Installer: Clean up RepoIO interface
Change-Id: If80d7be1460c725b7df9d1d27c9354cb9141acfe
diff --git a/core/installer/bootstrapper.go b/core/installer/bootstrapper.go
index b981573..ad01140 100644
--- a/core/installer/bootstrapper.go
+++ b/core/installer/bootstrapper.go
@@ -24,13 +24,14 @@
const dnsAPIConfigMapName = "api-config"
type Bootstrapper struct {
- cl ChartLoader
- ns NamespaceCreator
- ha HelmActionConfigFactory
+ cl ChartLoader
+ ns NamespaceCreator
+ ha HelmActionConfigFactory
+ appRepo AppRepository
}
-func NewBootstrapper(cl ChartLoader, ns NamespaceCreator, ha HelmActionConfigFactory) Bootstrapper {
- return Bootstrapper{cl, ns, ha}
+func NewBootstrapper(cl ChartLoader, ns NamespaceCreator, ha HelmActionConfigFactory, appRepo AppRepository) Bootstrapper {
+ return Bootstrapper{cl, ns, ha, appRepo}
}
func (b Bootstrapper) Run(env EnvConfig) error {
@@ -75,30 +76,32 @@
fmt.Println("Failed to get config repo")
return err
}
- repoIO := NewRepoIO(repo, ss.Signer)
+ repoIO, err := NewRepoIO(repo, ss.Signer)
+ if err != nil {
+ return err
+ }
fmt.Println("Configuring main repo")
if err := configureMainRepo(repoIO, env); err != nil {
return err
}
fmt.Println("Installing infrastructure services")
- nsGen := NewPrefixGenerator(env.NamespacePrefix)
- if err := b.installInfrastructureServices(repoIO, nsGen, b.ns, env); err != nil {
+ if err := b.installInfrastructureServices(repoIO, env); err != nil {
return err
}
fmt.Println("Installing DNS Zone Manager")
- if err := b.installDNSZoneManager(ss, repoIO, nsGen, b.ns, env); err != nil {
+ if err := b.installDNSZoneManager(repoIO, env); err != nil {
return err
}
fmt.Println("Installing Fluxcd Reconciler")
- if err := b.installFluxcdReconciler(ss, repoIO, nsGen, b.ns, env); err != nil {
+ if err := b.installFluxcdReconciler(repoIO, ss, env); err != nil {
return err
}
fmt.Println("Installing env manager")
- if err := b.installEnvManager(ss, repoIO, nsGen, b.ns, env); err != nil {
+ if err := b.installEnvManager(repoIO, ss, env); err != nil {
return err
}
fmt.Println("Installing Ory Hydra Maester")
- if err := b.installOryHydraMaester(ss, repoIO, nsGen, b.ns, env); err != nil {
+ if err := b.installOryHydraMaester(repoIO, env); err != nil {
return err
}
fmt.Println("Environment ready to use")
@@ -320,8 +323,20 @@
if err != nil {
return err
}
- repoIO := NewRepoIO(repo, ss.Signer)
- if err := repoIO.WriteCommitAndPush("README.md", fmt.Sprintf("# %s systems", envName), "readme"); err != nil {
+ repoIO, err := NewRepoIO(repo, ss.Signer)
+ if err != nil {
+ return err
+ }
+ if err := repoIO.Atomic(func(r RepoFS) (string, error) {
+ w, err := r.Writer("README.md")
+ if err != nil {
+ return "", err
+ }
+ if _, err := fmt.Fprintf(w, "# %s systems", envName); err != nil {
+ return "", err
+ }
+ return "readme", nil
+ }); err != nil {
return err
}
fmt.Println("Installing Flux")
@@ -380,31 +395,20 @@
return nil
}
-func (b Bootstrapper) installInfrastructureServices(repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
- appRepo := NewInMemoryAppRepository(CreateAllApps())
+func (b Bootstrapper) installInfrastructureServices(repo RepoIO, env EnvConfig) error {
install := func(name string) error {
fmt.Printf("Installing infrastructure service %s\n", name)
- app, err := appRepo.Find(name)
+ app, err := b.appRepo.Find(name)
if err != nil {
return err
}
- nms, err := nsGen.Generate(app.Namespace())
- if err != nil {
- return err
- }
- if err := nsCreator.Create(nms); err != nil {
- return err
- }
+ namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
derived := Derived{
Global: Values{
PCloudEnvName: env.Name,
},
- Release: Release{},
- Values: make(map[string]any),
}
- derived.Release.Namespace = nms
- values := map[string]any{}
- return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), values, derived)
+ return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, nil, derived)
}
appsToInstall := []string{
"resource-renderer-controller",
@@ -422,28 +426,29 @@
}
func configureMainRepo(repo RepoIO, env EnvConfig) error {
- if err := repo.WriteYaml("config.yaml", env); err != nil {
- return err
- }
- if err := repo.WriteYaml("env-cidrs.yaml", EnvCIDRs{}); err != nil {
- return err
- }
- kust := NewKustomization()
- kust.AddResources(
- fmt.Sprintf("%s-flux", env.Name),
- "infrastructure",
- "environments",
- )
- if err := repo.WriteKustomization("kustomization.yaml", kust); err != nil {
- return err
- }
- {
- out, err := repo.Writer("infrastructure/pcloud-charts.yaml")
- if err != nil {
- return err
+ return repo.Atomic(func(r RepoFS) (string, error) {
+ if err := WriteYaml(r, "config.yaml", env); err != nil {
+ return "", err
}
- defer out.Close()
- _, err = out.Write([]byte(fmt.Sprintf(`
+ if err := WriteYaml(r, "env-cidrs.yaml", EnvCIDRs{}); err != nil {
+ return "", err
+ }
+ kust := NewKustomization()
+ kust.AddResources(
+ fmt.Sprintf("%s-flux", env.Name),
+ "infrastructure",
+ "environments",
+ )
+ if err := WriteYaml(r, "kustomization.yaml", kust); err != nil {
+ return "", err
+ }
+ {
+ out, err := r.Writer("infrastructure/pcloud-charts.yaml")
+ if err != nil {
+ return "", err
+ }
+ defer out.Close()
+ _, err = out.Write([]byte(fmt.Sprintf(`
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
@@ -455,25 +460,23 @@
ref:
branch: main
`, env.Name)))
- if err != nil {
- return err
+ if err != nil {
+ return "", err
+ }
}
- }
- infraKust := NewKustomization()
- infraKust.AddResources("pcloud-charts.yaml")
- if err := repo.WriteKustomization("infrastructure/kustomization.yaml", infraKust); err != nil {
- return err
- }
- if err := repo.WriteKustomization("environments/kustomization.yaml", NewKustomization()); err != nil {
- return err
- }
- if err := repo.CommitAndPush("initialize pcloud directory structure"); err != nil {
- return err
- }
- return nil
+ infraKust := NewKustomization()
+ infraKust.AddResources("pcloud-charts.yaml")
+ if err := WriteYaml(r, "infrastructure/kustomization.yaml", infraKust); err != nil {
+ return "", err
+ }
+ if err := WriteYaml(r, "environments/kustomization.yaml", NewKustomization()); err != nil {
+ return "", err
+ }
+ return "initialize pcloud directory structure", nil
+ })
}
-func (b Bootstrapper) installEnvManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
+func (b Bootstrapper) installEnvManager(repo RepoIO, ss *soft.Client, env EnvConfig) error {
keys, err := NewSSHKeyPair("env-manager")
if err != nil {
return err
@@ -485,18 +488,11 @@
if err := ss.MakeUserAdmin(user); err != nil {
return err
}
- appRepo := NewInMemoryAppRepository(CreateAllApps())
- app, err := appRepo.Find("env-manager")
+ app, err := b.appRepo.Find("env-manager")
if err != nil {
return err
}
- nms, err := nsGen.Generate(app.Namespace())
- if err != nil {
- return err
- }
- if err := nsCreator.Create(nms); err != nil {
- return err
- }
+ namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
derived := Derived{
Global: Values{
PCloudEnvName: env.Name,
@@ -508,100 +504,61 @@
"sshPrivateKey": string(keys.RawPrivateKey()),
},
}
- derived.Release.Namespace = nms
- return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived)
+ return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, derived.Values, derived)
}
-func (b Bootstrapper) installOryHydraMaester(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
- appRepo := NewInMemoryAppRepository(CreateAllApps())
- app, err := appRepo.Find("hydra-maester")
+func (b Bootstrapper) installOryHydraMaester(repo RepoIO, env EnvConfig) error {
+ app, err := b.appRepo.Find("hydra-maester")
if err != nil {
return err
}
- nms, err := nsGen.Generate(app.Namespace())
- if err != nil {
- return err
- }
- if err := nsCreator.Create(nms); err != nil {
- return err
- }
+ namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
derived := Derived{
Global: Values{
PCloudEnvName: env.Name,
},
- Values: map[string]any{},
}
- derived.Release.Namespace = nms
- return repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived)
+ return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, nil, derived)
}
-func (b Bootstrapper) installDNSZoneManager(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
+func (b Bootstrapper) installDNSZoneManager(repo RepoIO, env EnvConfig) error {
const (
volumeClaimName = "dns-zone-configs"
volumeMountPath = "/etc/pcloud/dns-zone-configs"
)
- ns, err := nsGen.Generate("dns-zone-manager")
+ app, err := b.appRepo.Find("dns-zone-manager")
if err != nil {
return err
}
- if err := nsCreator.Create(ns); err != nil {
- return err
- }
- appRepo := NewInMemoryAppRepository(CreateAllApps())
- {
- app, err := appRepo.Find("dns-zone-manager")
- if err != nil {
- return err
- }
- derived := Derived{
- Global: Values{
- PCloudEnvName: env.Name,
- },
- Values: map[string]any{
- "volume": map[string]any{
- "claimName": volumeClaimName,
- "mountPath": volumeMountPath,
- "size": "1Gi",
- },
- "apiConfigMapName": dnsAPIConfigMapName,
- },
- Release: Release{
- Namespace: ns,
- },
- }
- if err := repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (b Bootstrapper) installFluxcdReconciler(ss *soft.Client, repo RepoIO, nsGen NamespaceGenerator, nsCreator NamespaceCreator, env EnvConfig) error {
- appRepo := NewInMemoryAppRepository(CreateAllApps())
- app, err := appRepo.Find("fluxcd-reconciler")
- if err != nil {
- return err
- }
- ns, err := nsGen.Generate(app.Namespace())
- if err != nil {
- return err
- }
- if err := nsCreator.Create(ns); err != nil {
- return err
- }
+ namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
derived := Derived{
Global: Values{
PCloudEnvName: env.Name,
},
- Values: map[string]any{},
- Release: Release{
- Namespace: ns,
+ Values: map[string]any{
+ "volume": map[string]any{
+ "claimName": volumeClaimName,
+ "mountPath": volumeMountPath,
+ "size": "1Gi",
+ },
+ "apiConfigMapName": dnsAPIConfigMapName,
},
}
- if err := repo.InstallApp(app, filepath.Join("/infrastructure", app.Name()), derived.Values, derived); err != nil {
+ return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, derived.Values, derived)
+}
+
+func (b Bootstrapper) installFluxcdReconciler(repo RepoIO, ss *soft.Client, env EnvConfig) error {
+ app, err := b.appRepo.Find("fluxcd-reconciler")
+ if err != nil {
return err
}
- return nil
+ namespace := fmt.Sprintf("%s-%s", env.Name, app.Namespace())
+ derived := Derived{
+ Global: Values{
+ PCloudEnvName: env.Name,
+ },
+ }
+ return InstallApp(repo, b.ns, app, filepath.Join("/infrastructure", app.Name()), namespace, nil, derived)
}
type HelmActionConfigFactory interface {