diff --git a/build/base-package/install.sh b/build/base-package/install.sh index 23374b68d..98e8dd54d 100644 --- a/build/base-package/install.sh +++ b/build/base-package/install.sh @@ -10,7 +10,7 @@ function command_exists() { if [[ x"$VERSION" == x"" ]]; then if [[ "$LOCAL_RELEASE" == "1" ]]; then ts=$(date +%Y%m%d%H%M%S) - export VERSION="0.0.0-local-dev-$ts" + export VERSION="1.12.0-local-$ts" echo "will build and use a local release of Olares with version: $VERSION" echo "" else @@ -79,47 +79,55 @@ if [[ x"$os_type" == x"Darwin" ]]; then CLI_FILE="olares-cli-v${VERSION}_darwin_${ARCH}.tar.gz" fi -if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]]; then +if [[ "$LOCAL_RELEASE" == "1" ]]; then + if ! command_exists olares-cli ; then + echo "error: LOCAL_RELEASE specified but olares-cli not found" + exit 1 + fi INSTALL_OLARES_CLI=$(which olares-cli) - echo "olares-cli already installed and is the expected version" - echo "" else - if [[ ! -f ${CLI_FILE} ]]; then - CLI_URL="${cdn_url}/${CLI_FILE}" - - echo "downloading Olares installer from ${CLI_URL} ..." + if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]]; then + INSTALL_OLARES_CLI=$(which olares-cli) + echo "olares-cli already installed and is the expected version" echo "" + else + if [[ ! -f ${CLI_FILE} ]]; then + CLI_URL="${cdn_url}/${CLI_FILE}" - curl -Lo ${CLI_FILE} ${CLI_URL} + echo "downloading Olares installer from ${CLI_URL} ..." + echo "" + + curl -Lo ${CLI_FILE} ${CLI_URL} + + if [[ $? -ne 0 ]]; then + echo "error: failed to download Olares installer" + exit 1 + else + echo "Olares installer ${VERSION} download complete!" + echo "" + fi + fi + INSTALL_OLARES_CLI="/usr/local/bin/olares-cli" + echo "unpacking Olares installer to $INSTALL_OLARES_CLI..." + echo "" + tar -zxf ${CLI_FILE} olares-cli && chmod +x olares-cli + if [[ x"$os_type" == x"Darwin" ]]; then + if [ ! -f "/usr/local/Cellar/olares" ]; then + current_user=$(whoami) + $sh_c "sudo mkdir -p /usr/local/Cellar/olares && sudo chown ${current_user}:staff /usr/local/Cellar/olares" + fi + $sh_c "mv olares-cli /usr/local/Cellar/olares/olares-cli && \ + sudo rm -rf /usr/local/bin/olares-cli && \ + sudo ln -s /usr/local/Cellar/olares/olares-cli $INSTALL_OLARES_CLI" + else + $sh_c "mv olares-cli $INSTALL_OLARES_CLI" + fi if [[ $? -ne 0 ]]; then - echo "error: failed to download Olares installer" + echo "error: failed to unpack Olares installer" exit 1 - else - echo "Olares installer ${VERSION} download complete!" - echo "" fi fi - INSTALL_OLARES_CLI="/usr/local/bin/olares-cli" - echo "unpacking Olares installer to $INSTALL_OLARES_CLI..." - echo "" - tar -zxf ${CLI_FILE} olares-cli && chmod +x olares-cli - if [[ x"$os_type" == x"Darwin" ]]; then - if [ ! -f "/usr/local/Cellar/olares" ]; then - current_user=$(whoami) - $sh_c "sudo mkdir -p /usr/local/Cellar/olares && sudo chown ${current_user}:staff /usr/local/Cellar/olares" - fi - $sh_c "mv olares-cli /usr/local/Cellar/olares/olares-cli && \ - sudo rm -rf /usr/local/bin/olares-cli && \ - sudo ln -s /usr/local/Cellar/olares/olares-cli $INSTALL_OLARES_CLI" - else - $sh_c "mv olares-cli $INSTALL_OLARES_CLI" - fi - - if [[ $? -ne 0 ]]; then - echo "error: failed to unpack Olares installer" - exit 1 - fi fi PARAMS="--version $VERSION --base-dir $BASE_DIR" diff --git a/cli/cmd/ctl/os/release.go b/cli/cmd/ctl/os/release.go index dfdd45fab..ba231b024 100644 --- a/cli/cmd/ctl/os/release.go +++ b/cli/cmd/ctl/os/release.go @@ -48,7 +48,7 @@ func NewCmdRelease() *cobra.Command { } if version == "" { - version = fmt.Sprintf("0.0.0-local-dev-%s", time.Now().Format("20060102150405")) + version = fmt.Sprintf("1.12.0-local-%s", time.Now().Format("20060102150405")) fmt.Printf("--version unspecified, using: %s\n", version) time.Sleep(1 * time.Second) } diff --git a/cli/pkg/release/app/app.go b/cli/pkg/release/app/app.go index 249fe1abb..1d2c86ec5 100644 --- a/cli/pkg/release/app/app.go +++ b/cli/pkg/release/app/app.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "bytetrade.io/web3os/installer/pkg/core/util" ) @@ -21,13 +22,8 @@ func NewManager(olaresRepoRoot, distPath string) *Manager { } func (m *Manager) Package() error { - modules := []string{"frameworks", "libs", "apps", "third-party"} - buildTemplate := "build/installer" - - // Create dist directory if not exists - if err := os.MkdirAll(m.distPath, 0755); err != nil { - return err - } + modules := []string{"apps", "framework", "daemon", "infrastructure", "platform", "vendor"} + buildTemplate := "build/base-package" // Copy template files if err := util.CopyDirectory(buildTemplate, m.distPath); err != nil { @@ -55,46 +51,47 @@ func (m *Manager) Package() error { func (m *Manager) packageModule(mod string) error { modPath := filepath.Join(m.olaresRepoRoot, mod) - entries, err := os.ReadDir(modPath) - if err != nil { - return err - } - - for _, entry := range entries { - if !entry.IsDir() { - continue + err := filepath.Walk(modPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + if !strings.EqualFold(info.Name(), ".olares") { + return nil } - app := entry.Name() - - fmt.Printf("packaging %s ... \n", app) + fmt.Printf("packaging %s ... \n", path) // Package user app charts - chartPath := filepath.Join(modPath, app, "config/user/helm-charts") + chartPath := filepath.Join(path, "config/user/helm-charts") if err := util.CopyDirectoryIfExists(chartPath, filepath.Join(m.distPath, "wizard/config/apps")); err != nil { return err } // Package cluster CRDs - crdPath := filepath.Join(modPath, app, "config/cluster/crds") + crdPath := filepath.Join(path, "config/cluster/crds") if err := util.CopyDirectoryIfExists(crdPath, filepath.Join(m.distPath, "wizard/config/settings/templates/crds")); err != nil { return err } // Package cluster deployments - deployPath := filepath.Join(modPath, app, "config/cluster/deploy") + deployPath := filepath.Join(path, "config/cluster/deploy") if err := util.CopyDirectoryIfExists(deployPath, filepath.Join(m.distPath, "wizard/config/system/templates/deploy")); err != nil { return err } - } - return nil + return nil + }) + + return err } func (m *Manager) packageLauncher() error { fmt.Println("packaging launcher ...") return util.CopyDirectory( - filepath.Join(m.olaresRepoRoot, "frameworks/bfl/config/launcher"), + filepath.Join(m.olaresRepoRoot, "framework/bfl/.olares/config/launcher"), filepath.Join(m.distPath, "wizard/config/launcher"), ) } @@ -102,7 +99,7 @@ func (m *Manager) packageLauncher() error { func (m *Manager) packageGPU() error { fmt.Println("packaging gpu ...") return util.CopyDirectory( - filepath.Join(m.olaresRepoRoot, "frameworks/GPU/config/gpu"), + filepath.Join(m.olaresRepoRoot, "framework/gpu/.olares/config/gpu"), filepath.Join(m.distPath, "wizard/config/gpu"), ) } diff --git a/cli/pkg/release/builder/builder.go b/cli/pkg/release/builder/builder.go index 452c85774..f790c850b 100644 --- a/cli/pkg/release/builder/builder.go +++ b/cli/pkg/release/builder/builder.go @@ -23,62 +23,44 @@ func NewBuilder(olaresRepoRoot, version, cdnURL string, ignoreMissingImages bool olaresRepoRoot: olaresRepoRoot, distPath: distPath, version: version, - manifestManager: manifest.NewManager(olaresRepoRoot, cdnURL, ignoreMissingImages), + manifestManager: manifest.NewManager(olaresRepoRoot, distPath, cdnURL, ignoreMissingImages), appManager: app.NewManager(olaresRepoRoot, distPath), } } func (b *Builder) Build() (string, error) { // Clean previous build - if err := os.RemoveAll(filepath.Join(b.olaresRepoRoot, ".dist")); err != nil { + if err := os.RemoveAll(b.distPath); err != nil { return "", fmt.Errorf("failed to clean previous dist directory: %v", err) } + // Create dist directory if not exists + if err := os.MkdirAll(b.distPath, 0755); err != nil { + return "", err + } + // Package apps if err := b.appManager.Package(); err != nil { return "", fmt.Errorf("package apps failed: %v", err) } - // Build manifest - if err := b.manifestManager.Build(); err != nil { - return "", fmt.Errorf("manifest build failed: %v", err) - } - - // Copy upgrade script, as the current build.sh does - if err := util.CopyFile( - filepath.Join(b.olaresRepoRoot, "scripts/upgrade.sh"), - filepath.Join(b.distPath, "upgrade.sh"), - ); err != nil { - return "", fmt.Errorf("failed to copy upgrade script: %v", err) + // Generate manifest + if err := b.manifestManager.Generate(); err != nil { + return "", fmt.Errorf("failed to generate manifest: %v", err) } // archive the install-wizard - return b.createFinalPackage() + return b.archive() } -func (b *Builder) createFinalPackage() (string, error) { - if err := os.RemoveAll(filepath.Join(b.distPath, "images")); err != nil { - return "", err - } - - manifestSrc := filepath.Join(b.olaresRepoRoot, ".manifest/installation.manifest") - manifestDst := filepath.Join(b.distPath, "installation.manifest") - if err := util.MoveFile(manifestSrc, manifestDst); err != nil { - return "", err - } - - imagesSrc := filepath.Join(b.olaresRepoRoot, ".manifest") - imagesDst := filepath.Join(b.distPath, "images") - if err := util.MoveDirectory(imagesSrc, imagesDst); err != nil { - return "", err - } - +func (b *Builder) archive() (string, error) { versionStr := "v" + b.version files := []string{ filepath.Join(b.distPath, "wizard/config/settings/templates/terminus_cr.yaml"), filepath.Join(b.distPath, "install.sh"), filepath.Join(b.distPath, "install.ps1"), + filepath.Join(b.distPath, "joincluster.sh"), } for _, file := range files { diff --git a/cli/pkg/release/manifest/manifest.go b/cli/pkg/release/manifest/manifest.go index 066c3e1af..c1dd00e26 100644 --- a/cli/pkg/release/manifest/manifest.go +++ b/cli/pkg/release/manifest/manifest.go @@ -2,7 +2,6 @@ package manifest import ( "bufio" - "bytetrade.io/web3os/installer/pkg/core/util" "crypto/md5" "fmt" dockerref "github.com/containerd/containerd/reference/docker" @@ -11,127 +10,68 @@ import ( "os" "path/filepath" "regexp" + "sigs.k8s.io/kustomize/kyaml/yaml" "sort" "strings" ) -type Manager struct { - olaresRepoRoot string - cdnURL string - ignoreMissingImages bool +type OlaresManifest struct { + APIVersion string `yaml:"apiVersion"` + Target string `yaml:"target"` + Output OutputManifest `yaml:"output"` } -func NewManager(olaresRepoRoot, cdnURL string, ignoreMissingImages bool) *Manager { +type OutputManifest struct { + Binaries []BinaryOutput `yaml:"binaries"` + Containers []ContainerOutput `yaml:"containers"` +} + +type BinaryOutput struct { + ID string `yaml:"id"` + Name string `yaml:"name"` + AMD64 string `yaml:"amd64"` + ARM64 string `yaml:"arm64"` +} + +type ContainerOutput struct { + Name string `yaml:"name"` +} + +type Manager struct { + olaresRepoRoot string + distPath string + cdnURL string + ignoreMissingImages bool + extractedImages []string + extractedComponents []BinaryOutput +} + +func NewManager(olaresRepoRoot, distPath, cdnURL string, ignoreMissingImages bool) *Manager { return &Manager{ olaresRepoRoot: olaresRepoRoot, + distPath: distPath, cdnURL: cdnURL, ignoreMissingImages: ignoreMissingImages, } } -func (m *Manager) generateImageManifest() error { - manifestDir := filepath.Join(m.olaresRepoRoot, ".manifest") - if err := os.RemoveAll(manifestDir); err != nil { +func (m *Manager) Generate() error { + if err := m.scan(); err != nil { + return fmt.Errorf("failed to scan Olares repository for images and components: %v", err) + } + + manifestPath := filepath.Join(m.distPath, "installation.manifest") + f, err := os.OpenFile(manifestPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { return err } - if err := os.MkdirAll(manifestDir, 0755); err != nil { + defer f.Close() + + if err := m.writeComponents(f); err != nil { return err } - imageManifest := filepath.Join(manifestDir, "images.mf") - - // Copy default base images - if err := util.CopyFile( - filepath.Join(m.olaresRepoRoot, "build/manifest/images"), - imageManifest, - ); err != nil { - return err - } - - if err := util.CopyFile( - filepath.Join(m.olaresRepoRoot, "build/manifest/images.node.mf"), - filepath.Join(manifestDir, "images.node.mf"), - ); err != nil { - return err - } - - // Find images in app modules - modules := []string{"frameworks", "libs", "apps", "third-party"} - tmpManifest := filepath.Join(manifestDir, "tmp.image.manifest") - - for _, mod := range modules { - entries, err := os.ReadDir(filepath.Join(m.olaresRepoRoot, mod)) - if err != nil { - continue - } - - for _, entry := range entries { - if !entry.IsDir() { - continue - } - - chartPath := filepath.Join(m.olaresRepoRoot, mod, entry.Name(), "config") - if err := m.findImagesInPath(chartPath, tmpManifest); err != nil { - return err - } - } - } - - // Process temporary manifest - return m.processTemporaryManifest(tmpManifest, imageManifest) -} - -func (m *Manager) generateDepsManifest() error { - depsDir := filepath.Join(m.olaresRepoRoot, ".dependencies") - if err := os.RemoveAll(depsDir); err != nil { - return err - } - if err := os.MkdirAll(depsDir, 0755); err != nil { - return err - } - - // Copy components and pkgs - files := []string{"components", "pkgs"} - for _, file := range files { - if err := util.CopyFile( - filepath.Join(m.olaresRepoRoot, "build/manifest", file), - filepath.Join(depsDir, file), - ); err != nil { - return err - } - } - - return nil -} - -func (m *Manager) Build() error { - if err := m.generateImageManifest(); err != nil { - return fmt.Errorf("image manifest generation failed: %v", err) - } - - if err := m.generateDepsManifest(); err != nil { - return fmt.Errorf("deps manifest generation failed: %v", err) - } - - // Move dependencies - if err := util.MoveDirectory( - filepath.Join(m.olaresRepoRoot, ".dependencies"), - filepath.Join(m.olaresRepoRoot, ".manifest"), - ); err != nil { - return fmt.Errorf("failed to move dependencies: %v", err) - } - - manifestFile := filepath.Join(m.olaresRepoRoot, ".manifest/installation.manifest") - - // Process components and pkgs - deps := []string{"components", "pkgs"} - for _, dep := range deps { - if err := m.processDependencies(dep, manifestFile); err != nil { - return err - } - } - - return m.processImages(manifestFile) + return m.writeImages(f) } func (m *Manager) downloadChecksum(name string) (string, error) { @@ -160,39 +100,22 @@ func (m *Manager) downloadChecksum(name string) (string, error) { return strings.Fields(string(body))[0], nil } -func (m *Manager) processDependencies(depType, manifestFile string) error { - file, err := os.Open(filepath.Join(m.olaresRepoRoot, ".manifest", depType)) - if err != nil { - return err - } - defer file.Close() - - manifestOut, err := os.OpenFile(manifestFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer manifestOut.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := scanner.Text() - if line == "" { - continue +func (m *Manager) writeComponents(out io.Writer) error { + for _, component := range m.extractedComponents { + var fileName, path string + fields := strings.Split(component.Name, ",") + fileName = strings.TrimSpace(fields[0]) + if len(fields) > 1 { + path = strings.TrimSpace(fields[1]) + } else { + path = "pkg/components" } + md5Name := fmt.Sprintf("%x", md5.Sum([]byte(fileName))) - fields := strings.Split(line, ",") - if len(fields) < 5 { - return fmt.Errorf("invalid format: %s", line) - } + urlAMD64 := md5Name + urlARM64 := "arm64/" + md5Name - filename := fields[0] - path := fields[1] - name := fmt.Sprintf("%x", md5.Sum([]byte(filename))) - - urlAMD64 := name - urlARM64 := "arm64/" + name - - fmt.Printf("downloading md5 checksum for dependency %s, object: %s\n", filename, name) + fmt.Printf("downloading md5 checksum for dependency %s, object: %s\n", fileName, md5Name) checksumAMD64, err := m.downloadChecksum(urlAMD64) if err != nil { @@ -204,99 +127,100 @@ func (m *Manager) processDependencies(depType, manifestFile string) error { return err } - fmt.Fprintf(manifestOut, "%s,%s,%s,%s,%s,%s,%s,%s\n", - filename, path, depType, urlAMD64, checksumAMD64, urlARM64, checksumARM64, fields[4]) + _, err = fmt.Fprintf(out, "%s,%s,%s,%s,%s,%s,%s,%s\n", + fileName, path, "", urlAMD64, checksumAMD64, urlARM64, checksumARM64, component.ID) + if err != nil { + return err + } } - - return scanner.Err() + return nil } -func (m *Manager) processImages(manifestFile string) error { - path := "images" - manifestOut, err := os.OpenFile(manifestFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer manifestOut.Close() - - imagesList, err := os.Open(filepath.Join(m.olaresRepoRoot, ".manifest/images.mf")) - if err != nil { - return err - } - defer imagesList.Close() - - scanner := bufio.NewScanner(imagesList) - for scanner.Scan() { - line := scanner.Text() - if line == "" { - continue - } - +func (m *Manager) writeImages(out io.Writer) error { + for _, image := range m.extractedImages { // Generate MD5 hash of the image name - name := fmt.Sprintf("%x", md5.Sum([]byte(line))) + md5Name := fmt.Sprintf("%x", md5.Sum([]byte(image))) // Define URLs for both architectures - urlAMD64 := name + ".tar.gz" - urlARM64 := "arm64/" + name + ".tar.gz" + urlAMD64 := md5Name + ".tar.gz" + urlARM64 := "arm64/" + md5Name + ".tar.gz" - fmt.Printf("downloading checksum for image %s, object: %s\n", line, urlAMD64) + fmt.Printf("downloading checksum for image %s, object: %s\n", image, md5Name) - checksumAMD64, err := m.downloadChecksum(name) + checksumAMD64, err := m.downloadChecksum(md5Name) if err != nil { - return fmt.Errorf("failed to download AMD64 checksum for %s: %v", line, err) + return fmt.Errorf("failed to download AMD64 checksum for %s: %v", image, err) } if checksumAMD64 == "" { if m.ignoreMissingImages { - fmt.Printf("skipping image %s due to missing checksum\n", line) + fmt.Printf("skipping image %s due to missing checksum\n", image) continue } - return fmt.Errorf("got empty checksum for image %s", line) + return fmt.Errorf("got empty checksum for image %s", image) } - checksumARM64, err := m.downloadChecksum("arm64/" + name) + checksumARM64, err := m.downloadChecksum("arm64/" + md5Name) if err != nil { - return fmt.Errorf("failed to download ARM64 checksum for %s: %v", line, err) + return fmt.Errorf("failed to download ARM64 checksum for %s: %v", image, err) } - // Write to manifest file - _, err = fmt.Fprintf(manifestOut, "%s.tar.gz,%s,%s,%s,%s,%s,%s,%s\n", - name, path, "images.mf", urlAMD64, checksumAMD64, urlARM64, checksumARM64, line) + _, err = fmt.Fprintf(out, "%s.tar.gz,%s,%s,%s,%s,%s,%s,%s\n", + md5Name, "images", "images.mf", urlAMD64, checksumAMD64, urlARM64, checksumARM64, image) if err != nil { return fmt.Errorf("failed to write to manifest file: %v", err) } } - return scanner.Err() + return nil } -func (m *Manager) findImagesInPath(path string, tmpManifest string) error { - // Open temporary manifest file for appending - tmpFile, err := os.OpenFile(tmpManifest, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer tmpFile.Close() +func (m *Manager) scan() error { + var images []string + uniqueComponents := make(map[string]BinaryOutput) - // Walk through all yaml files in the path - err = filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error { + err := filepath.Walk(m.olaresRepoRoot, func(filePath string, info os.FileInfo, err error) error { if err != nil { if os.IsNotExist(err) { - relPath, _ := filepath.Rel(m.olaresRepoRoot, filePath) - fmt.Printf("skipping non existing path: %s\n", relPath) return nil } return err } - // Only process yaml files + // shortcut to Olares manifest file + if strings.EqualFold(info.Name(), "olares.yaml") { + content, err := os.ReadFile(filePath) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + olaresManifest := &OlaresManifest{} + err = yaml.Unmarshal(content, olaresManifest) + if err != nil { + return fmt.Errorf("failed to unmarshal olares manifest %s: %v", filePath, err) + } + + for _, c := range olaresManifest.Output.Containers { + images = append(images, c.Name) + } + + for _, b := range olaresManifest.Output.Binaries { + uniqueComponents[b.ID] = b + } + + return nil + } + + // extract image from ordinary kubernetes yaml files if !info.IsDir() && (strings.HasSuffix(filePath, ".yaml") || strings.HasSuffix(filePath, ".yml")) { targetFile, err := os.Open(filePath) if err != nil { + if os.IsNotExist(err) { + return nil + } return err } - defer targetFile.Close() - - relPath, _ := filepath.Rel(m.olaresRepoRoot, filePath) scanner := bufio.NewScanner(targetFile) for scanner.Scan() { line := scanner.Text() @@ -306,97 +230,45 @@ func (m *Manager) findImagesInPath(path string, tmpManifest string) error { image := strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(line), "image:")) image = strings.Trim(image, "'") image = strings.Trim(image, "\"") - - // probably some other config yaml - // instead of a container spec - if image == "" { - fmt.Printf("skipping empty image key in file: %s, line: %s\n", relPath, line) - continue - } - - image, err = m.patchImage(image) - if err != nil { - return fmt.Errorf("failed to patch image %s: %v", image, err) - } - - if _, err := dockerref.ParseDockerRef(image); err != nil { - fmt.Printf("skipping invalid image key: %s in file: %s, line: %s\n", image, relPath, line) - continue - } - - // Skip specific images - if strings.Contains(image, "nitro") || strings.Contains(image, "orion") { - fmt.Printf("skipping image %s in file: %s, line: %s\n", image, relPath, line) - continue - } - - fmt.Printf("found image %s in file %s\n", image, relPath) - // Write image to temporary manifest - if _, err := fmt.Fprintln(tmpFile, image); err != nil { - return err - } + images = append(images, image) } } + return nil }) - return err -} - -func (m *Manager) processTemporaryManifest(tmpManifest, imageManifest string) error { - // Read temporary manifest - tmpContent, err := os.ReadFile(tmpManifest) - if err != nil { - return err - } - - // Create a map to store unique images uniqueImages := make(map[string]struct{}) - // remove this logic for now - // to maintain a same order as the one - // built from shell script - // Add existing images from image manifest - //existingContent, err := os.ReadFile(imageManifest) - //if err != nil { - // return err - //} - //for _, line := range strings.Split(string(existingContent), "\n") { - // if line = strings.TrimSpace(line); line != "" { - // uniqueImages[line] = struct{}{} - // } - //} - - // Add new images from temporary manifest - for _, line := range strings.Split(string(tmpContent), "\n") { - if line = strings.TrimSpace(line); line != "" { - uniqueImages[line] = struct{}{} - } - } - - // Write unique images back to image manifest - manifestFile, err := os.OpenFile(imageManifest, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) - if err != nil { - return err - } - defer manifestFile.Close() - - // Convert map to sorted slice for consistent output - var images []string - for image := range uniqueImages { - images = append(images, image) - } - sort.Strings(images) - - // Write sorted images to manifest for _, image := range images { - if _, err := fmt.Fprintln(manifestFile, image); err != nil { - return err + image = strings.TrimSpace(image) + if image == "" { + continue } + + image, err = m.patchImage(image) + if err != nil { + return fmt.Errorf("failed to patch image %s: %v", image, err) + } + + if _, err := dockerref.ParseDockerRef(image); err != nil { + continue + } + + uniqueImages[image] = struct{}{} } - // Clean up temporary manifest - return os.Remove(tmpManifest) + var sortedImages []string + for image := range uniqueImages { + sortedImages = append(sortedImages, image) + } + sort.Strings(sortedImages) + m.extractedImages = sortedImages + + for _, component := range uniqueComponents { + m.extractedComponents = append(m.extractedComponents, component) + } + + return nil } // Helper function to patch extracted image name @@ -407,7 +279,7 @@ func (m *Manager) patchImage(image string) (string, error) { if !strings.Contains(image, backupServerImageVersionTpl) { return image, nil } - backupConfigPath := filepath.Join(m.olaresRepoRoot, "frameworks/backup-server/config/cluster/deploy/backup_server.yaml") + backupConfigPath := filepath.Join(m.olaresRepoRoot, "framework/backup-server/.olares/config/cluster/deploy/backup_server.yaml") content, err := os.ReadFile(backupConfigPath) if err != nil { return "", err