Skip to content

Commit

Permalink
Merge pull request #46 from beclab/feat/local_release
Browse files Browse the repository at this point in the history
feat: add command to build local release of Olares
  • Loading branch information
eball authored Nov 22, 2024
2 parents bb40f3f + b721e3b commit dec1775
Show file tree
Hide file tree
Showing 9 changed files with 789 additions and 210 deletions.
83 changes: 83 additions & 0 deletions cmd/ctl/os/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package os

import (
"bytetrade.io/web3os/installer/pkg/core/common"
"bytetrade.io/web3os/installer/pkg/core/util"
"bytetrade.io/web3os/installer/pkg/release/builder"
"fmt"
"os"
"os/user"
"path/filepath"
"time"

"github.com/spf13/cobra"
)

func NewCmdRelease() *cobra.Command {
var (
baseDir string
version string
cdn string
ignoreMissingImages bool
extract bool
)

cmd := &cobra.Command{
Use: "release",
Short: "Build release based on a local Olares repository",
Run: func(cmd *cobra.Command, args []string) {
cwd, err := os.Getwd()
if err != nil {
fmt.Printf("failed to get current working directory: %s\n", err)
os.Exit(1)
}
if filepath.Base(cwd) != "Olares" {
fmt.Println("error: please run release command under the root path of Olares repo")
os.Exit(1)
}
if baseDir == "" {
usr, err := user.Current()
if err != nil {
fmt.Printf("failed to get current user: %s\n", err)
os.Exit(1)
}
baseDir = filepath.Join(usr.HomeDir, common.DefaultBaseDir)
fmt.Printf("--base-dir unspecified, using: %s\n", baseDir)
time.Sleep(1 * time.Second)
}

if version == "" {
version = fmt.Sprintf("0.0.0-local-dev-%s", time.Now().Format("20060102150405"))
fmt.Printf("--version unspecified, using: %s\n", version)
time.Sleep(1 * time.Second)
}

wizardFile, err := builder.NewBuilder(cwd, version, cdn, ignoreMissingImages).Build()
if err != nil {
fmt.Printf("failed to build release: %s\n", err)
os.Exit(1)
}
fmt.Printf("\nsuccessfully built release\nversion: %s\n package: %s\n", version, wizardFile)
if extract {
dest := filepath.Join(baseDir, "versions", "v"+version)
if err := os.MkdirAll(dest, 0755); err != nil {
fmt.Printf("Failed to create new version directory for this release: %s\n", err)
os.Exit(1)
}
if err := util.Untar(wizardFile, dest); err != nil {
fmt.Printf("failed to extract release package: %s\n", err)
os.Exit(1)
}
fmt.Printf("\nrelease package is extracted to: %s\n", dest)
}
},
}

cmd.Flags().StringVarP(&baseDir, "base-dir", "b", "", "base directory of Olares, where this release will be extracted to as a new version if --extract/-e is not disabled, defaults to $HOME/"+common.DefaultBaseDir)
cmd.Flags().StringVarP(&version, "version", "v", "", "version of this release, defaults to 0.0.0-local-dev-{yyyymmddhhmmss}")
cmd.Flags().StringVar(&cdn, "download-cdn-url", common.DownloadUrl, "CDN used for downloading checksums of dependencies and images")
cmd.Flags().BoolVar(&ignoreMissingImages, "ignore-missing-images", true, "ignore missing images when downloading cheksums from CDN, only disable this if no new image is added, or the build may fail because the image is not uploaded to the CDN yet")
cmd.Flags().BoolVarP(&extract, "extract", "e", true, "extract this release to --base-dir after build, this can be disabled if only the release file itself is needed")

return cmd
}
1 change: 1 addition & 0 deletions cmd/ctl/os/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func NewCmdOs() *cobra.Command {
rootOsCmd.AddCommand(NewCmdInstallOs())
rootOsCmd.AddCommand(NewCmdUninstallOs())
rootOsCmd.AddCommand(NewCmdChangeIP())
rootOsCmd.AddCommand(NewCmdRelease())
rootOsCmd.AddCommand(NewCmdPrintInfo())

return rootOsCmd
Expand Down
2 changes: 1 addition & 1 deletion pkg/bootstrap/os/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ func (a *BackupFilesToDir) Execute(runtime connector.Runtime) error {
return errors.Wrapf(err, "failed to create backup dir %s for file %s", path.Dir(file), path.Base(file))
}
logger.Debugf("copying file %s to backup dir %s", file, a.BackupDir)
if err := util.CopyFile(file, path.Join(a.BackupDir, path.Dir(file))); err != nil {
if err := util.CopyFile(file, path.Join(a.BackupDir, file)); err != nil {
return errors.Wrapf(err, "failed to copy file %s to backup dir", file)
}
}
Expand Down
87 changes: 75 additions & 12 deletions pkg/core/util/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,34 +160,97 @@ func Mkdir(dirName string) error {
return os.MkdirAll(dirName, os.ModePerm)
}

func CopyFile(src, dst string) error {
cmd := exec.Command("cp", src, dst)
if err := cmd.Run(); err != nil {
func WriteFile(fileName string, content []byte, perm os.FileMode) error {
dir := filepath.Dir(fileName)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err = os.MkdirAll(dir, 0755); err != nil {
return err
}
}

if err := ioutil.WriteFile(fileName, content, perm); err != nil {
return err
}
return nil
}

func CopyFile(src, dst string) error {
sourceFile, err := os.Open(src)
if err != nil {
return err
}
defer sourceFile.Close()

dstDir := filepath.Dir(dst)
if err := os.MkdirAll(dstDir, 0755); err != nil {
return err
}

destFile, err := os.Create(dst)
if err != nil {
return err
}
defer destFile.Close()

_, err = io.Copy(destFile, sourceFile)
return err
}

func CopyFileToDir(src, dir string) error {
dest := filepath.Join(dir, filepath.Base(src))
return CopyFile(src, dest)
}

func MoveFile(src, dst string) error {
cmd := exec.Command("mv", src, dst)
if err := cmd.Run(); err != nil {
if err := CopyFile(src, dst); err != nil {
return err
}
return nil
return os.Remove(src)
}

func WriteFile(fileName string, content []byte, perm os.FileMode) error {
dir := filepath.Dir(fileName)
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err = os.MkdirAll(dir, 0755); err != nil {
func CopyDirectory(src, dst string) error {
return filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

relPath, err := filepath.Rel(src, path)
if err != nil {
return err
}

dstPath := filepath.Join(dst, relPath)

if info.IsDir() {
return os.MkdirAll(dstPath, info.Mode())
}

return CopyFile(path, dstPath)
})
}

func MoveDirectory(src, dst string) error {
if err := CopyDirectory(src, dst); err != nil {
return err
}
return os.RemoveAll(src)
}

if err := ioutil.WriteFile(fileName, content, perm); err != nil {
func CopyDirectoryIfExists(src, dstDir string) error {
if _, err := os.Stat(src); os.IsNotExist(err) {
return nil // Skip if source doesn't exist
}
return CopyDirectory(src, dstDir)
}

func ReplaceInFile(filepath, old, new string) error {
content, err := os.ReadFile(filepath)
if err != nil {
return err
}
return nil

newContent := strings.ReplaceAll(string(content), old, new)
return os.WriteFile(filepath, []byte(newContent), 0644)
}

func Tar(src, dst, trimPrefix string) error {
Expand Down
108 changes: 108 additions & 0 deletions pkg/release/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package app

import (
"fmt"
"os"
"path/filepath"

"bytetrade.io/web3os/installer/pkg/core/util"
)

type Manager struct {
olaresRepoRoot string
distPath string
}

func NewManager(olaresRepoRoot, distPath string) *Manager {
return &Manager{
olaresRepoRoot: olaresRepoRoot,
distPath: distPath,
}
}

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
}

// Copy template files
if err := util.CopyDirectory(buildTemplate, m.distPath); err != nil {
return err
}

// Package modules
for _, mod := range modules {
if err := m.packageModule(mod); err != nil {
return err
}
}

// Package launcher and GPU
if err := m.packageLauncher(); err != nil {
return err
}

if err := m.packageGPU(); err != nil {
return err
}

return nil
}

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
}

app := entry.Name()

fmt.Printf("packaging %s ... \n", app)

// Package user app charts
chartPath := filepath.Join(modPath, app, "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")
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")
if err := util.CopyDirectoryIfExists(deployPath, filepath.Join(m.distPath, "wizard/config/system/templates/deploy")); err != nil {
return err
}
}

return nil
}

func (m *Manager) packageLauncher() error {
fmt.Println("packaging launcher ...")
return util.CopyDirectory(
filepath.Join(m.olaresRepoRoot, "frameworks/bfl/config/launcher"),
filepath.Join(m.distPath, "wizard/config/launcher"),
)
}

func (m *Manager) packageGPU() error {
fmt.Println("packaging gpu ...")
return util.CopyDirectory(
filepath.Join(m.olaresRepoRoot, "frameworks/GPU/config/gpu"),
filepath.Join(m.distPath, "wizard/config/gpu"),
)
}
Loading

0 comments on commit dec1775

Please sign in to comment.