@@ -20,6 +20,7 @@ import (
2020 "github.com/replicatedhq/embedded-cluster/pkg/goods"
2121 "github.com/replicatedhq/embedded-cluster/pkg/helpers"
2222 "github.com/replicatedhq/embedded-cluster/pkg/metrics"
23+ "github.com/replicatedhq/embedded-cluster/pkg/netutils"
2324 "github.com/replicatedhq/embedded-cluster/pkg/preflights"
2425 "github.com/replicatedhq/embedded-cluster/pkg/prompts"
2526 "github.com/replicatedhq/embedded-cluster/pkg/release"
@@ -36,18 +37,55 @@ var ErrNothingElseToAdd = fmt.Errorf("")
3637// installAndEnableLocalArtifactMirror installs and enables the local artifact mirror. This
3738// service is responsible for serving on localhost, through http, all files that are used
3839// during a cluster upgrade.
39- func installAndEnableLocalArtifactMirror () error {
40+ func installAndEnableLocalArtifactMirror (port int ) error {
4041 if err := goods .MaterializeLocalArtifactMirrorUnitFile (); err != nil {
4142 return fmt .Errorf ("failed to materialize artifact mirror unit: %w" , err )
4243 }
44+ if err := writeLocalArtifactMirrorEnvironmentFile (port ); err != nil {
45+ return fmt .Errorf ("failed to write local artifact mirror environment file: %w" , err )
46+ }
4347 if _ , err := helpers .RunCommand ("systemctl" , "daemon-reload" ); err != nil {
4448 return fmt .Errorf ("unable to get reload systemctl daemon: %w" , err )
4549 }
4650 if _ , err := helpers .RunCommand ("systemctl" , "start" , "local-artifact-mirror" ); err != nil {
4751 return fmt .Errorf ("unable to start the local artifact mirror: %w" , err )
4852 }
4953 if _ , err := helpers .RunCommand ("systemctl" , "enable" , "local-artifact-mirror" ); err != nil {
50- return fmt .Errorf ("unable to start the local artifact mirror: %w" , err )
54+ return fmt .Errorf ("unable to start the local artifact mirror service: %w" , err )
55+ }
56+ return nil
57+ }
58+
59+ // updateLocalArtifactMirrorService updates the port on which the local artifact mirror is served.
60+ func updateLocalArtifactMirrorService (port int ) error {
61+ if err := writeLocalArtifactMirrorEnvironmentFile (port ); err != nil {
62+ return fmt .Errorf ("failed to write local artifact mirror environment file: %w" , err )
63+ }
64+ if _ , err := helpers .RunCommand ("systemctl" , "daemon-reload" ); err != nil {
65+ return fmt .Errorf ("unable to get reload systemctl daemon: %w" , err )
66+ }
67+ if _ , err := helpers .RunCommand ("systemctl" , "restart" , "local-artifact-mirror" ); err != nil {
68+ return fmt .Errorf ("unable to restart the local artifact mirror service: %w" , err )
69+ }
70+ return nil
71+ }
72+
73+ const (
74+ localArtifactMirrorSystemdConfFile = "/etc/systemd/system/local-artifact-mirror.service.d/embedded-cluster.conf"
75+ localArtifactMirrorEnvironmentFileContents = `[Service]
76+ Environment="LOCAL_ARTIFACT_MIRROR_PORT=%d"`
77+ )
78+
79+ func writeLocalArtifactMirrorEnvironmentFile (port int ) error {
80+ dir := filepath .Dir (localArtifactMirrorSystemdConfFile )
81+ err := os .MkdirAll (dir , 0755 )
82+ if err != nil {
83+ return fmt .Errorf ("create directory: %w" , err )
84+ }
85+ contents := fmt .Sprintf (localArtifactMirrorEnvironmentFileContents , port )
86+ err = os .WriteFile (localArtifactMirrorSystemdConfFile , []byte (contents ), 0644 )
87+ if err != nil {
88+ return fmt .Errorf ("write file: %w" , err )
5189 }
5290 return nil
5391}
@@ -130,8 +168,12 @@ func runHostPreflights(c *cli.Context, hpf *v1beta2.HostPreflightSpec, proxy *ec
130168
131169 err = output .SaveToDisk ()
132170 if err != nil {
133- pb .CloseWithError ()
134- return fmt .Errorf ("failed to save preflights output: %w" , err )
171+ logrus .Warnf ("unable to save preflights output: %v" , err )
172+ }
173+
174+ err = preflights .CopyBundleToECSupportDir ()
175+ if err != nil {
176+ logrus .Warnf ("unable to copy preflight bundle to embedded-cluster support dir: %v" , err )
135177 }
136178
137179 // Failures found
@@ -327,12 +369,17 @@ func ensureK0sConfig(c *cli.Context, applier *addons.Applier) (*k0sconfig.Cluste
327369 return nil , fmt .Errorf ("unable to create directory: %w" , err )
328370 }
329371 cfg := config .RenderK0sConfig ()
372+ address , err := netutils .FirstValidAddress (c .String ("network-interface" ))
373+ if err != nil {
374+ return nil , fmt .Errorf ("unable to find first valid address: %w" , err )
375+ }
376+ cfg .Spec .API .Address = address
377+ cfg .Spec .Storage .Etcd .PeerAddress = address
330378 cfg .Spec .Network .PodCIDR = c .String ("pod-cidr" )
331379 cfg .Spec .Network .ServiceCIDR = c .String ("service-cidr" )
332380 if err := config .UpdateHelmConfigs (applier , cfg ); err != nil {
333381 return nil , fmt .Errorf ("unable to update helm configs: %w" , err )
334382 }
335- var err error
336383 cfg , err = applyUnsupportedOverrides (c , cfg )
337384 if err != nil {
338385 return nil , fmt .Errorf ("unable to apply unsupported overrides: %w" , err )
@@ -399,13 +446,17 @@ func applyUnsupportedOverrides(c *cli.Context, cfg *k0sconfig.ClusterConfig) (*k
399446
400447// installK0s runs the k0s install command and waits for it to finish. If no configuration
401448// is found one is generated.
402- func installK0s () error {
449+ func installK0s (c * cli. Context ) error {
403450 ourbin := defaults .PathToEmbeddedClusterBinary ("k0s" )
404451 hstbin := defaults .K0sBinaryPath ()
405452 if err := helpers .MoveFile (ourbin , hstbin ); err != nil {
406453 return fmt .Errorf ("unable to move k0s binary: %w" , err )
407454 }
408- if _ , err := helpers .RunCommand (hstbin , config .InstallFlags ()... ); err != nil {
455+ nodeIP , err := netutils .FirstValidAddress (c .String ("network-interface" ))
456+ if err != nil {
457+ return fmt .Errorf ("unable to find first valid address: %w" , err )
458+ }
459+ if _ , err := helpers .RunCommand (hstbin , config .InstallFlags (nodeIP )... ); err != nil {
409460 return fmt .Errorf ("unable to install: %w" , err )
410461 }
411462 if _ , err := helpers .RunCommand (hstbin , "start" ); err != nil {
@@ -437,7 +488,7 @@ func waitForK0s() error {
437488}
438489
439490// installAndWaitForK0s installs the k0s binary and waits for it to be ready
440- func installAndWaitForK0s (c * cli.Context , applier * addons.Applier ) (* k0sconfig.ClusterConfig , error ) {
491+ func installAndWaitForK0s (c * cli.Context , applier * addons.Applier , proxy * ecv1beta1. ProxySpec ) (* k0sconfig.ClusterConfig , error ) {
441492 loading := spinner .Start ()
442493 defer loading .Close ()
443494 loading .Infof ("Installing %s node" , defaults .BinaryName ())
@@ -448,16 +499,15 @@ func installAndWaitForK0s(c *cli.Context, applier *addons.Applier) (*k0sconfig.C
448499 metrics .ReportApplyFinished (c , err )
449500 return nil , err
450501 }
451- proxy := getProxySpecFromFlags (c )
452502 logrus .Debugf ("creating systemd unit files" )
453- if err := createSystemdUnitFiles (false , proxy ); err != nil {
503+ if err := createSystemdUnitFiles (false , proxy , applier . GetLocalArtifactMirrorPort () ); err != nil {
454504 err := fmt .Errorf ("unable to create systemd unit files: %w" , err )
455505 metrics .ReportApplyFinished (c , err )
456506 return nil , err
457507 }
458508
459509 logrus .Debugf ("installing k0s" )
460- if err := installK0s (); err != nil {
510+ if err := installK0s (c ); err != nil {
461511 err := fmt .Errorf ("unable update cluster: %w" , err )
462512 metrics .ReportApplyFinished (c , err )
463513 return nil , err
@@ -487,7 +537,7 @@ func runOutro(c *cli.Context, applier *addons.Applier, cfg *k0sconfig.ClusterCon
487537 return fmt .Errorf ("unable to process overrides file: %w" , err )
488538 }
489539
490- return applier .Outro (c .Context , cfg , eucfg , metadata )
540+ return applier .Outro (c .Context , cfg , eucfg , metadata , c . String ( "network-interface" ) )
491541}
492542
493543func maybeAskAdminConsolePassword (c * cli.Context ) (string , error ) {
@@ -554,6 +604,11 @@ var installCommand = &cli.Command{
554604 Usage : "Path to the license file" ,
555605 Hidden : false ,
556606 },
607+ & cli.StringFlag {
608+ Name : "network-interface" ,
609+ Usage : "The network interface to use for the cluster" ,
610+ Value : "" ,
611+ },
557612 & cli.BoolFlag {
558613 Name : "no-prompt" ,
559614 Usage : "Disable interactive prompts. The Admin Console password will be set to password." ,
@@ -573,10 +628,18 @@ var installCommand = &cli.Command{
573628 Name : "private-ca" ,
574629 Usage : "Path to a trusted private CA certificate file" ,
575630 },
631+ getAdminColsolePortFlag (),
632+ getLocalArtifactMirrorPortFlag (),
576633 },
577634 )),
578635 Action : func (c * cli.Context ) error {
636+ var err error
579637 proxy := getProxySpecFromFlags (c )
638+ proxy , err = includeLocalIPInNoProxy (c , proxy )
639+ if err != nil {
640+ metrics .ReportApplyFinished (c , err )
641+ return err
642+ }
580643 setProxyEnv (proxy )
581644
582645 logrus .Debugf ("checking if %s is already installed" , binName )
@@ -608,17 +671,22 @@ var installCommand = &cli.Command{
608671 return err // we want the user to see the error message without a prefix
609672 }
610673 }
674+ if err := preflights .ValidateApp (); err != nil {
675+ metrics .ReportApplyFinished (c , err )
676+ return err
677+ }
611678 adminConsolePwd , err := maybeAskAdminConsolePassword (c )
612679 if err != nil {
613680 metrics .ReportApplyFinished (c , err )
614681 return err
615682 }
683+
616684 logrus .Debugf ("materializing binaries" )
617685 if err := materializeFiles (c ); err != nil {
618686 metrics .ReportApplyFinished (c , err )
619687 return err
620688 }
621- applier , err := getAddonsApplier (c , adminConsolePwd )
689+ applier , err := getAddonsApplier (c , adminConsolePwd , proxy )
622690 if err != nil {
623691 metrics .ReportApplyFinished (c , err )
624692 return err
@@ -633,7 +701,7 @@ var installCommand = &cli.Command{
633701 metrics .ReportApplyFinished (c , err )
634702 return err
635703 }
636- cfg , err := installAndWaitForK0s (c , applier )
704+ cfg , err := installAndWaitForK0s (c , applier , proxy )
637705 if err != nil {
638706 return err
639707 }
@@ -647,7 +715,7 @@ var installCommand = &cli.Command{
647715 },
648716}
649717
650- func getAddonsApplier (c * cli.Context , adminConsolePwd string ) (* addons.Applier , error ) {
718+ func getAddonsApplier (c * cli.Context , adminConsolePwd string , proxy * ecv1beta1. ProxySpec ) (* addons.Applier , error ) {
651719 opts := []addons.Option {}
652720 if c .Bool ("no-prompt" ) {
653721 opts = append (opts , addons .WithoutPrompt ())
@@ -658,7 +726,6 @@ func getAddonsApplier(c *cli.Context, adminConsolePwd string) (*addons.Applier,
658726 if ab := c .String ("airgap-bundle" ); ab != "" {
659727 opts = append (opts , addons .WithAirgapBundle (ab ))
660728 }
661- proxy := getProxySpecFromFlags (c )
662729 if proxy != nil {
663730 opts = append (opts , addons .WithProxy (proxy .HTTPProxy , proxy .HTTPSProxy , proxy .NoProxy ))
664731 }
@@ -681,6 +748,19 @@ func getAddonsApplier(c *cli.Context, adminConsolePwd string) (*addons.Applier,
681748 }
682749 opts = append (opts , addons .WithPrivateCAs (privateCAs ))
683750 }
751+
752+ adminConsolePort , err := getAdminConsolePortFromFlag (c )
753+ if err != nil {
754+ return nil , err
755+ }
756+ opts = append (opts , addons .WithAdminConsolePort (adminConsolePort ))
757+
758+ localArtifactMirrorPort , err := getLocalArtifactMirrorPortFromFlag (c )
759+ if err != nil {
760+ return nil , err
761+ }
762+ opts = append (opts , addons .WithLocalArtifactMirrorPort (localArtifactMirrorPort ))
763+
684764 if adminConsolePwd != "" {
685765 opts = append (opts , addons .WithAdminConsolePassword (adminConsolePwd ))
686766 }
0 commit comments