Skip to content

Commit

Permalink
[teleport-update] update --now (#49807)
Browse files Browse the repository at this point in the history
* update --now

* testdata
  • Loading branch information
sclevine authored Dec 5, 2024
1 parent 8e723cc commit f7bf7eb
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: v1
kind: update_config
spec:
proxy: localhost
group: group
url_template: https://example.com
enabled: true
pinned: false
status:
active:
version: 16.3.0
backup:
version: old-version
20 changes: 14 additions & 6 deletions lib/autoupdate/agent/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ func (u *Updater) Unpin(ctx context.Context) error {
// Otherwise, the auto-updates configuration is not changed.
// Unlike Enable, Update will not validate or repair the current version.
// This function is idempotent.
func (u *Updater) Update(ctx context.Context) error {
func (u *Updater) Update(ctx context.Context, now bool) error {
// Read configuration from update.yaml and override any new values passed as flags.
cfg, err := readConfig(u.ConfigPath)
if err != nil {
Expand Down Expand Up @@ -536,7 +536,7 @@ func (u *Updater) Update(ctx context.Context) error {
// If a version fails and is marked skip, we ignore any edition changes as well.
// If a cluster is broadcasting a version that failed to start, changing ent/fips is unlikely to fix the issue.

if !resp.InWindow {
if !resp.InWindow && !now {
switch {
case target.Version == "":
u.Log.WarnContext(ctx, "Cannot determine target agent version. Waiting for both version and update window.")
Expand All @@ -552,18 +552,26 @@ func (u *Updater) Update(ctx context.Context) error {

switch {
case target.Version == "":
u.Log.ErrorContext(ctx, "Update window is active, but target version is not available.", activeKey, active)
if resp.InWindow {
u.Log.ErrorContext(ctx, "Update window is active, but target version is not available.", activeKey, active)
}
return trace.Errorf("target version missing")
case target == active:
u.Log.InfoContext(ctx, "Teleport is up-to-date. Update window is active, but no action is needed.", activeKey, active)
if resp.InWindow {
u.Log.InfoContext(ctx, "Teleport is up-to-date. Update window is active, but no action is needed.", activeKey, active)
} else {
u.Log.InfoContext(ctx, "Teleport is up-to-date. No action is needed.", activeKey, active)
}
return nil
case target.Version == skip.Version:
u.Log.InfoContext(ctx, "Update available, but the new version is marked as broken. Skipping update during the update window.", targetKey, target, activeKey, active)
u.Log.InfoContext(ctx, "Update available, but the new version is marked as broken. Skipping update.", targetKey, target, activeKey, active)
return nil
default:
u.Log.InfoContext(ctx, "Update available. Initiating update.", targetKey, target, activeKey, active)
}
time.Sleep(resp.Jitter)
if !now {
time.Sleep(resp.Jitter)
}

updateErr := u.update(ctx, cfg, target)
writeErr := writeConfig(u.ConfigPath, cfg)
Expand Down
27 changes: 26 additions & 1 deletion lib/autoupdate/agent/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ func TestUpdater_Update(t *testing.T) {
cfg *UpdateConfig // nil -> file not present
flags InstallFlags
inWindow bool
now bool
installErr error
setupErr error
reloadErr error
Expand Down Expand Up @@ -261,6 +262,30 @@ func TestUpdater_Update(t *testing.T) {
reloadCalls: 1,
setupCalls: 1,
},
{
name: "updates enabled now",
cfg: &UpdateConfig{
Version: updateConfigVersion,
Kind: updateConfigKind,
Spec: UpdateSpec{
Group: "group",
URLTemplate: "https://example.com",
Enabled: true,
},
Status: UpdateStatus{
Active: NewRevision("old-version", 0),
},
},
now: true,

removedRevisions: []Revision{NewRevision("unknown-version", 0)},
installedRevision: NewRevision("16.3.0", 0),
installedTemplate: "https://example.com",
linkedRevision: NewRevision("16.3.0", 0),
requestGroup: "group",
reloadCalls: 1,
setupCalls: 1,
},
{
name: "updates disabled during window",
cfg: &UpdateConfig{
Expand Down Expand Up @@ -627,7 +652,7 @@ func TestUpdater_Update(t *testing.T) {
}

ctx := context.Background()
err = updater.Update(ctx)
err = updater.Update(ctx, tt.now)
if tt.errMatch != "" {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.errMatch)
Expand Down
6 changes: 5 additions & 1 deletion tool/teleport-update/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type cliConfig struct {
InstallSuffix string
// SelfSetup mode for using the current version of the teleport-update to setup the update service.
SelfSetup bool
// UpdateNow forces an immediate update.
UpdateNow bool
}

func Run(args []string) int {
Expand Down Expand Up @@ -136,6 +138,8 @@ func Run(args []string) int {
unpinCmd := app.Command("unpin", "Unpin the current version, allowing it to be updated.")

updateCmd := app.Command("update", "Update the agent to the latest version, if a new version is available.")
updateCmd.Flag("now", "Force immediate update even if update window is not active.").
Short('n').BoolVar(&ccfg.UpdateNow)
updateCmd.Flag("self-setup", "Use the current teleport-update binary to create systemd service config for auto-updates.").
Short('s').Hidden().BoolVar(&ccfg.SelfSetup)

Expand Down Expand Up @@ -345,7 +349,7 @@ func cmdUpdate(ctx context.Context, ccfg *cliConfig) error {
}
}()

if err := updater.Update(ctx); err != nil {
if err := updater.Update(ctx, ccfg.UpdateNow); err != nil {
return trace.Wrap(err)
}
return nil
Expand Down

0 comments on commit f7bf7eb

Please sign in to comment.