diff --git a/lib/autoupdate/agent/config.go b/lib/autoupdate/agent/config.go index a13b475f59720..247392f881c57 100644 --- a/lib/autoupdate/agent/config.go +++ b/lib/autoupdate/agent/config.go @@ -85,12 +85,12 @@ func readConfig(path string) (*UpdateConfig, error) { }, nil } if err != nil { - return nil, trace.Errorf("failed to open: %w", err) + return nil, trace.Wrap(err, "failed to open") } defer f.Close() var cfg UpdateConfig if err := yaml.NewDecoder(f).Decode(&cfg); err != nil { - return nil, trace.Errorf("failed to parse: %w", err) + return nil, trace.Wrap(err, "failed to parse") } if k := cfg.Kind; k != updateConfigKind { return nil, trace.Errorf("invalid kind %q", k) diff --git a/lib/autoupdate/agent/installer.go b/lib/autoupdate/agent/installer.go index f3a98e30223bc..91c70402288e2 100644 --- a/lib/autoupdate/agent/installer.go +++ b/lib/autoupdate/agent/installer.go @@ -103,10 +103,10 @@ func (li *LocalInstaller) Remove(ctx context.Context, version string) error { linked, err := li.isLinked(filepath.Join(versionDir, "bin")) if err != nil && !errors.Is(err, os.ErrNotExist) { - return trace.Errorf("failed to determine if linked: %w", err) + return trace.Wrap(err, "failed to determine if linked") } if linked { - return trace.Errorf("refusing to remove: %w", ErrLinked) + return trace.Wrap(ErrLinked, "refusing to remove") } // invalidate checksum first, to protect against partially-removed @@ -142,7 +142,7 @@ func (li *LocalInstaller) Install(ctx context.Context, version, template string, checksumURI := uri + "." + checksumType newSum, err := li.getChecksum(ctx, checksumURI) if err != nil { - return trace.Errorf("failed to download checksum from %s: %w", checksumURI, err) + return trace.Wrap(err, "failed to download checksum from %s", checksumURI) } oldSum, err := readChecksum(sumPath) if err == nil { @@ -164,11 +164,11 @@ func (li *LocalInstaller) Install(ctx context.Context, version, template string, // Verify that we have enough free temp space, then download tgz freeTmp, err := utils.FreeDiskWithReserve(os.TempDir(), li.ReservedFreeTmpDisk) if err != nil { - return trace.Errorf("failed to calculate free disk: %w", err) + return trace.Wrap(err, "failed to calculate free disk") } f, err := os.CreateTemp("", "teleport-update-") if err != nil { - return trace.Errorf("failed to create temporary file: %w", err) + return trace.Wrap(err, "failed to create temporary file") } defer func() { _ = f.Close() // data never read after close @@ -178,11 +178,11 @@ func (li *LocalInstaller) Install(ctx context.Context, version, template string, }() pathSum, err := li.download(ctx, f, int64(freeTmp), uri) if err != nil { - return trace.Errorf("failed to download teleport: %w", err) + return trace.Wrap(err, "failed to download teleport") } // Seek to the start of the tgz file after writing if _, err := f.Seek(0, io.SeekStart); err != nil { - return trace.Errorf("failed seek to start of download: %w", err) + return trace.Wrap(err, "failed seek to start of download") } // If interrupted, close the file immediately to stop extracting. @@ -198,11 +198,11 @@ func (li *LocalInstaller) Install(ctx context.Context, version, template string, // Get uncompressed size of the tgz n, err := uncompressedSize(f) if err != nil { - return trace.Errorf("failed to determine uncompressed size: %w", err) + return trace.Wrap(err, "failed to determine uncompressed size") } // Seek to start of tgz after reading size if _, err := f.Seek(0, io.SeekStart); err != nil { - return trace.Errorf("failed seek to start: %w", err) + return trace.Wrap(err, "failed seek to start") } // If there's an error after we start extracting, delete the version dir. @@ -216,12 +216,12 @@ func (li *LocalInstaller) Install(ctx context.Context, version, template string, // Extract tgz into version directory. if err := li.extract(ctx, versionDir, f, n, flags); err != nil { - return trace.Errorf("failed to extract teleport: %w", err) + return trace.Wrap(err, "failed to extract teleport") } // Write the checksum last. This marks the version directory as valid. err = renameio.WriteFile(sumPath, []byte(hex.EncodeToString(newSum)), configFileMode) if err != nil { - return trace.Errorf("failed to write checksum: %w", err) + return trace.Wrap(err, "failed to write checksum") } return nil } @@ -346,7 +346,7 @@ func (li *LocalInstaller) extract(ctx context.Context, dstDir string, src io.Rea } free, err := utils.FreeDiskWithReserve(dstDir, li.ReservedFreeInstallDisk) if err != nil { - return trace.Errorf("failed to calculate free disk in %q: %w", dstDir, err) + return trace.Wrap(err, "failed to calculate free disk in %q", dstDir) } // Bail if there's not enough free disk space at the target if d := int64(free) - max; d < 0 { @@ -354,7 +354,7 @@ func (li *LocalInstaller) extract(ctx context.Context, dstDir string, src io.Rea } zr, err := gzip.NewReader(src) if err != nil { - return trace.Errorf("requires gzip-compressed body: %w", err) + return trace.Wrap(err, "requires gzip-compressed body") } li.Log.InfoContext(ctx, "Extracting Teleport tarball.", "path", dstDir, "size", max) @@ -551,7 +551,7 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string entries, err := os.ReadDir(binDir) if err != nil { - return revert, trace.Errorf("failed to find Teleport binary directory: %w", err) + return revert, trace.Wrap(err, "failed to find Teleport binary directory") } var linked int for _, entry := range entries { @@ -562,7 +562,7 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string newname := filepath.Join(li.LinkBinDir, entry.Name()) orig, err := forceLink(oldname, newname) if err != nil && !errors.Is(err, os.ErrExist) { - return revert, trace.Errorf("failed to create symlink for %s: %w", filepath.Base(oldname), err) + return revert, trace.Wrap(err, "failed to create symlink for %s", filepath.Base(oldname)) } if orig != "" { revertLinks = append(revertLinks, symlink{ @@ -580,7 +580,7 @@ func (li *LocalInstaller) forceLinks(ctx context.Context, binDir, svcPath string orig, err := li.forceCopyService(li.LinkServicePath, svcPath, maxServiceFileSize) if err != nil && !errors.Is(err, os.ErrExist) { - return revert, trace.Errorf("failed to copy service: %w", err) + return revert, trace.Wrap(err, "failed to copy service") } if orig != nil { revertFiles = append(revertFiles, *orig) @@ -688,7 +688,7 @@ func (li *LocalInstaller) removeLinks(ctx context.Context, binDir, svcPath strin removeService := false entries, err := os.ReadDir(binDir) if err != nil { - return trace.Errorf("failed to find Teleport binary directory: %w", err) + return trace.Wrap(err, "failed to find Teleport binary directory") } for _, entry := range entries { if entry.IsDir() { @@ -704,7 +704,7 @@ func (li *LocalInstaller) removeLinks(ctx context.Context, binDir, svcPath strin continue } if err != nil { - return trace.Errorf("error reading link for %s: %w", filepath.Base(newname), err) + return trace.Wrap(err, "error reading link for %s", filepath.Base(newname)) } if v != oldname { li.Log.DebugContext(ctx, "Skipping link to different binary.", "oldname", oldname, "newname", newname) @@ -740,7 +740,7 @@ func (li *LocalInstaller) removeLinks(ctx context.Context, binDir, svcPath strin return nil } if err := os.Remove(li.LinkServicePath); err != nil { - return trace.Errorf("error removing copy of %s: %w", filepath.Base(li.LinkServicePath), err) + return trace.Wrap(err, "error removing copy of %s", filepath.Base(li.LinkServicePath)) } return nil } @@ -766,7 +766,7 @@ func (li *LocalInstaller) tryLinks(ctx context.Context, binDir, svcPath string) var linked int entries, err := os.ReadDir(binDir) if err != nil { - return trace.Errorf("failed to find Teleport binary directory: %w", err) + return trace.Wrap(err, "failed to find Teleport binary directory") } for _, entry := range entries { if entry.IsDir() { @@ -776,7 +776,7 @@ func (li *LocalInstaller) tryLinks(ctx context.Context, binDir, svcPath string) newname := filepath.Join(li.LinkBinDir, entry.Name()) ok, err := needsLink(oldname, newname) if err != nil { - return trace.Errorf("error evaluating link for %s: %w", filepath.Base(oldname), err) + return trace.Wrap(err, "error evaluating link for %s", filepath.Base(oldname)) } if ok { links = append(links, symlink{oldname, newname}) @@ -791,14 +791,14 @@ func (li *LocalInstaller) tryLinks(ctx context.Context, binDir, svcPath string) // link binaries that are missing links for _, link := range links { if err := os.Symlink(link.oldname, link.newname); err != nil { - return trace.Errorf("failed to create symlink for %s: %w", filepath.Base(link.oldname), err) + return trace.Wrap(err, "failed to create symlink for %s", filepath.Base(link.oldname)) } } // if any binaries are linked from binDir, always link the service from svcDir _, err = li.forceCopyService(li.LinkServicePath, svcPath, maxServiceFileSize) if err != nil && !errors.Is(err, os.ErrExist) { - return trace.Errorf("failed to copy service: %w", err) + return trace.Wrap(err, "failed to copy service") } return nil @@ -828,7 +828,7 @@ func needsLink(oldname, newname string) (ok bool, err error) { return false, trace.Wrap(err) } if orig != oldname { - return false, trace.Errorf("refusing to replace link at %s: %w", newname, ErrLinked) + return false, trace.Wrap(ErrLinked, "refusing to replace link at %s", newname) } return false, nil } diff --git a/lib/autoupdate/agent/setup.go b/lib/autoupdate/agent/setup.go index 4e3aaa4803317..b0660509ef587 100644 --- a/lib/autoupdate/agent/setup.go +++ b/lib/autoupdate/agent/setup.go @@ -77,17 +77,17 @@ func NewNamespace(name string) (Namespace, error) { func (ns Namespace) Setup(ctx context.Context, log *slog.Logger, linkDir, dataDir string) error { err := ns.writeConfigFiles(linkDir) if err != nil { - return trace.Errorf("failed to write teleport-update systemd config files: %w", err) + return trace.Wrap(err, "failed to write teleport-update systemd config files") } svc := &SystemdService{ ServiceName: ns.UpdaterTimer(), Log: log, } if err := svc.Sync(ctx); err != nil { - return trace.Errorf("failed to sync systemd config: %w", err) + return trace.Wrap(err, "failed to sync systemd config") } if err := svc.Enable(ctx, true); err != nil { - return trace.Errorf("failed to enable teleport-update systemd timer: %w", err) + return trace.Wrap(err, "failed to enable teleport-update systemd timer") } return nil } @@ -99,21 +99,21 @@ func (ns Namespace) Teardown(ctx context.Context, log *slog.Logger, linkDir, dat Log: log, } if err := svc.Disable(ctx); err != nil { - return trace.Errorf("failed to disable teleport-update systemd timer: %w", err) + return trace.Wrap(err, "failed to disable teleport-update systemd timer") } servicePath := filepath.Join(ns.LinkDir(linkDir), serviceDir, ns.UpdaterService()) if err := os.Remove(servicePath); err != nil && !errors.Is(err, fs.ErrNotExist) { - return trace.Errorf("failed to remove teleport-update systemd service: %w", err) + return trace.Wrap(err, "failed to remove teleport-update systemd service") } timerPath := filepath.Join(ns.LinkDir(linkDir), serviceDir, ns.UpdaterTimer()) if err := os.Remove(timerPath); err != nil && !errors.Is(err, fs.ErrNotExist) { - return trace.Errorf("failed to remove teleport-update systemd timer: %w", err) + return trace.Wrap(err, "failed to remove teleport-update systemd timer") } if err := svc.Sync(ctx); err != nil { - return trace.Errorf("failed to sync systemd config: %w", err) + return trace.Wrap(err, "failed to sync systemd config") } if err := os.RemoveAll(filepath.Join(ns.DataDir(dataDir), VersionsDirName)); err != nil { - return trace.Errorf("failed to remove versions directory: %w", err) + return trace.Wrap(err, "failed to remove versions directory") } return nil } diff --git a/lib/autoupdate/agent/updater.go b/lib/autoupdate/agent/updater.go index ef794c0c2228e..152115f1920c8 100644 --- a/lib/autoupdate/agent/updater.go +++ b/lib/autoupdate/agent/updater.go @@ -108,7 +108,7 @@ func NewLocalUpdater(cfg LocalUpdaterConfig) (*Updater, error) { } installDir := filepath.Join(ns.DataDir(cfg.DataDir), VersionsDirName) if err := os.MkdirAll(installDir, systemDirMode); err != nil { - return nil, trace.Errorf("failed to create install directory: %w", err) + return nil, trace.Wrap(err, "failed to create install directory") } return &Updater{ Log: cfg.Log, @@ -301,7 +301,7 @@ func (u *Updater) Install(ctx context.Context, override OverrideConfig) error { // Read configuration from update.yaml and override any new values passed as flags. cfg, err := readConfig(u.ConfigPath) if err != nil { - return trace.Errorf("failed to read %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to read %s", updateConfigName) } if err := validateConfigSpec(&cfg.Spec, override); err != nil { return trace.Wrap(err) @@ -343,7 +343,7 @@ func (u *Updater) Install(ctx context.Context, override OverrideConfig) error { // Note: skip_version is never set on failed enable, only failed update. if err := writeConfig(u.ConfigPath, cfg); err != nil { - return trace.Errorf("failed to write %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to write %s", updateConfigName) } u.Log.InfoContext(ctx, "Configuration updated.") return nil @@ -355,7 +355,7 @@ func (u *Updater) Install(ctx context.Context, override OverrideConfig) error { func (u *Updater) Remove(ctx context.Context) error { cfg, err := readConfig(u.ConfigPath) if err != nil { - return trace.Errorf("failed to read %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to read %s", updateConfigName) } if err := validateConfigSpec(&cfg.Spec, OverrideConfig{}); err != nil { return trace.Wrap(err) @@ -391,7 +391,7 @@ func (u *Updater) Remove(ctx context.Context) error { return nil } if err != nil { - return trace.Errorf("failed to link: %w", err) + return trace.Wrap(err, "failed to link") } u.Log.InfoContext(ctx, "Updater-managed installation of Teleport detected. Restoring packaged version of Teleport before removing.") @@ -421,7 +421,7 @@ func (u *Updater) Remove(ctx context.Context) error { if ok := revertConfig(ctx); ok { u.Log.WarnContext(ctx, "Teleport updater encountered a configuration error and successfully reverted the installation.") } - return trace.Errorf("failed to validate configuration for system package version of Teleport: %w", err) + return trace.Wrap(err, "failed to validate configuration for system package version of Teleport") } // Restart Teleport. @@ -444,7 +444,7 @@ func (u *Updater) Remove(ctx context.Context) error { u.Log.WarnContext(ctx, "Teleport updater detected an error with the new installation and successfully reverted it.") } } - return trace.Errorf("failed to start system package version of Teleport: %w", err) + return trace.Wrap(err, "failed to start system package version of Teleport") } u.Log.InfoContext(ctx, "Auto-updating Teleport removed and replaced by Teleport packaged.", "version", activeVersion) if err := u.Teardown(ctx); err != nil { @@ -460,7 +460,7 @@ func (u *Updater) Status(ctx context.Context) (Status, error) { // Read configuration from update.yaml. cfg, err := readConfig(u.ConfigPath) if err != nil { - return out, trace.Errorf("failed to read %s: %w", updateConfigName, err) + return out, trace.Wrap(err, "failed to read %s", updateConfigName) } if err := validateConfigSpec(&cfg.Spec, OverrideConfig{}); err != nil { return out, trace.Wrap(err) @@ -482,7 +482,7 @@ func (u *Updater) Status(ctx context.Context) (Status, error) { func (u *Updater) Disable(ctx context.Context) error { cfg, err := readConfig(u.ConfigPath) if err != nil { - return trace.Errorf("failed to read %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to read %s", updateConfigName) } if !cfg.Spec.Enabled { u.Log.InfoContext(ctx, "Automatic updates already disabled.") @@ -490,7 +490,7 @@ func (u *Updater) Disable(ctx context.Context) error { } cfg.Spec.Enabled = false if err := writeConfig(u.ConfigPath, cfg); err != nil { - return trace.Errorf("failed to write %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to write %s", updateConfigName) } return nil } @@ -500,7 +500,7 @@ func (u *Updater) Disable(ctx context.Context) error { func (u *Updater) Unpin(ctx context.Context) error { cfg, err := readConfig(u.ConfigPath) if err != nil { - return trace.Errorf("failed to read %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to read %s", updateConfigName) } if !cfg.Spec.Pinned { u.Log.InfoContext(ctx, "Current version not pinned.", activeVersionKey, cfg.Status.ActiveVersion) @@ -508,7 +508,7 @@ func (u *Updater) Unpin(ctx context.Context) error { } cfg.Spec.Pinned = false if err := writeConfig(u.ConfigPath, cfg); err != nil { - return trace.Errorf("failed to write %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to write %s", updateConfigName) } return nil } @@ -522,7 +522,7 @@ func (u *Updater) Update(ctx context.Context) error { // Read configuration from update.yaml and override any new values passed as flags. cfg, err := readConfig(u.ConfigPath) if err != nil { - return trace.Errorf("failed to read %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to read %s", updateConfigName) } if err := validateConfigSpec(&cfg.Spec, OverrideConfig{}); err != nil { return trace.Wrap(err) @@ -582,7 +582,7 @@ func (u *Updater) Update(ctx context.Context) error { updateErr := u.update(ctx, cfg, targetVersion, resp.Flags) writeErr := writeConfig(u.ConfigPath, cfg) if writeErr != nil { - writeErr = trace.Errorf("failed to write %s: %w", updateConfigName, writeErr) + writeErr = trace.Wrap(writeErr, "failed to write %s", updateConfigName) } else { u.Log.InfoContext(ctx, "Configuration updated.") } @@ -595,7 +595,7 @@ func (u *Updater) find(ctx context.Context, cfg *UpdateConfig) (FindResp, error) } addr, err := libutils.ParseAddr(cfg.Spec.Proxy) if err != nil { - return FindResp{}, trace.Errorf("failed to parse proxy server address: %w", err) + return FindResp{}, trace.Wrap(err, "failed to parse proxy server address") } resp, err := webclient.Find(&webclient.Config{ Context: ctx, @@ -606,7 +606,7 @@ func (u *Updater) find(ctx context.Context, cfg *UpdateConfig) (FindResp, error) Pool: u.Pool, }) if err != nil { - return FindResp{}, trace.Errorf("failed to request version from proxy: %w", err) + return FindResp{}, trace.Wrap(err, "failed to request version from proxy") } var flags InstallFlags switch resp.Edition { @@ -653,7 +653,7 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, targetVersion s } err := u.Installer.Install(ctx, targetVersion, template, flags) if err != nil { - return trace.Errorf("failed to install: %w", err) + return trace.Wrap(err, "failed to install") } // If the target version has fewer binaries, this will leave old binaries linked. @@ -663,7 +663,7 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, targetVersion s revert, err := u.Installer.Link(ctx, targetVersion) if err != nil { - return trace.Errorf("failed to link: %w", err) + return trace.Wrap(err, "failed to link") } // If we fail to revert after this point, the next update/enable will @@ -695,7 +695,7 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, targetVersion s if ok := revertConfig(ctx); ok { u.Log.WarnContext(ctx, "Teleport updater encountered a configuration error and successfully reverted the installation.") } - return trace.Errorf("failed to validate configuration for new version %q of Teleport: %w", targetVersion, err) + return trace.Wrap(err, "failed to validate configuration for new version %q of Teleport", targetVersion) } // Restart Teleport if necessary. @@ -719,7 +719,7 @@ func (u *Updater) update(ctx context.Context, cfg *UpdateConfig, targetVersion s u.Log.WarnContext(ctx, "Teleport updater detected an error with the new installation and successfully reverted it.") } } - return trace.Errorf("failed to start new version %q of Teleport: %w", targetVersion, err) + return trace.Wrap(err, "failed to start new version %q of Teleport", targetVersion) } cfg.Status.BackupVersion = cfg.Status.ActiveVersion cfg.Status.ActiveVersion = targetVersion @@ -773,7 +773,7 @@ func (u *Updater) cleanup(ctx context.Context, keep []string) error { func (u *Updater) LinkPackage(ctx context.Context) error { cfg, err := readConfig(u.ConfigPath) if err != nil { - return trace.Errorf("failed to read %s: %w", updateConfigName, err) + return trace.Wrap(err, "failed to read %s", updateConfigName) } if err := validateConfigSpec(&cfg.Spec, OverrideConfig{}); err != nil { return trace.Wrap(err) @@ -794,10 +794,10 @@ func (u *Updater) LinkPackage(ctx context.Context) error { u.Log.WarnContext(ctx, "Automatic updates is disabled, but a non-package version of Teleport is linked.", activeVersionKey, activeVersion) return nil } else if err != nil { - return trace.Errorf("failed to link system package installation: %w", err) + return trace.Wrap(err, "failed to link system package installation") } if err := u.Process.Sync(ctx); err != nil { - return trace.Errorf("failed to sync systemd configuration: %w", err) + return trace.Wrap(err, "failed to sync systemd configuration") } u.Log.InfoContext(ctx, "Successfully linked system package installation.") return nil @@ -807,10 +807,10 @@ func (u *Updater) LinkPackage(ctx context.Context) error { // This function is idempotent. func (u *Updater) UnlinkPackage(ctx context.Context) error { if err := u.Installer.UnlinkSystem(ctx); err != nil { - return trace.Errorf("failed to unlink system package installation: %w", err) + return trace.Wrap(err, "failed to unlink system package installation") } if err := u.Process.Sync(ctx); err != nil { - return trace.Errorf("failed to sync systemd configuration: %w", err) + return trace.Wrap(err, "failed to sync systemd configuration") } u.Log.InfoContext(ctx, "Successfully unlinked system package installation.") return nil diff --git a/tool/teleport-update/main.go b/tool/teleport-update/main.go index e133135ba7ecc..beebf0ec373b5 100644 --- a/tool/teleport-update/main.go +++ b/tool/teleport-update/main.go @@ -236,11 +236,12 @@ func newUpdater(ccfg *cliConfig) (*autoupdate.Updater, error) { func cmdDisable(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to initialize updater: %w", err) + return trace.Wrap(err, "failed to initialize updater") } - unlock, err := libutils.FSWriteLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSWriteLock(lockPath) if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil { @@ -257,11 +258,12 @@ func cmdDisable(ctx context.Context, ccfg *cliConfig) error { func cmdUnpin(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to setup updater: %w", err) + return trace.Wrap(err, "failed to setup updater") } - unlock, err := libutils.FSWriteLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSWriteLock(lockPath) if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil { @@ -291,13 +293,14 @@ func cmdInstall(ctx context.Context, ccfg *cliConfig) error { } updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to initialize updater: %w", err) + return trace.Wrap(err, "failed to initialize updater") } // Ensure enable can't run concurrently. - unlock, err := libutils.FSWriteLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSWriteLock(lockPath) if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil { @@ -314,12 +317,13 @@ func cmdInstall(ctx context.Context, ccfg *cliConfig) error { func cmdUpdate(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to initialize updater: %w", err) + return trace.Wrap(err, "failed to initialize updater") } // Ensure update can't run concurrently. - unlock, err := libutils.FSWriteLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSWriteLock(lockPath) if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil { @@ -337,17 +341,18 @@ func cmdUpdate(ctx context.Context, ccfg *cliConfig) error { func cmdLinkPackage(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to initialize updater: %w", err) + return trace.Wrap(err, "failed to initialize updater") } // Skip operation and warn if the updater is currently running. - unlock, err := libutils.FSTryReadLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSTryReadLock(lockPath) if errors.Is(err, libutils.ErrUnsuccessfulLockTry) { plog.WarnContext(ctx, "Updater is currently running. Skipping package linking.") return nil } if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil { @@ -365,16 +370,18 @@ func cmdLinkPackage(ctx context.Context, ccfg *cliConfig) error { func cmdUnlinkPackage(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to setup updater: %w", err) + return trace.Wrap(err, "failed to setup updater") } // Error if the updater is running. We could remove its links by accident. - unlock, err := libutils.FSTryWriteLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSTryWriteLock(lockPath) if errors.Is(err, libutils.ErrUnsuccessfulLockTry) { - return trace.Errorf("updater is currently running") + plog.WarnContext(ctx, "Updater is currently running. Skipping package unlinking.") + return nil } if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil { @@ -400,7 +407,7 @@ func cmdSetup(ctx context.Context, ccfg *cliConfig) error { return trace.Wrap(err) } if err != nil { - return trace.Errorf("failed to setup teleport-update service: %w", err) + return trace.Wrap(err, "failed to setup teleport-update service") } return nil } @@ -409,11 +416,11 @@ func cmdSetup(ctx context.Context, ccfg *cliConfig) error { func cmdStatus(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to initialize updater: %w", err) + return trace.Wrap(err, "failed to initialize updater") } status, err := updater.Status(ctx) if err != nil { - return trace.Errorf("failed to get status: %w", err) + return trace.Wrap(err, "failed to get status") } enc := yaml.NewEncoder(os.Stdout) return trace.Wrap(enc.Encode(status)) @@ -423,12 +430,13 @@ func cmdStatus(ctx context.Context, ccfg *cliConfig) error { func cmdUninstall(ctx context.Context, ccfg *cliConfig) error { updater, err := newUpdater(ccfg) if err != nil { - return trace.Errorf("failed to initialize updater: %w", err) + return trace.Wrap(err, "failed to initialize updater") } // Ensure update can't run concurrently. - unlock, err := libutils.FSWriteLock(filepath.Join(ccfg.DataDir, lockFileName)) + lockPath := filepath.Join(ccfg.DataDir, lockFileName) + unlock, err := libutils.FSWriteLock(lockPath) if err != nil { - return trace.Errorf("failed to grab concurrent execution lock: %w", err) + return trace.Wrap(err, "failed to grab concurrent execution lock %q", lockPath) } defer func() { if err := unlock(); err != nil {