Skip to content

Commit f64314b

Browse files
authored
feat(bootstrap-gcp): install from local package (#208)
* Upload a locally built/downloaded package to the * Install from the local package * Enable UseConcurrentWrites in sftp client to speedup transfer of large files --------- Signed-off-by: NautiluX <2600004+NautiluX@users.noreply.github.com> Co-authored-by: NautiluX <2600004+NautiluX@users.noreply.github.com>
1 parent 1e92d94 commit f64314b

File tree

5 files changed

+245
-72
lines changed

5 files changed

+245
-72
lines changed

cli/cmd/bootstrap_gcp.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ func AddBootstrapGcpCmd(parent *cobra.Command, opts *GlobalOptions) {
7777
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.Zone, "zone", "europe-west4-a", "GCP Zone (default: europe-west4-a)")
7878
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.DNSProjectID, "dns-project-id", "", "GCP Project ID for Cloud DNS (optional)")
7979
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.DNSZoneName, "dns-zone-name", "oms-testing", "Cloud DNS Zone Name (optional)")
80+
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallLocal, "install-local", "", "Install Codesphere from local package (default: none)")
8081
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallVersion, "install-version", "", "Codesphere version to install (default: none)")
8182
flags.StringVar(&bootstrapGcpCmd.CodesphereEnv.InstallHash, "install-hash", "", "Codesphere package hash to install (default: none)")
8283
flags.StringArrayVarP(&bootstrapGcpCmd.CodesphereEnv.InstallSkipSteps, "install-skip-steps", "s", []string{}, "Installation steps to skip during Codesphere installation (optional)")

docs/oms-cli_beta_bootstrap-gcp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ oms-cli beta bootstrap-gcp [flags]
3333
-h, --help help for bootstrap-gcp
3434
--install-config string Path to install config file (optional) (default "config.yaml")
3535
--install-hash string Codesphere package hash to install (default: none)
36+
--install-local string Install Codesphere from local package (default: none)
3637
-s, --install-skip-steps stringArray Installation steps to skip during Codesphere installation (optional)
3738
--install-version string Codesphere version to install (default: none)
3839
--openbao-engine string OpenBao engine name (default: cs-secrets-engine) (default "cs-secrets-engine")

internal/bootstrap/gcp/gcp.go

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ type CodesphereEnvironment struct {
8989
ContainerRegistryURL string `json:"-"`
9090
ExistingConfigUsed bool `json:"-"`
9191
InstallVersion string `json:"install_version"`
92+
InstallLocal string `json:"install_local"`
9293
InstallHash string `json:"install_hash"`
9394
InstallSkipSteps []string `json:"install_skip_steps"`
9495
Preemptible bool `json:"preemptible"`
@@ -160,14 +161,12 @@ func GetInfraFilePath() string {
160161
}
161162

162163
func (b *GCPBootstrapper) Bootstrap() error {
163-
if b.Env.InstallVersion != "" {
164-
err := b.stlog.Step("Validate input", b.ValidateInput)
165-
if err != nil {
166-
return fmt.Errorf("invalid input: %w", err)
167-
}
168-
164+
err := b.stlog.Step("Validate input", b.ValidateInput)
165+
if err != nil {
166+
return fmt.Errorf("invalid input: %w", err)
169167
}
170-
err := b.stlog.Step("Ensure install config", b.EnsureInstallConfig)
168+
169+
err = b.stlog.Step("Ensure install config", b.EnsureInstallConfig)
171170
if err != nil {
172171
return fmt.Errorf("failed to ensure install config: %w", err)
173172
}
@@ -285,7 +284,7 @@ func (b *GCPBootstrapper) Bootstrap() error {
285284
return fmt.Errorf("failed to generate k0s config script: %w", err)
286285
}
287286

288-
if b.Env.InstallVersion != "" {
287+
if b.Env.InstallVersion != "" || b.Env.InstallLocal != "" {
289288
err = b.stlog.Step("Install Codesphere", b.InstallCodesphere)
290289
if err != nil {
291290
return fmt.Errorf("failed to install Codesphere: %w", err)
@@ -300,7 +299,30 @@ func (b *GCPBootstrapper) Bootstrap() error {
300299
return nil
301300
}
302301

302+
// ValidateInput checks that the required input parameters are set and valid
303303
func (b *GCPBootstrapper) ValidateInput() error {
304+
err := b.validateInstallVersion()
305+
if err != nil {
306+
return err
307+
}
308+
309+
return b.validateGithubParams()
310+
}
311+
312+
// validateInstallVersion checks if the specified install version exists and contains the required installer artifact
313+
func (b *GCPBootstrapper) validateInstallVersion() error {
314+
if b.Env.InstallLocal != "" {
315+
if b.Env.InstallVersion != "" || b.Env.InstallHash != "" {
316+
return fmt.Errorf("cannot specify both install-local and install-version/install-hash")
317+
}
318+
if !b.fw.Exists(b.Env.InstallLocal) {
319+
return fmt.Errorf("local installer package not found at path: %s", b.Env.InstallLocal)
320+
}
321+
return nil
322+
}
323+
if b.Env.InstallVersion == "" {
324+
return nil
325+
}
304326
build, err := b.PortalClient.GetBuild(portal.CodesphereProduct, b.Env.InstallVersion, b.Env.InstallHash)
305327
if err != nil {
306328
return fmt.Errorf("failed to get codesphere package: %w", err)
@@ -323,12 +345,17 @@ func (b *GCPBootstrapper) ValidateInput() error {
323345
}
324346
}
325347

348+
return fmt.Errorf("specified package does not contain required installer artifact %s. Existing artifacts: %s", requiredFilename, strings.Join(filenames, ", "))
349+
}
350+
351+
// validateGithubParams checks if the GitHub credentials are fully specified if GitHub registry is selected
352+
func (b *GCPBootstrapper) validateGithubParams() error {
326353
ghParams := []string{b.Env.GitHubAppName, b.Env.GithubAppClientID, b.Env.GithubAppClientSecret}
327354
if slices.Contains(ghParams, "") && strings.Join(ghParams, "") != "" {
328355
return fmt.Errorf("GitHub app credentials are not fully specified (all or none of GitHubAppName, GithubAppClientID, GithubAppClientSecret must be set)")
329356
}
330357

331-
return fmt.Errorf("specified package does not contain required installer artifact %s. Existing artifacts: %s", requiredFilename, strings.Join(filenames, ", "))
358+
return nil
332359
}
333360

334361
func (b *GCPBootstrapper) EnsureInstallConfig() error {
@@ -1401,36 +1428,70 @@ func (b *GCPBootstrapper) EnsureDNSRecords() error {
14011428
}
14021429

14031430
func (b *GCPBootstrapper) InstallCodesphere() error {
1404-
packageFile := "installer.tar.gz"
1405-
skipSteps := b.Env.InstallSkipSteps
1431+
fullPackageFilename, err := b.ensureCodespherePackageOnJumpbox()
1432+
if err != nil {
1433+
return fmt.Errorf("failed to ensure Codesphere package on jumpbox: %w", err)
1434+
}
1435+
1436+
err = b.runInstallCommand(fullPackageFilename)
1437+
if err != nil {
1438+
return fmt.Errorf("failed to install Codesphere from jumpbox: %w", err)
1439+
}
1440+
1441+
return nil
1442+
}
1443+
1444+
func (b *GCPBootstrapper) ensureCodespherePackageOnJumpbox() (string, error) {
1445+
packageFilename := "installer.tar.gz"
14061446
if b.Env.RegistryType == RegistryTypeGitHub {
1407-
skipSteps = append(skipSteps, "load-container-images")
1408-
packageFile = "installer-lite.tar.gz"
1447+
packageFilename = "installer-lite.tar.gz"
14091448
}
1410-
skipStepsArg := ""
1411-
if len(skipSteps) > 0 {
1412-
skipStepsArg = " -s " + strings.Join(skipSteps, ",")
1449+
1450+
if b.Env.InstallLocal != "" {
1451+
b.stlog.Logf("Copying local package %s to jumpbox...", b.Env.InstallLocal)
1452+
fullPackageFilename := fmt.Sprintf("local-%s", packageFilename)
1453+
err := b.Env.Jumpbox.NodeClient.CopyFile(b.Env.Jumpbox, b.Env.InstallLocal, "/root/"+fullPackageFilename)
1454+
if err != nil {
1455+
return "", fmt.Errorf("failed to copy local install package to jumpbox: %w", err)
1456+
}
1457+
return fullPackageFilename, nil
14131458
}
14141459

1415-
downloadCmd := "oms-cli download package -f " + packageFile
1416-
if b.Env.InstallHash != "" {
1417-
downloadCmd += " -H " + b.Env.InstallHash
1460+
if b.Env.InstallVersion == "" {
1461+
return "", errors.New("either install version or a local package must be specified to install Codesphere")
14181462
}
1419-
downloadCmd += " " + b.Env.InstallVersion
1463+
1464+
fullPackageFilename := portal.BuildPackageFilenameFromParts(b.Env.InstallVersion, b.Env.InstallHash, packageFilename)
1465+
if b.Env.InstallHash == "" {
1466+
return "", fmt.Errorf("install hash must be set when install version is set")
1467+
}
1468+
b.stlog.Logf("Downloading Codesphere package...")
1469+
downloadCmd := fmt.Sprintf("oms-cli download package -f %s -H %s %s", packageFilename, b.Env.InstallHash, b.Env.InstallVersion)
14201470
err := b.Env.Jumpbox.RunSSHCommand("root", downloadCmd)
14211471
if err != nil {
1422-
return fmt.Errorf("failed to download Codesphere package from jumpbox: %w", err)
1472+
return "", fmt.Errorf("failed to download Codesphere package from jumpbox: %w", err)
14231473
}
14241474

1425-
fullPackageFilename := portal.BuildPackageFilenameFromParts(b.Env.InstallVersion, b.Env.InstallHash, packageFile)
1475+
return fullPackageFilename, nil
1476+
}
1477+
1478+
func (b *GCPBootstrapper) runInstallCommand(packageFilename string) error {
1479+
b.stlog.Logf("Installing Codesphere...")
14261480
installCmd := fmt.Sprintf("oms-cli install codesphere -c /etc/codesphere/config.yaml -k %s/age_key.txt -p %s%s",
1427-
b.Env.SecretsDir, fullPackageFilename, skipStepsArg)
1428-
err = b.Env.Jumpbox.RunSSHCommand("root", installCmd)
1429-
if err != nil {
1430-
return fmt.Errorf("failed to install Codesphere from jumpbox: %w", err)
1481+
b.Env.SecretsDir, packageFilename, b.generateSkipStepsArg())
1482+
return b.Env.Jumpbox.RunSSHCommand("root", installCmd)
1483+
}
1484+
1485+
func (b *GCPBootstrapper) generateSkipStepsArg() string {
1486+
skipSteps := b.Env.InstallSkipSteps
1487+
if b.Env.RegistryType == RegistryTypeGitHub {
1488+
skipSteps = append(skipSteps, "load-container-images")
1489+
}
1490+
if len(skipSteps) == 0 {
1491+
return ""
14311492
}
14321493

1433-
return nil
1494+
return " -s " + strings.Join(skipSteps, ",")
14341495
}
14351496

14361497
func (b *GCPBootstrapper) GenerateK0sConfigScript() error {

0 commit comments

Comments
 (0)