Skip to content

Commit

Permalink
K8sInstallerConfig controller implementation added (#526)
Browse files Browse the repository at this point in the history
K8sInstallerConfig controller will be generation the installation secret
for the bundleType to install on byohost

test cases added

To increase the test coverage, few test cases added for
k8sinstallercontroller
- should not return reconcile request if ByoMachine InstallerRef doesn't exists
- should not return reconcile request if ByoMachine InstallerRef doesn't refer to K8sInstallerConfitTemplate
- should return reconcile request if ByoMachine refer to K8sInstallerConfigTemplate installer

Signed-off-by: Mayur Das <[email protected]>
  • Loading branch information
mayur-tolexo committed May 13, 2022
1 parent c917aec commit 779caac
Show file tree
Hide file tree
Showing 16 changed files with 1,243 additions and 99 deletions.
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ RUN go mod download
COPY main.go main.go
COPY apis/ apis/
COPY controllers/ controllers/
COPY common/installer common/installer
COPY agent/installer agent/installer

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go
Expand Down
1 change: 1 addition & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ resources:
- api:
crdVersion: v1
namespaced: true
controller: true
domain: cluster.x-k8s.io
group: infrastructure
kind: K8sInstallerConfig
Expand Down
18 changes: 14 additions & 4 deletions agent/installer/bundle_downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@ var (

// bundleDownloader for downloading an OCI image.
type bundleDownloader struct {
bundleType bundleType
bundleType BundleType
repoAddr string
downloadPath string
logger logr.Logger
}

// NewBundleDownloader will return a new bundle downloader instance
func NewBundleDownloader(bundleType BundleType, repoAddr, downloadPath string, logger logr.Logger) *bundleDownloader {
return &bundleDownloader{
bundleType: bundleType,
repoAddr: repoAddr,
downloadPath: downloadPath,
logger: logger,
}
}

// Download is a method that downloads the bundle from repoAddr to downloadPath.
// It automatically downloads and extracts the given version for the current linux
// distribution. Creates the folder where the bundle should be saved if it does not exist.
Expand Down Expand Up @@ -87,7 +97,7 @@ func (bd *bundleDownloader) DownloadFromRepo(
if err != nil {
return err
}
bundleAddr := bd.getBundleAddr(normalizedOsVersion, k8sVersion, tag)
bundleAddr := bd.GetBundleAddr(normalizedOsVersion, k8sVersion, tag)
err = convertError(downloadByTool(bundleAddr, dir))
if err != nil {
return err
Expand Down Expand Up @@ -148,8 +158,8 @@ func (bd *bundleDownloader) getBundlePathWithRepo() string {
return filepath.Join(bd.downloadPath, strings.ReplaceAll(bd.repoAddr, "/", "."))
}

// getBundleAddr returns the exact address to the bundle in the repo.
func (bd *bundleDownloader) getBundleAddr(normalizedOsVersion, k8sVersion, tag string) string {
// GetBundleAddr returns the exact address to the bundle in the repo.
func (bd *bundleDownloader) GetBundleAddr(normalizedOsVersion, k8sVersion, tag string) string {
return fmt.Sprintf("%s/%s:%s", bd.repoAddr, GetBundleName(normalizedOsVersion), tag)
}

Expand Down
22 changes: 11 additions & 11 deletions agent/installer/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ const (
)

// BundleType is used to support various bundles
type bundleType string
type BundleType string

const (
// BundleTypeK8s represents a vanilla k8s bundle
BundleTypeK8s bundleType = "k8s"
BundleTypeK8s BundleType = "k8s"
)

var preRequisitePackages = []string{"socat", "ebtables", "ethtool", "conntrack"}
Expand All @@ -49,8 +49,8 @@ type installer struct {
logger logr.Logger
}

// getSupportedRegistry returns a registry with installers for the supported OS and K8s
func getSupportedRegistry(ob algo.OutputBuilder) registry {
// GetSupportedRegistry returns a registry with installers for the supported OS and K8s
func GetSupportedRegistry(ob algo.OutputBuilder) registry {
reg := newRegistry()

addBundleInstaller := func(osBundle, k8sBundle string, stepProvider algo.K8sStepProvider) {
Expand Down Expand Up @@ -116,7 +116,7 @@ func (bd *bundleDownloader) DownloadOrPreview(os, k8s, tag string) error {
// New returns an installer that downloads bundles for the current OS from OCI repository with
// address bundleRepo and stores them under downloadPath. Download path is created,
// if it does not exist.
func New(downloadPath string, bundleType bundleType, logger logr.Logger) (*installer, error) {
func New(downloadPath string, bundleType BundleType, logger logr.Logger) (*installer, error) {
if downloadPath == "" {
return nil, fmt.Errorf("empty download path")
}
Expand All @@ -139,17 +139,17 @@ func New(downloadPath string, bundleType bundleType, logger logr.Logger) (*insta
// newUnchecked returns an installer bypassing os detection and checks of downloadPath.
// If it is empty, returned installer will run in preview mode, i.e.
// executes everything except the actual commands.
func newUnchecked(currentOs string, bundleType bundleType, downloadPath string, logger logr.Logger, outputBuilder algo.OutputBuilder) (*installer, error) {
bd := bundleDownloader{repoAddr: "", bundleType: bundleType, downloadPath: downloadPath, logger: logger}
func newUnchecked(currentOs string, bundleType BundleType, downloadPath string, logger logr.Logger, outputBuilder algo.OutputBuilder) (*installer, error) {
bd := NewBundleDownloader(bundleType, "", downloadPath, logger)

reg := getSupportedRegistry(outputBuilder)
reg := GetSupportedRegistry(outputBuilder)
if len(reg.ListK8s(currentOs)) == 0 {
return nil, ErrOsK8sNotSupported
}

return &installer{
algoRegistry: reg,
bundleDownloader: bd,
bundleDownloader: *bd,
detectedOs: currentOs,
logger: logger}, nil
}
Expand Down Expand Up @@ -228,15 +228,15 @@ func ListSupportedK8s(os string) []string {
// getSupportedRegistryDescription returns a description registry of supported OS and k8s.
// It that can only be queried for OS and k8s but cannot be used for install/uninstall.
func getSupportedRegistryDescription() registry {
return getSupportedRegistry(nil)
return GetSupportedRegistry(nil)
}

// PreviewChanges describes the changes to install and uninstall K8s on OS without actually applying them.
// It returns install and uninstall changes
// Can be invoked on a non-supported OS
func PreviewChanges(os, k8sVer string) (install, uninstall string, err error) {
stepPreviewer := stringPrinter{msgFmt: "# %s"}
reg := getSupportedRegistry(&stepPreviewer)
reg := GetSupportedRegistry(&stepPreviewer)
installer, _ := reg.GetInstaller(os, k8sVer)

if installer == nil {
Expand Down
63 changes: 0 additions & 63 deletions agent/installer/steps.go

This file was deleted.

7 changes: 7 additions & 0 deletions apis/infrastructure/v1beta1/k8sinstallerconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// K8sInstallerConfigFinalizer allows ReconcileK8sInstallerConfig to clean up secret
// resources associated with K8sInstallerConfig before removing it from the
// API Server.
K8sInstallerConfigFinalizer = "k8sinstallerconfig.infrastructure.cluster.x-k8s.io"
)

// K8sInstallerConfigSpec defines the desired state of K8sInstallerConfig
type K8sInstallerConfigSpec struct {
// BundleRepo is the OCI registry from which the carvel imgpkg bundle will be downloaded
Expand Down
19 changes: 19 additions & 0 deletions common/installer/downloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2022 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package installer

import (
"github.com/go-logr/logr"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/installer"
)

// BundleDownloader represent a bundle downloader interface
type BundleDownloader interface {
GetBundleAddr(normalizedOsVersion, k8sVersion, tag string) string
}

// DefaultBundleDownloader implement the downloader interface
func DefaultBundleDownloader(bundleType, repoAddr, downloadPath string, logger logr.Logger) BundleDownloader {
return installer.NewBundleDownloader(installer.BundleType(bundleType), repoAddr, downloadPath, logger)
}
33 changes: 33 additions & 0 deletions common/installer/installer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2022 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package installer

import (
"context"
"strings"

"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/agent/installer"
"github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/common/installer/internal/algo"
)

// K8sInstaller represent k8s installer interface
type K8sInstaller interface {
Install() string
Uninstall() string
}

// NewInstaller will return a new installer
func NewInstaller(ctx context.Context, osDist, arch, k8sVersion string, downloader BundleDownloader) (K8sInstaller, error) {
// normalizing os image name and adding arch
osArch := strings.ReplaceAll(osDist, " ", "_") + "_" + arch

reg := installer.GetSupportedRegistry(nil)
if len(reg.ListK8s(osArch)) == 0 {
return nil, installer.ErrOsK8sNotSupported
}
_, osbundle := reg.GetInstaller(osArch, k8sVersion)
addrs := downloader.GetBundleAddr(osbundle, k8sVersion, k8sVersion)

return algo.NewUbuntu20_04Installer(ctx, arch, addrs)
}
Loading

0 comments on commit 779caac

Please sign in to comment.