diff --git a/subcommands/targets/offline-update.go b/subcommands/targets/offline-update.go index 71c22355..5ab6a01f 100644 --- a/subcommands/targets/offline-update.go +++ b/subcommands/targets/offline-update.go @@ -52,6 +52,7 @@ var ( ouNoApps bool ouAllowMultipleTargets bool ouWave string + ouOstreeRepoSrc string ) func init() { @@ -87,6 +88,8 @@ func init() { "Skip fetching Target Apps") offlineUpdateCmd.Flags().BoolVarP(&ouAllowMultipleTargets, "allow-multiple-targets", "", false, "Allow multiple targets to be stored in the same directory") + offlineUpdateCmd.Flags().StringVarP(&ouOstreeRepoSrc, "ostree-repo-source", "", "", + "Path to the local ostree repo to be used in the offline bundle") offlineUpdateCmd.MarkFlagsMutuallyExclusive("tag", "wave") offlineUpdateCmd.MarkFlagsMutuallyExclusive("prod", "wave") initSignCmd(offlineUpdateCmd) @@ -169,8 +172,13 @@ Notice that multiple targets in the same directory is only supported in LmP >= v ti, err := getTargetInfo(targetCustomData) subcommands.DieNotNil(err) - fmt.Printf("Downloading an ostree repo from the Target's OE build %d...\n", ti.ostreeVersion) - subcommands.DieNotNil(downloadOstree(factory, ti.ostreeVersion, ti.hardwareID, dstDir), "Failed to download Target's ostree repo:") + if ouOstreeRepoSrc != "" { + fmt.Printf("Copying local ostree repo from %s...\n", ouOstreeRepoSrc) + subcommands.DieNotNil(copyOstree(ouOstreeRepoSrc, dstDir+"/ostree_repo/"), "Failed to copy local ostree repo:") + } else { + fmt.Printf("Downloading an ostree repo from the Target's OE build %d...\n", ti.ostreeVersion) + subcommands.DieNotNil(downloadOstree(factory, ti.ostreeVersion, ti.hardwareID, dstDir), "Failed to download Target's ostree repo:") + } if !ouNoApps { if (len(ouWave) > 0 || ouProd) && ti.fetchedApps == nil { // Get the specified target from the list of factory targets to obtain the "original" tag/branch that produced @@ -366,6 +374,64 @@ func downloadTufRepo(factory string, target string, tag string, prod bool, wave return nil } +func copyFile(src string, dst string) error { + srcFile, err := os.Open(src) + if err != nil { + return err + } + defer srcFile.Close() + + dstFile, err := os.Create(dst) + if err != nil { + return err + } + defer dstFile.Close() + + _, err = dstFile.ReadFrom(srcFile) + if err != nil { + return err + } + srcInfo, err := os.Stat(src) + if err != nil { + return err + } + return os.Chmod(dst, srcInfo.Mode()) +} + +func copyDirRecursive(srcDir string, dstDir string) error { + srcInfo, err := os.Stat(srcDir) + if err != nil { + return err + } + + err = os.MkdirAll(dstDir, srcInfo.Mode()) + if err != nil { + return err + } + + dirEntries, err := os.ReadDir(srcDir) + if err != nil { + return err + } + for _, dirEntry := range dirEntries { + src := path.Join(srcDir, dirEntry.Name()) + dst := path.Join(dstDir, dirEntry.Name()) + if dirEntry.IsDir() { + err = copyDirRecursive(src, dst) + } else { + err = copyFile(src, dst) + } + if err != nil { + return err + } + } + return nil +} + +func copyOstree(srcDir string, dstDir string) error { + return copyDirRecursive(srcDir, dstDir) +} + func downloadOstree(factory string, targetVer int, hardwareID string, dstDir string) error { runName := hardwareID artifactName := hardwareID + "-ostree_repo.tar.bz2"