Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into laverya/sc-115699/rep…
Browse files Browse the repository at this point in the history
…ort-skipped-preflight-failures
  • Loading branch information
laverya committed Dec 4, 2024
2 parents e3130c7 + 8784242 commit 21e3e42
Show file tree
Hide file tree
Showing 36 changed files with 1,440 additions and 134 deletions.
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ ifneq ($(DISABLE_FIO_BUILD),1)
cp output/bins/fio-$(FIO_VERSION)-$(ARCH) $@
endif

.PHONY: pkg/goods/bins/manager
pkg/goods/bins/manager:
mkdir -p pkg/goods/bins
CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o output/bins/manager ./cmd/manager
cp output/bins/manager $@
touch $@

.PHONY: pkg/goods/internal/bins/kubectl-kots
pkg/goods/internal/bins/kubectl-kots:
mkdir -p pkg/goods/internal/bins
Expand Down Expand Up @@ -210,6 +217,7 @@ static: pkg/goods/bins/k0s \
pkg/goods/bins/kubectl-support_bundle \
pkg/goods/bins/local-artifact-mirror \
pkg/goods/bins/fio \
pkg/goods/bins/manager \
pkg/goods/internal/bins/kubectl-kots

.PHONY: static-dryrun
Expand All @@ -220,6 +228,7 @@ static-dryrun:
pkg/goods/bins/kubectl-support_bundle \
pkg/goods/bins/local-artifact-mirror \
pkg/goods/bins/fio \
pkg/goods/bins/manager \
pkg/goods/internal/bins/kubectl-kots

.PHONY: embedded-cluster-linux-amd64
Expand Down Expand Up @@ -370,10 +379,11 @@ bin/installer:
bin/manager:
go build -o bin/manager ./cmd/manager

# make test-embed channel=Unstable app=slackernews
# make test-embed channel=<channelid> app=<appslug>
.PHONY: test-embed
test-emded: export OS=linux
test-embed: export ARCH=amd64
test-embed: VERSION=1.19.0+k8s-1.30
test-embed: static embedded-cluster
@echo "Cleaning up previous release directory..."
rm -rf ./hack/release
Expand Down
38 changes: 27 additions & 11 deletions cmd/installer/cli/cidr.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,37 @@ func addCIDRFlags(cmd *cobra.Command) {
cmd.Flags().String("cidr", ecv1beta1.DefaultNetworkCIDR, "CIDR block of available private IP addresses (/16 or larger)")
}

// DeterminePodAndServiceCIDRS determines, based on the command line flags,
// what are the pod and service CIDRs to be used for the cluster. If both
// --pod-cidr and --service-cidr have been set, they are used. Otherwise,
// the cidr flag is split into pod and service CIDRs.
func determinePodAndServiceCIDRs(cmd *cobra.Command) (string, string, error) {
podCIDRFlag, err := cmd.Flags().GetString("pod-cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get pod-cidr flag: %w", err)
func validateCIDRFlags(cmd *cobra.Command) error {
if cmd.Flags().Changed("cidr") && (cmd.Flags().Changed("pod-cidr") || cmd.Flags().Changed("service-cidr")) {
return fmt.Errorf("--cidr flag can't be used with --pod-cidr or --service-cidr")
}
serviceCIDRFlag, err := cmd.Flags().GetString("service-cidr")

cidr, err := cmd.Flags().GetString("cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get service-cidr flag: %w", err)
return fmt.Errorf("unable to get cidr flag: %w", err)
}

if err := netutils.ValidateCIDR(cidr, 16, true); err != nil {
return fmt.Errorf("invalid cidr %q: %w", cidr, err)
}

if podCIDRFlag != "" || serviceCIDRFlag != "" {
return nil
}

// getPODAndServiceCIDR determines, based on the command line flags,
// what are the pod and service CIDRs to be used for the cluster. If both
// --pod-cidr and --service-cidr have been set, they are used. Otherwise,
// the cidr flag is split into pod and service CIDRs.
func getPODAndServiceCIDR(cmd *cobra.Command) (string, string, error) {
if cmd.Flags().Changed("pod-cidr") || cmd.Flags().Changed("service-cidr") {
podCIDRFlag, err := cmd.Flags().GetString("pod-cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get pod-cidr flag: %w", err)
}
serviceCIDRFlag, err := cmd.Flags().GetString("service-cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get service-cidr flag: %w", err)
}
return podCIDRFlag, serviceCIDRFlag, nil
}

Expand Down
144 changes: 80 additions & 64 deletions cmd/installer/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,45 +65,31 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
if os.Getuid() != 0 {
return fmt.Errorf("install command must be run as root")
}

if skipHostPreflights {
logrus.Warnf("Warning: --skip-host-preflights is deprecated and will be removed in a later version. Use --ignore-host-preflights instead.")
}

// TODO move this to pass params, not flags. flags don't leave the cmd/ package
runtimeconfig.ApplyFlags(cmd.Flags())
os.Setenv("TMPDIR", runtimeconfig.EmbeddedClusterTmpSubDir())

if err := runtimeconfig.WriteToDisk(); err != nil {
return fmt.Errorf("unable to write runtime config to disk: %w", err)
}

var err error
proxy, err = getProxySpecFromFlags(cmd)
p, err := parseProxyFlags(cmd)
if err != nil {
return fmt.Errorf("unable to get proxy spec from flags: %w", err)
return fmt.Errorf("unable to parse proxy flags: %w", err)
}
proxy = p

proxy, err = includeLocalIPInNoProxy(cmd, proxy)
if err != nil {
licenseFlag, err := cmd.Flags().GetString("license")
if err != nil {
return fmt.Errorf("unable to get license flag: %w", err)
}
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, err)
return err
if err := validateCIDRFlags(cmd); err != nil {
return fmt.Errorf("unable to parse cidr flags: %w", err)
}
setProxyEnv(proxy)

if cmd.Flags().Changed("cidr") && (cmd.Flags().Changed("pod-cidr") || cmd.Flags().Changed("service-cidr")) {
return fmt.Errorf("--cidr flag can't be used with --pod-cidr or --service-cidr")
}

cidr, err := cmd.Flags().GetString("cidr")
if err != nil {
return fmt.Errorf("unable to get cidr flag: %w", err)
}

if err := netutils.ValidateCIDR(cidr, 16, true); err != nil {
return fmt.Errorf("invalid cidr %q: %w", cidr, err)
if os.Getenv("DISABLE_TELEMETRY") != "" {
metrics.DisableMetrics()
}

return nil
Expand All @@ -113,12 +99,16 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
},
RunE: func(cmd *cobra.Command, args []string) error {
logrus.Debugf("checking if %s is already installed", name)
installed, err := k0s.IsInstalled(name)
installed, err := k0s.IsInstalled()
if err != nil {
return err
}
if installed {
return ErrNothingElseToAdd
logrus.Errorf("An installation has been detected on this machine.")
logrus.Infof("If you want to reinstall, you need to remove the existing installation first.")
logrus.Infof("You can do this by running the following command:")
logrus.Infof("\n sudo ./%s reset\n", name)
os.Exit(1)
}

channelRelease, err := release.GetChannelRelease()
Expand Down Expand Up @@ -150,7 +140,7 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
license, err := getLicenseFromFilepath(licenseFile)
if err != nil {
metricErr := fmt.Errorf("unable to get license: %w", err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, metricErr)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, metricErr)
return err // do not return the metricErr, as we want the user to see the error message without a prefix
}
isAirgap := false
Expand All @@ -167,7 +157,7 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
if !isAirgap {
if err := maybePromptForAppUpdate(cmd.Context(), prompts.New(), license, assumeYes); err != nil {
if errors.Is(err, ErrNothingElseToAdd) {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
return err
}
// If we get an error other than ErrNothingElseToAdd, we warn and continue as
Expand All @@ -177,19 +167,19 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
}

if err := preflights.ValidateApp(); err != nil {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
return err
}

adminConsolePwd, err := maybeAskAdminConsolePassword(cmd, assumeYes)
if err != nil {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
return err
}

logrus.Debugf("materializing binaries")
if err := materializeFiles(airgapBundle); err != nil {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
return err
}

Expand All @@ -203,7 +193,7 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
}
applier, err := getAddonsApplier(cmd, opts, adminConsolePwd, proxy)
if err != nil {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
return err
}

Expand All @@ -214,13 +204,13 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
proxyRegistryURL = fmt.Sprintf("https://%s", runtimeconfig.ProxyRegistryAddress)
}

fromCIDR, toCIDR, err := DeterminePodAndServiceCIDRs(cmd)
fromCIDR, toCIDR, err := getPODAndServiceCIDR(cmd)
if err != nil {
return fmt.Errorf("unable to determine pod and service CIDRs: %w", err)
}

if err := RunHostPreflights(cmd, applier, replicatedAPIURL, proxyRegistryURL, isAirgap, proxy, fromCIDR, toCIDR, assumeYes); err != nil {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
if err == ErrPreflightsHaveFail {
return ErrNothingElseToAdd
}
Expand All @@ -231,12 +221,14 @@ func InstallCmd(ctx context.Context, name string) *cobra.Command {
if err != nil {
return err
}

logrus.Debugf("running outro")
if err := runOutro(cmd, applier, cfg); err != nil {
metrics.ReportApplyFinished(cmd.Context(), licenseFile, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, err)
return err
}
metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil)

metrics.ReportApplyFinished(cmd.Context(), licenseFile, nil, nil)
return nil
},
}
Expand Down Expand Up @@ -453,13 +445,13 @@ func installAndWaitForK0s(cmd *cobra.Command, applier *addons.Applier, proxy *ec
cfg, err := ensureK0sConfig(cmd, applier)
if err != nil {
err := fmt.Errorf("unable to create config file: %w", err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, nil, err)
return nil, err
}
logrus.Debugf("creating systemd unit files")
if err := createSystemdUnitFiles(false, proxy); err != nil {
err := fmt.Errorf("unable to create systemd unit files: %w", err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, nil, err)
return nil, err
}

Expand All @@ -470,14 +462,14 @@ func installAndWaitForK0s(cmd *cobra.Command, applier *addons.Applier, proxy *ec
}
if err := k0s.Install(networkInterface); err != nil {
err := fmt.Errorf("unable to install cluster: %w", err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, nil, err)
return nil, err
}
loading.Infof("Waiting for %s node to be ready", runtimeconfig.BinaryName())
logrus.Debugf("waiting for k0s to be ready")
if err := waitForK0s(); err != nil {
err := fmt.Errorf("unable to wait for node: %w", err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, err)
metrics.ReportApplyFinished(cmd.Context(), licenseFlag, nil, err)
return nil, err
}

Expand Down Expand Up @@ -651,7 +643,7 @@ func ensureK0sConfig(cmd *cobra.Command, applier *addons.Applier) (*k0sconfig.Cl
cfg.Spec.API.Address = address
cfg.Spec.Storage.Etcd.PeerAddress = address

podCIDR, serviceCIDR, err := DeterminePodAndServiceCIDRs(cmd)
podCIDR, serviceCIDR, err := getPODAndServiceCIDR(cmd)
if err != nil {
return nil, fmt.Errorf("unable to determine pod and service CIDRs: %w", err)
}
Expand Down Expand Up @@ -733,30 +725,6 @@ func applyUnsupportedOverrides(cmd *cobra.Command, cfg *k0sconfig.ClusterConfig)
return cfg, nil
}

// DeterminePodAndServiceCIDRS determines, based on the command line flags,
// what are the pod and service CIDRs to be used for the cluster. If both
// --pod-cidr and --service-cidr have been set, they are used. Otherwise,
// the cidr flag is split into pod and service CIDRs.
func DeterminePodAndServiceCIDRs(cmd *cobra.Command) (string, string, error) {
if cmd.Flags().Changed("pod-cidr") || cmd.Flags().Changed("service-cidr") {
podCIDRFlag, err := cmd.Flags().GetString("pod-cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get pod-cidr flag: %w", err)
}
serviceCIDRFlag, err := cmd.Flags().GetString("service-cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get service-cidr flag: %w", err)
}
return podCIDRFlag, serviceCIDRFlag, nil
}

cidrFlag, err := cmd.Flags().GetString("cidr")
if err != nil {
return "", "", fmt.Errorf("unable to get cidr flag: %w", err)
}
return netutils.SplitNetworkCIDR(cidrFlag)
}

// createSystemdUnitFiles links the k0s systemd unit file. this also creates a new
// systemd unit file for the local artifact mirror service.
func createSystemdUnitFiles(isWorker bool, proxy *ecv1beta1.ProxySpec) error {
Expand Down Expand Up @@ -838,6 +806,28 @@ func installAndEnableLocalArtifactMirror() error {
return nil
}

// installAndEnableManager installs and enables the manager. This service is
// responsible for managing the embedded cluster after the initial installation.
func installAndEnableManager() error {
materializer := goods.NewMaterializer()
if err := materializer.ManagerUnitFile(); err != nil {
return fmt.Errorf("unable to materialize manager unit: %w", err)
}
if err := writeManagerDropInFile(); err != nil {
return fmt.Errorf("unable to write manager environment file: %w", err)
}
if _, err := helpers.RunCommand("systemctl", "daemon-reload"); err != nil {
return fmt.Errorf("unable to get reload systemctl daemon: %w", err)
}
if _, err := helpers.RunCommand("systemctl", "start", runtimeconfig.ManagerServiceName); err != nil {
return fmt.Errorf("unable to start the manager: %w", err)
}
if _, err := helpers.RunCommand("systemctl", "enable", runtimeconfig.ManagerServiceName); err != nil {
return fmt.Errorf("unable to start the manager service: %w", err)
}
return nil
}

const (
localArtifactMirrorSystemdConfFile = "/etc/systemd/system/local-artifact-mirror.service.d/embedded-cluster.conf"
localArtifactMirrorDropInFileContents = `[Service]
Expand All @@ -849,6 +839,15 @@ ExecStart=%s serve
`
)

var (
managerSystemdConfFile = fmt.Sprintf("/etc/systemd/system/%s.service.d/embedded-cluster.conf", runtimeconfig.ManagerServiceName)
managerDropInFileContents = `[Service]
# Empty ExecStart= will clear out the previous ExecStart value
ExecStart=
ExecStart=%s start
`
)

func writeLocalArtifactMirrorDropInFile() error {
dir := filepath.Dir(localArtifactMirrorSystemdConfFile)
err := os.MkdirAll(dir, 0755)
Expand All @@ -868,6 +867,23 @@ func writeLocalArtifactMirrorDropInFile() error {
return nil
}

func writeManagerDropInFile() error {
dir := filepath.Dir(managerSystemdConfFile)
err := os.MkdirAll(dir, 0755)
if err != nil {
return fmt.Errorf("create directory: %w", err)
}
contents := fmt.Sprintf(
managerDropInFileContents,
runtimeconfig.PathToEmbeddedClusterBinary("manager"),
)
err = os.WriteFile(managerSystemdConfFile, []byte(contents), 0644)
if err != nil {
return fmt.Errorf("write file: %w", err)
}
return nil
}

// waitForK0s waits for the k0s API to be available. We wait for the k0s socket to
// appear in the system and until the k0s status command to finish.
func waitForK0s() error {
Expand Down
Loading

0 comments on commit 21e3e42

Please sign in to comment.