mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
@@ -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
|
||||
@@ -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 {
|
||||
@@ -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.")
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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{
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user