diff --git a/orbit/cmd/orbit/orbit.go b/orbit/cmd/orbit/orbit.go index 2f8a7ad37b8e..21cfa8858033 100644 --- a/orbit/cmd/orbit/orbit.go +++ b/orbit/cmd/orbit/orbit.go @@ -471,13 +471,26 @@ func main() { } } - metadataFileName := update.MetadataFileName if updateURL := c.String("update-url"); updateURL != update.OldFleetTUFURL && updateURL != update.DefaultURL { - // Users using custom TUF repository will continue using the local TUF metadata as usual. - metadataFileName = update.OldMetadataFileName + // Migrate agents running with a custom TUF to use the new metadata file. + // We'll keep the old metadata file to support downgrades. + newMetadataFilePath := filepath.Join(c.String("root-dir"), update.MetadataFileName) + ok, err := file.Exists(newMetadataFilePath) + if err != nil { + // If we cannot stat this file then we cannot do other operations on it thus we fail with fatal error. + log.Fatal().Err(err).Msg("failed to check for new metadata file path") + } + if !ok { + oldMetadataFilePath := filepath.Join(c.String("root-dir"), update.OldMetadataFileName) + err := file.Copy(oldMetadataFilePath, newMetadataFilePath, constant.DefaultFileMode) + if err != nil { + // If we cannot write to this file then we cannot do other operations on it thus we fail with fatal error. + log.Fatal().Err(err).Msg("failed to copy new metadata file path") + } + } } - localStore, err := filestore.New(filepath.Join(c.String("root-dir"), metadataFileName)) + localStore, err := filestore.New(filepath.Join(c.String("root-dir"), update.MetadataFileName)) if err != nil { log.Fatal().Err(err).Msg("create local metadata store") } @@ -510,7 +523,7 @@ func main() { opt.RootDirectory = c.String("root-dir") opt.ServerURL = c.String("update-url") if opt.ServerURL == update.OldFleetTUFURL { - // orbit 1.37.0+ will use the new TUF repository + // orbit 1.38.0+ will use the new TUF repository opt.ServerURL = update.DefaultURL } opt.LocalStore = localStore diff --git a/orbit/pkg/packaging/packaging.go b/orbit/pkg/packaging/packaging.go index 110518f51609..279da1dc5e71 100644 --- a/orbit/pkg/packaging/packaging.go +++ b/orbit/pkg/packaging/packaging.go @@ -172,12 +172,7 @@ func (u UpdatesData) String() string { } func InitializeUpdates(updateOpt update.Options) (*UpdatesData, error) { - metadataFileName := update.MetadataFileName - if updateOpt.ServerURL != update.OldFleetTUFURL && updateOpt.ServerURL != update.DefaultURL { - // Users using custom TUF repository will continue using the local TUF metadata as usual. - metadataFileName = update.OldMetadataFileName - } - localStore, err := filestore.New(filepath.Join(updateOpt.RootDirectory, metadataFileName)) + localStore, err := filestore.New(filepath.Join(updateOpt.RootDirectory, update.MetadataFileName)) if err != nil { return nil, fmt.Errorf("failed to create local metadata store: %w", err) } @@ -241,14 +236,15 @@ func InitializeUpdates(updateOpt update.Options) (*UpdatesData, error) { } } - if updateOpt.ServerURL == update.OldFleetTUFURL || updateOpt.ServerURL == update.DefaultURL { - // If using Fleet's TUF then copy the new metadata to the old location (pre-migration) to - // support orbit downgrades to 1.36.0 or lower. - oldMetadataPath := filepath.Join(updateOpt.RootDirectory, update.OldMetadataFileName) - newMetadataPath := filepath.Join(updateOpt.RootDirectory, update.MetadataFileName) - if err := file.Copy(newMetadataPath, oldMetadataPath, constant.DefaultFileMode); err != nil { - return nil, fmt.Errorf("failed to create %s copy: %w", oldMetadataPath, err) - } + // Copy the new metadata file to the old location (pre-migration) to + // support orbit downgrades to 1.37.0 or lower. + // + // Once https://tuf.fleetctl.com is brought down (which means downgrades to 1.37.0 or + // lower won't be possible), we can remove this copy. + oldMetadataPath := filepath.Join(updateOpt.RootDirectory, update.OldMetadataFileName) + newMetadataPath := filepath.Join(updateOpt.RootDirectory, update.MetadataFileName) + if err := file.Copy(newMetadataPath, oldMetadataPath, constant.DefaultFileMode); err != nil { + return nil, fmt.Errorf("failed to create %s copy: %w", oldMetadataPath, err) } return &UpdatesData{ diff --git a/orbit/pkg/update/update.go b/orbit/pkg/update/update.go index 50de47008aff..a45e5c117a43 100644 --- a/orbit/pkg/update/update.go +++ b/orbit/pkg/update/update.go @@ -39,8 +39,22 @@ const ( // Defining these as variables so that we can overwrite them during development/testing of the migration. var ( // - // These used by `fleetctl package` and by orbit in the migration to the new TUF repository. + // For users using Fleet's TUF: + // - orbit 1.38.0+ we migrate TUF from https://tuf.fleetctl.com to https://updates.fleetdm.com. + // - orbit 1.38.0+ will start using `updates-metadata.json` instead of `tuf-metadata.json`. If it is missing + // (which will be the case for the first run after the auto-update) then it will generate it from the new pinned roots. // + // For users using a custom TUF: + // - orbit 1.38.0+ will start using `updates-metadata.json` instead of `tuf-metadata.json` (if it is missing then + // it will perform a copy). + // + // For both Fleet's TUF and custom TUF, fleetd packages built with fleetctl 4.62.0+ will contain both files + // `updates-metadata.json` and `tuf-metadata.json` (same content) to support downgrades to orbit 1.37.0 or lower. + + // + // The following variables are used by `fleetctl package` and by orbit in the migration to the new TUF repository. + // + // TODO(lucas): Before merging to `main` update DefaultURL to "https://updates.fleetctl.com". DefaultURL = `https://tuf.fleetctl.com` MetadataFileName = "updates-metadata.json" diff --git a/tools/tuf/test/migration/migration_test.sh b/tools/tuf/test/migration/migration_test.sh index 146b5b63be13..ae44d726d2e0 100755 --- a/tools/tuf/test/migration/migration_test.sh +++ b/tools/tuf/test/migration/migration_test.sh @@ -5,6 +5,7 @@ # - User runs the script on macOS # - User has a Ubuntu 22.04 and a Windows 10/11 VM (running on the same macOS host script runs on). # - Fleet is running on the macOS host. +# - `fleetctl login` was ran on the localhost Fleet instance (to be able to run `fleectl query` commands). # - host.docker.internal points to localhost on the macOS host. # - host.docker.internal points to the macOS host on the two VMs (/etc/hosts on Ubuntu and C:\Windows\System32\Drivers\etc\hosts on Windows). # - 1.36.0 is the last version of orbit that uses the old TUF repository