@@ -54,34 +54,33 @@ var vmDefs = []VMDef{
5454}
5555
5656type GCPBootstrapper struct {
57- ctx context.Context
58- stlog * bootstrap.StepLogger
59- fw util.FileIO
60- icg installer.InstallConfigManager
61- NodeManager node.NodeManager
62- GCPClient GCPClientManager
57+ ctx context.Context
58+ stlog * bootstrap.StepLogger
59+ fw util.FileIO
60+ icg installer.InstallConfigManager
61+ GCPClient GCPClientManager
6362 // Environment
6463 Env * CodesphereEnvironment
65- // SSH options
66- sshQuiet bool
64+ // SSH command runner
65+ CommandRunner node. NodeClient
6766}
6867
6968type CodesphereEnvironment struct {
70- ProjectID string `json:"project_id"`
71- ProjectName string `json:"project_name"`
72- DNSProjectID string `json:"dns_project_id"`
73- Jumpbox node.NodeManager `json:"jumpbox"`
74- PostgreSQLNode node.NodeManager `json:"postgresql_node "`
75- ControlPlaneNodes []node.NodeManager `json:"control_plane_nodes"`
76- CephNodes []node.NodeManager `json:"ceph_nodes"`
77- ContainerRegistryURL string `json:"-"`
78- ExistingConfigUsed bool `json:"-"`
79- InstallCodesphereVersion string `json:"install_codesphere_version"`
80- Preemptible bool `json:"preemptible"`
81- WriteConfig bool `json:"-"`
82- GatewayIP string `json:"gateway_ip"`
83- PublicGatewayIP string `json:"public_gateway_ip"`
84- RegistryType RegistryType `json:"registry_type"`
69+ ProjectID string `json:"project_id"`
70+ ProjectName string `json:"project_name"`
71+ DNSProjectID string `json:"dns_project_id"`
72+ Jumpbox * node.Node `json:"jumpbox"`
73+ PostgreSQLNode * node.Node `json:"postgres_node "`
74+ ControlPlaneNodes []* node.Node `json:"control_plane_nodes"`
75+ CephNodes []* node.Node `json:"ceph_nodes"`
76+ ContainerRegistryURL string `json:"-"`
77+ ExistingConfigUsed bool `json:"-"`
78+ InstallCodesphereVersion string `json:"install_codesphere_version"`
79+ Preemptible bool `json:"preemptible"`
80+ WriteConfig bool `json:"-"`
81+ GatewayIP string `json:"gateway_ip"`
82+ PublicGatewayIP string `json:"public_gateway_ip"`
83+ RegistryType RegistryType `json:"registry_type"`
8584
8685 // Config
8786 InstallConfigPath string `json:"-"`
@@ -106,19 +105,31 @@ type CodesphereEnvironment struct {
106105 DNSZoneName string `json:"dns_zone_name"`
107106}
108107
109- func NewGCPBootstrapper (ctx context.Context , env env.Env , stlog * bootstrap.StepLogger , CodesphereEnv * CodesphereEnvironment , icg installer.InstallConfigManager , gcpClient GCPClientManager , nm node.NodeManager , fw util.FileIO ) (* GCPBootstrapper , error ) {
108+ func NewGCPBootstrapper (
109+ ctx context.Context ,
110+ env env.Env ,
111+ stlog * bootstrap.StepLogger ,
112+ CodesphereEnv * CodesphereEnvironment ,
113+ icg installer.InstallConfigManager ,
114+ gcpClient GCPClientManager ,
115+ fw util.FileIO ,
116+ sshRunner node.NodeClient ) (* GCPBootstrapper , error ) {
110117 return & GCPBootstrapper {
111- ctx : ctx ,
112- stlog : stlog ,
113- fw : fw ,
114- icg : icg ,
115- GCPClient : gcpClient ,
116- NodeManager : nm ,
117- Env : CodesphereEnv ,
118- sshQuiet : true ,
118+ ctx : ctx ,
119+ stlog : stlog ,
120+ fw : fw ,
121+ icg : icg ,
122+ GCPClient : gcpClient ,
123+ Env : CodesphereEnv ,
124+ CommandRunner : sshRunner ,
119125 }, nil
120126}
121127
128+ func GetInfraFilePath () string {
129+ workdir := env .NewEnv ().GetOmsWorkdir ()
130+ return fmt .Sprintf ("%s/gcp-infra.json" , workdir )
131+ }
132+
122133func (b * GCPBootstrapper ) Bootstrap () error {
123134 err := b .stlog .Step ("Ensure install config" , b .EnsureInstallConfig )
124135 if err != nil {
@@ -659,18 +670,20 @@ func (b *GCPBootstrapper) EnsureComputeInstances() error {
659670 }
660671
661672 // Create nodes from results (in main goroutine, not in spawned goroutines)
673+ b .Env .Jumpbox = & node.Node {
674+ NodeClient : b .CommandRunner ,
675+ }
662676 for result := range resultCh {
663677 switch result .vmType {
664678 case "jumpbox" :
665- b .NodeManager .UpdateNode (result .name , result .externalIP , result .internalIP )
666- b .Env .Jumpbox = b .NodeManager
679+ b .Env .Jumpbox .UpdateNode (result .name , result .externalIP , result .internalIP )
667680 case "postgres" :
668- b .Env .PostgreSQLNode = b .NodeManager .CreateSubNode (result .name , result .externalIP , result .internalIP )
681+ b .Env .PostgreSQLNode = b .Env . Jumpbox .CreateSubNode (result .name , result .externalIP , result .internalIP )
669682 case "ceph" :
670- node := b .NodeManager .CreateSubNode (result .name , result .externalIP , result .internalIP )
683+ node := b .Env . Jumpbox .CreateSubNode (result .name , result .externalIP , result .internalIP )
671684 b .Env .CephNodes = append (b .Env .CephNodes , node )
672685 case "k0s" :
673- node := b .NodeManager .CreateSubNode (result .name , result .externalIP , result .internalIP )
686+ node := b .Env . Jumpbox .CreateSubNode (result .name , result .externalIP , result .internalIP )
674687 b .Env .ControlPlaneNodes = append (b .Env .ControlPlaneNodes , node )
675688 }
676689 }
@@ -734,7 +747,7 @@ func (b *GCPBootstrapper) EnsureExternalIP(name string) (string, error) {
734747}
735748
736749func (b * GCPBootstrapper ) EnsureRootLoginEnabled () error {
737- allNodes := []node.NodeManager {
750+ allNodes := []* node.Node {
738751 b .Env .Jumpbox ,
739752 }
740753 allNodes = append (allNodes , b .Env .ControlPlaneNodes ... )
@@ -753,8 +766,8 @@ func (b *GCPBootstrapper) EnsureRootLoginEnabled() error {
753766 return nil
754767}
755768
756- func (b * GCPBootstrapper ) ensureRootLoginEnabledInNode (node node.NodeManager ) error {
757- err := node .WaitForSSH ( 30 * time .Second )
769+ func (b * GCPBootstrapper ) ensureRootLoginEnabledInNode (node * node.Node ) error {
770+ err := node .NodeClient . WaitReady ( node , 30 * time .Second )
758771 if err != nil {
759772 return fmt .Errorf ("timed out waiting for SSH service to start on %s: %w" , node .GetName (), err )
760773 }
@@ -829,7 +842,7 @@ func (b *GCPBootstrapper) EnsureLocalContainerRegistry() error {
829842 // Figure out if registry is already running
830843 b .stlog .Logf ("Checking if local container registry is already running on postgres node" )
831844 checkCommand := `test "$(podman ps --filter 'name=registry' --format '{{.Names}}' | wc -l)" -eq "1"`
832- err := b .Env .PostgreSQLNode .RunSSHCommand ("root" , checkCommand , b . sshQuiet )
845+ err := b .Env .PostgreSQLNode .RunSSHCommand ("root" , checkCommand )
833846 if err == nil && b .Env .InstallConfig .Registry != nil && b .Env .InstallConfig .Registry .Server == localRegistryServer &&
834847 b .Env .InstallConfig .Registry .Username != "" && b .Env .InstallConfig .Registry .Password != "" {
835848 b .stlog .Logf ("Local container registry already running on postgres node" )
@@ -863,7 +876,7 @@ func (b *GCPBootstrapper) EnsureLocalContainerRegistry() error {
863876 }
864877 for _ , cmd := range commands {
865878 b .stlog .Logf ("Running command on postgres node: %s" , util .Truncate (cmd , 12 ))
866- err := b .Env .PostgreSQLNode .RunSSHCommand ("root" , cmd , b . sshQuiet )
879+ err := b .Env .PostgreSQLNode .RunSSHCommand ("root" , cmd )
867880 if err != nil {
868881 return fmt .Errorf ("failed to run command on postgres node: %w" , err )
869882 }
@@ -872,15 +885,15 @@ func (b *GCPBootstrapper) EnsureLocalContainerRegistry() error {
872885 allNodes := append (b .Env .ControlPlaneNodes , b .Env .CephNodes ... )
873886 for _ , node := range allNodes {
874887 b .stlog .Logf ("Configuring node '%s' to trust local registry certificate" , node .GetName ())
875- err := b .Env .PostgreSQLNode .RunSSHCommand ("root" , "scp -o StrictHostKeyChecking=no /root/registry.crt root@" + node .GetInternalIP ()+ ":/usr/local/share/ca-certificates/registry.crt" , b . sshQuiet )
888+ err := b .Env .PostgreSQLNode .RunSSHCommand ("root" , "scp -o StrictHostKeyChecking=no /root/registry.crt root@" + node .GetInternalIP ()+ ":/usr/local/share/ca-certificates/registry.crt" )
876889 if err != nil {
877890 return fmt .Errorf ("failed to copy registry certificate to node %s: %w" , node .GetInternalIP (), err )
878891 }
879- err = node .RunSSHCommand ("root" , "update-ca-certificates" , b . sshQuiet )
892+ err = node .RunSSHCommand ("root" , "update-ca-certificates" )
880893 if err != nil {
881894 return fmt .Errorf ("failed to update CA certificates on node %s: %w" , node .GetInternalIP (), err )
882895 }
883- err = node .RunSSHCommand ("root" , "systemctl restart docker.service || true" , true ) // docker is probably not yet installed
896+ err = node .RunSSHCommand ("root" , "systemctl restart docker.service || true" ) // docker is probably not yet installed
884897 if err != nil {
885898 return fmt .Errorf ("failed to restart docker service on node %s: %w" , node .GetInternalIP (), err )
886899 }
@@ -1128,25 +1141,25 @@ func (b *GCPBootstrapper) UpdateInstallConfig() error {
11281141 return fmt .Errorf ("failed to write vault file: %w" , err )
11291142 }
11301143
1131- err := b .Env .Jumpbox .CopyFile (b .Env .InstallConfigPath , "/etc/codesphere/config.yaml" )
1144+ err := b .Env .Jumpbox .NodeClient . CopyFile (b . Env . Jumpbox , b .Env .InstallConfigPath , "/etc/codesphere/config.yaml" )
11321145 if err != nil {
11331146 return fmt .Errorf ("failed to copy install config to jumpbox: %w" , err )
11341147 }
11351148
1136- err = b .Env .Jumpbox .CopyFile (b .Env .SecretsFilePath , b .Env .SecretsDir + "/prod.vault.yaml" )
1149+ err = b .Env .Jumpbox .NodeClient . CopyFile (b . Env . Jumpbox , b .Env .SecretsFilePath , b .Env .SecretsDir + "/prod.vault.yaml" )
11371150 if err != nil {
11381151 return fmt .Errorf ("failed to copy secrets file to jumpbox: %w" , err )
11391152 }
11401153 return nil
11411154}
11421155
11431156func (b * GCPBootstrapper ) EnsureAgeKey () error {
1144- hasKey := b .Env .Jumpbox .HasFile (b .Env .SecretsDir + "/age_key.txt" )
1157+ hasKey := b .Env .Jumpbox .NodeClient . HasFile (b .Env .Jumpbox , b . Env . SecretsDir + "/age_key.txt" )
11451158 if hasKey {
11461159 return nil
11471160 }
11481161
1149- err := b .Env .Jumpbox .RunSSHCommand ("root" , fmt .Sprintf ("mkdir -p %s; age-keygen -o %s/age_key.txt" , b .Env .SecretsDir , b .Env .SecretsDir ), b . sshQuiet )
1162+ err := b .Env .Jumpbox .RunSSHCommand ("root" , fmt .Sprintf ("mkdir -p %s; age-keygen -o %s/age_key.txt" , b .Env .SecretsDir , b .Env .SecretsDir ))
11501163 if err != nil {
11511164 return fmt .Errorf ("failed to generate age key on jumpbox: %w" , err )
11521165 }
@@ -1155,12 +1168,12 @@ func (b *GCPBootstrapper) EnsureAgeKey() error {
11551168}
11561169
11571170func (b * GCPBootstrapper ) EncryptVault () error {
1158- err := b .Env .Jumpbox .RunSSHCommand ("root" , "cp " + b .Env .SecretsDir + "/prod.vault.yaml{,.bak}" , b . sshQuiet )
1171+ err := b .Env .Jumpbox .RunSSHCommand ("root" , "cp " + b .Env .SecretsDir + "/prod.vault.yaml{,.bak}" )
11591172 if err != nil {
11601173 return fmt .Errorf ("failed backup vault on jumpbox: %w" , err )
11611174 }
11621175
1163- err = b .Env .Jumpbox .RunSSHCommand ("root" , "sops --encrypt --in-place --age $(age-keygen -y " + b .Env .SecretsDir + "/age_key.txt) " + b .Env .SecretsDir + "/prod.vault.yaml" , b . sshQuiet )
1176+ err = b .Env .Jumpbox .RunSSHCommand ("root" , "sops --encrypt --in-place --age $(age-keygen -y " + b .Env .SecretsDir + "/age_key.txt) " + b .Env .SecretsDir + "/prod.vault.yaml" )
11641177 if err != nil {
11651178 return fmt .Errorf ("failed to encrypt vault on jumpbox: %w" , err )
11661179 }
@@ -1216,12 +1229,12 @@ func (b *GCPBootstrapper) EnsureDNSRecords() error {
12161229}
12171230
12181231func (b * GCPBootstrapper ) InstallCodesphere () error {
1219- err := b .Env .Jumpbox .RunSSHCommand ("root" , "oms-cli download package " + b .Env .InstallCodesphereVersion , b . sshQuiet )
1232+ err := b .Env .Jumpbox .RunSSHCommand ("root" , "oms-cli download package " + b .Env .InstallCodesphereVersion )
12201233 if err != nil {
12211234 return fmt .Errorf ("failed to download Codesphere package from jumpbox: %w" , err )
12221235 }
12231236
1224- err = b .Env .Jumpbox .RunSSHCommand ("root" , "oms-cli install codesphere -c /etc/codesphere/config.yaml -k " + b .Env .SecretsDir + "/age_key.txt -p " + b .Env .InstallCodesphereVersion + ".tar.gz" , b . sshQuiet )
1237+ err = b .Env .Jumpbox .RunSSHCommand ("root" , "oms-cli install codesphere -c /etc/codesphere/config.yaml -k " + b .Env .SecretsDir + "/age_key.txt -p " + b .Env .InstallCodesphereVersion + ".tar.gz" )
12251238 if err != nil {
12261239 return fmt .Errorf ("failed to install Codesphere from jumpbox: %w" , err )
12271240 }
@@ -1317,11 +1330,11 @@ systemctl restart k0scontroller
13171330 if err != nil {
13181331 return fmt .Errorf ("failed to write configure-k0s.sh: %w" , err )
13191332 }
1320- err = b .Env .ControlPlaneNodes [0 ].CopyFile ("configure-k0s.sh" , "/root/configure-k0s.sh" )
1333+ err = b .Env .ControlPlaneNodes [0 ].NodeClient . CopyFile (b . Env . ControlPlaneNodes [ 0 ], "configure-k0s.sh" , "/root/configure-k0s.sh" )
13211334 if err != nil {
13221335 return fmt .Errorf ("failed to copy configure-k0s.sh to control plane node: %w" , err )
13231336 }
1324- err = b .Env .ControlPlaneNodes [0 ].RunSSHCommand ("root" , "chmod +x /root/configure-k0s.sh" , b . sshQuiet )
1337+ err = b .Env .ControlPlaneNodes [0 ].RunSSHCommand ("root" , "chmod +x /root/configure-k0s.sh" )
13251338 if err != nil {
13261339 return fmt .Errorf ("failed to make configure-k0s.sh executable on control plane node: %w" , err )
13271340 }
0 commit comments