mirror of
https://github.com/beclab/Olares
synced 2026-05-24 01:08:23 +00:00
cli(refactor): adjust local release logic for new project structure (#1355)
This commit is contained in:
parent
a034b37239
commit
4e7ba01bcd
5 changed files with 218 additions and 359 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue