Skip to content

Commit e4b4285

Browse files
Merge branch 'main' into api-key-integration-test
2 parents 3c0ab1e + c3b6609 commit e4b4285

File tree

13 files changed

+700
-16
lines changed

13 files changed

+700
-16
lines changed

.github/workflows/cli-build_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
build:
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v5
1818

1919
- name: Set up Go
2020
uses: actions/setup-go@v6

.github/workflows/go-lint.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ jobs:
1414
name: lint
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v5
1818
- uses: actions/setup-go@v6
1919
with:
2020
go-version-file: 'go.mod'
2121
- name: golangci-lint
22-
uses: golangci/golangci-lint-action@v7
22+
uses: golangci/golangci-lint-action@v8
2323
with:
24-
version: v2.0
24+
version: v2.1

.github/workflows/service-build_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
build:
1515
runs-on: ubuntu-latest
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v5
1818

1919
- name: Set up Go
2020
uses: actions/setup-go@v6

.github/workflows/tag-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
needs: integration-tests
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v5
1818
with:
1919
fetch-tags: true
2020
fetch-depth: 0

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,10 @@ docs:
5959
generate-license: generate
6060
go-licenses report --template .NOTICE.template ./... > NOTICE
6161
copywrite headers apply
62+
63+
run-lima:
64+
limactl start ./hack/lima-oms.yaml
65+
66+
stop-lima:
67+
limactl stop lima-oms
68+
limactl delete lima-oms

cli/cmd/install.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type InstallCmd struct {
1313
cmd *cobra.Command
1414
}
1515

16-
func AddInstallCmd(rootCmd *cobra.Command) {
16+
func AddInstallCmd(rootCmd *cobra.Command, opts *GlobalOptions) {
1717
install := InstallCmd{
1818
cmd: &cobra.Command{
1919
Use: "install",
@@ -22,4 +22,5 @@ func AddInstallCmd(rootCmd *cobra.Command) {
2222
},
2323
}
2424
rootCmd.AddCommand(install.cmd)
25+
AddInstallCodesphereCmd(install.cmd, opts)
2526
}

cli/cmd/install_codesphere.go

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,150 @@
44
package cmd
55

66
import (
7+
"fmt"
8+
"log"
9+
"os"
10+
"os/exec"
11+
"path/filepath"
12+
"runtime"
13+
"slices"
14+
715
"github.com/codesphere-cloud/cs-go/pkg/io"
16+
"github.com/codesphere-cloud/oms/internal/env"
17+
"github.com/codesphere-cloud/oms/internal/installer"
18+
"github.com/codesphere-cloud/oms/internal/util"
819
"github.com/spf13/cobra"
920
)
1021

1122
// InstallCodesphereCmd represents the codesphere command
1223
type InstallCodesphereCmd struct {
13-
cmd *cobra.Command
24+
cmd *cobra.Command
25+
Opts *InstallCodesphereOpts
26+
Env env.Env
27+
}
28+
29+
type InstallCodesphereOpts struct {
30+
*GlobalOptions
31+
Package string
32+
Force bool
33+
Config string
34+
PrivKey string
35+
SkipSteps []string
36+
}
37+
38+
func (c *InstallCodesphereCmd) RunE(_ *cobra.Command, args []string) error {
39+
workdir := c.Env.GetOmsWorkdir()
40+
p := installer.NewPackage(workdir, c.Opts.Package)
41+
42+
err := c.ExtractAndInstall(p, runtime.GOOS, runtime.GOARCH)
43+
if err != nil {
44+
return fmt.Errorf("failed to extract and install package: %w", err)
45+
}
46+
47+
return nil
1448
}
1549

16-
func AddInstallCodesphereCmd(install *cobra.Command) {
50+
func AddInstallCodesphereCmd(install *cobra.Command, opts *GlobalOptions) {
1751
codesphere := InstallCodesphereCmd{
1852
cmd: &cobra.Command{
1953
Use: "codesphere",
20-
Short: "Coming soon: Install a Codesphere instance",
21-
Long: io.Long(`Coming soon: Install a Codesphere instance`),
54+
Short: "Install a Codesphere instance",
55+
Long: io.Long(`Install a Codesphere instance with the provided package, configuration file, and private key.
56+
Uses the private-cloud-installer.js script included in the package to perform the installation.`),
2257
},
58+
Opts: &InstallCodesphereOpts{GlobalOptions: opts},
59+
Env: env.NewEnv(),
2360
}
61+
codesphere.cmd.Flags().StringVarP(&codesphere.Opts.Package, "package", "p", "", "Package file (e.g. codesphere-v1.2.3-installer.tar.gz) to load binaries, installer etc. from")
62+
codesphere.cmd.Flags().BoolVarP(&codesphere.Opts.Force, "force", "f", false, "Enforce package extraction")
63+
codesphere.cmd.Flags().StringVarP(&codesphere.Opts.Config, "config", "c", "", "Path to the Codesphere Private Cloud configuration file (yaml)")
64+
codesphere.cmd.Flags().StringVarP(&codesphere.Opts.PrivKey, "priv-key", "k", "", "Path to the private key to encrypt/decrypt secrets")
65+
codesphere.cmd.Flags().StringSliceVarP(&codesphere.Opts.SkipSteps, "skip-steps", "s", []string{}, "Steps to be skipped. Must be one of: copy-dependencies, extract-dependencies, load-container-images, ceph, kubernetes")
66+
67+
util.MarkFlagRequired(codesphere.cmd, "package")
68+
util.MarkFlagRequired(codesphere.cmd, "config")
69+
util.MarkFlagRequired(codesphere.cmd, "priv-key")
70+
2471
install.AddCommand(codesphere.cmd)
72+
codesphere.cmd.RunE = codesphere.RunE
73+
}
74+
75+
func (c *InstallCodesphereCmd) ExtractAndInstall(p *installer.Package, goos string, goarch string) error {
76+
if goos != "linux" || goarch != "amd64" {
77+
return fmt.Errorf("codesphere installation is only supported on Linux amd64. Current platform: %s/%s", goos, goarch)
78+
}
79+
80+
err := p.Extract(c.Opts.Force)
81+
if err != nil {
82+
return fmt.Errorf("failed to extract package to workdir: %w", err)
83+
}
84+
85+
foundFiles, err := c.ListPackageContents(p)
86+
if err != nil {
87+
return fmt.Errorf("failed to list available files: %w", err)
88+
}
89+
90+
if !slices.Contains(foundFiles, "deps.tar.gz") {
91+
return fmt.Errorf("deps.tar.gz not found in package")
92+
}
93+
if !slices.Contains(foundFiles, "private-cloud-installer.js") {
94+
return fmt.Errorf("private-cloud-installer.js not found in package")
95+
}
96+
if !slices.Contains(foundFiles, "node") {
97+
return fmt.Errorf("node executable not found in package")
98+
}
99+
100+
nodePath := filepath.Join(".", p.GetWorkDir(), "node")
101+
err = os.Chmod(nodePath, 0755)
102+
if err != nil {
103+
return fmt.Errorf("failed to make node executable: %w", err)
104+
}
105+
106+
log.Printf("Using Node.js executable: %s", nodePath)
107+
log.Println("Starting private cloud installer script...")
108+
installerPath := filepath.Join(".", p.GetWorkDir(), "private-cloud-installer.js")
109+
archivePath := filepath.Join(".", p.GetWorkDir(), "deps.tar.gz")
110+
111+
// Build command
112+
cmdArgs := []string{installerPath, "--archive", archivePath, "--config", c.Opts.Config, "--privKey", c.Opts.PrivKey}
113+
if len(c.Opts.SkipSteps) > 0 {
114+
for _, step := range c.Opts.SkipSteps {
115+
cmdArgs = append(cmdArgs, "--skipStep", step)
116+
}
117+
}
118+
119+
cmd := exec.Command(nodePath, cmdArgs...)
120+
cmd.Stdout = os.Stdout
121+
cmd.Stderr = os.Stderr
122+
cmd.Stdin = os.Stdin
123+
124+
err = cmd.Run()
125+
if err != nil {
126+
return fmt.Errorf("failed to run installer script: %w", err)
127+
}
128+
log.Println("Private cloud installer script finished.")
129+
130+
return nil
131+
}
132+
133+
func (c *InstallCodesphereCmd) ListPackageContents(p *installer.Package) ([]string, error) {
134+
packageDir := p.GetWorkDir()
135+
if !p.FileIO.Exists(packageDir) {
136+
return nil, fmt.Errorf("work dir not found: %s", packageDir)
137+
}
138+
139+
entries, err := p.FileIO.ReadDir(packageDir)
140+
if err != nil {
141+
return nil, fmt.Errorf("failed to read directory contents: %w", err)
142+
}
143+
144+
log.Printf("Listing contents of %s", packageDir)
145+
var foundFiles []string
146+
for _, entry := range entries {
147+
filename := entry.Name()
148+
log.Printf("- %s", filename)
149+
foundFiles = append(foundFiles, filename)
150+
}
151+
152+
return foundFiles, nil
25153
}

0 commit comments

Comments
 (0)