Skip to content

Commit

Permalink
Air-gapped Image building changes
Browse files Browse the repository at this point in the history
  • Loading branch information
vignesh-goutham committed Oct 17, 2023
1 parent f567db6 commit 638f129
Show file tree
Hide file tree
Showing 7 changed files with 373 additions and 30 deletions.
76 changes: 76 additions & 0 deletions projects/aws/image-builder/builder/airgap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package builder

import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
)

func extractAndPrepManifestTarball(tarballFile, privateEksDServerDomain, privateEksAServerDomain string) error {
log.Println("Manifest tarball provided, extracting to directory")
manifestDir, err := getManifestRoot()
if err != nil {
return fmt.Errorf("Error retrieving manifest root")
}
if err = extractTarball(tarballFile, manifestDir); err != nil {
return fmt.Errorf("Error extracting tarball: %v", err)
}

// Replacing eks-a bundles manifest hostname
// These endpoints are used for artifacts like containerd, crictl & etcdadm
// Find all eks-a bundles manifest and replace hostname
files, err := os.ReadDir(manifestDir)
if err != nil {
return err
}
for _, file := range files {
if !file.IsDir() {
// Find EKS-D Manifests and replace prod distro domain with private server's
absFilePath := filepath.Join(manifestDir, file.Name())
eksDManifestFilePattern := strings.ReplaceAll(eksDistroManifestFileNameFormat, "%s", "*")
eksDMatch, err := filepath.Match(eksDManifestFilePattern, file.Name())
if err != nil {
return err
}
fmt.Printf("File: %s, Match: %s, Pattern: %s\n", file.Name(), eksDMatch, eksDManifestFilePattern)
if eksDMatch {
if err = replaceStringInFile(absFilePath, fmt.Sprintf("https://%s", eksDistroProdDomain), privateEksDServerDomain); err != nil {
return err
}
}

// Find EKS-A Bundles Manifests and replace prod anywhere domain with private server's
eksABundlesManifestFilePattern := strings.ReplaceAll(eksAnywhereBundlesFileNameFormat, "%s", "*")
eksAMatch, err := filepath.Match(eksABundlesManifestFilePattern, file.Name())
if err != nil {
return err
}

fmt.Printf("File: %s, Match: %s, Pattern: %s\n", file.Name(), eksAMatch, eksABundlesManifestFilePattern)
if eksAMatch {
if err = replaceStringInFile(absFilePath, fmt.Sprintf("https://%s", eksAnywhereAssetsProdDomain), privateEksAServerDomain); err != nil {
return err
}
}
}
}
return nil
}

func replaceStringInFile(filePath, oldString, newString string) error {
fileContents, err := os.ReadFile(filePath)
if err != nil {
return err
}
replacedString := strings.ReplaceAll(string(fileContents), oldString, newString)
if err = os.Remove(filePath); err != nil {
return err
}
err = os.WriteFile(filePath, []byte(replacedString), 0755)
if err != nil {
return err
}
return nil
}
61 changes: 55 additions & 6 deletions projects/aws/image-builder/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,28 @@ func (b *BuildOptions) BuildImage() {
if err != nil {
log.Fatalf("Error retrieving current working directory: %v", err)
}
if b.AirGapped {
var eksDArtifactsDomain, eksAArtifactsDomain string
switch b.Hypervisor {
case VSphere:
eksDArtifactsDomain = b.VsphereConfig.PrivateServerEksDDomainUrl
eksAArtifactsDomain = b.VsphereConfig.PrivateServerEksADomainUrl
case Baremetal:
eksDArtifactsDomain = b.BaremetalConfig.PrivateServerEksDDomainUrl
eksAArtifactsDomain = b.BaremetalConfig.PrivateServerEksADomainUrl
case CloudStack:
eksDArtifactsDomain = b.CloudstackConfig.PrivateServerEksDDomainUrl
eksAArtifactsDomain = b.CloudstackConfig.PrivateServerEksADomainUrl
case Nutanix:
eksDArtifactsDomain = b.NutanixConfig.PrivateServerEksDDomainUrl
eksAArtifactsDomain = b.NutanixConfig.PrivateServerEksADomainUrl
}
if err = extractAndPrepManifestTarball(b.ManifestTarball, eksDArtifactsDomain, eksAArtifactsDomain); err != nil {
log.Fatalf(err.Error())
}
}
buildToolingRepoPath := getBuildToolingPath(cwd)
detectedEksaVersion, err := prepBuildToolingRepo(buildToolingRepoPath, b.EKSAReleaseVersion, b.Force)
detectedEksaVersion, err := b.prepBuildToolingRepo(buildToolingRepoPath)
if err != nil {
log.Fatal(err.Error())
}
Expand All @@ -38,10 +58,14 @@ func (b *BuildOptions) BuildImage() {
upstreamImageBuilderProjectPath := filepath.Join(imageBuilderProjectPath, imageBuilderCAPIDirectory)
var outputArtifactPath string
var outputImageGlob []string
eksAReleaseManifestUrl, err := getEksAReleasesManifestURL(b.AirGapped)
if err != nil {
log.Fatalf(err.Error())
}
commandEnvVars := []string{
fmt.Sprintf("%s=%s", releaseBranchEnvVar, b.ReleaseChannel),
fmt.Sprintf("%s=%s", eksAReleaseVersionEnvVar, detectedEksaVersion),
fmt.Sprintf("%s=%s", eksAReleaseManifestURLEnvVar, getEksAReleasesManifestURL()),
fmt.Sprintf("%s=%s", eksAReleaseManifestURLEnvVar, eksAReleaseManifestUrl),
}

log.Printf("Initiating Image Build\n Image OS: %s\n Image OS Version: %s\n Hypervisor: %s\n Firmware: %s\n", b.Os, b.OsVersion, b.Hypervisor, b.Firmware)
Expand Down Expand Up @@ -89,6 +113,14 @@ func (b *BuildOptions) BuildImage() {
}
var outputImageGlobPattern string
if b.Hypervisor == VSphere {
if b.AirGapped {
airGapEnvVars, err := getAirGapCmdEnvVars(b.VsphereConfig.ImageBuilderRepoUrl, detectedEksaVersion, b.ReleaseChannel)
if err != nil {
log.Fatalf("Error getting air gapped env variables: %v", err)
}
commandEnvVars = append(commandEnvVars, airGapEnvVars...)
}

// Set proxy on RHSM if available
if b.Os == RedHat && b.VsphereConfig.HttpProxy != "" {
if err := setRhsmProxy(&b.VsphereConfig.ProxyConfig, &b.VsphereConfig.RhsmConfig); err != nil {
Expand Down Expand Up @@ -134,6 +166,14 @@ func (b *BuildOptions) BuildImage() {

log.Printf("Image Build Successful\n Please find the output artifact at %s\n", outputArtifactPath)
} else if b.Hypervisor == Baremetal {
if b.AirGapped {
airGapEnvVars, err := getAirGapCmdEnvVars(b.BaremetalConfig.ImageBuilderRepoUrl, detectedEksaVersion, b.ReleaseChannel)
if err != nil {
log.Fatalf("Error getting air gapped env variables: %v", err)
}
commandEnvVars = append(commandEnvVars, airGapEnvVars...)
}

// Set proxy on RHSM if available
if b.Os == RedHat && b.BaremetalConfig.HttpProxy != "" {
if err := setRhsmProxy(&b.BaremetalConfig.ProxyConfig, &b.BaremetalConfig.RhsmConfig); err != nil {
Expand Down Expand Up @@ -180,10 +220,12 @@ func (b *BuildOptions) BuildImage() {

log.Printf("Image Build Successful\n Please find the output artifact at %s\n", outputArtifactPath)
} else if b.Hypervisor == Nutanix {
// Patch firmware config for tool
upstreamPatchCommand := fmt.Sprintf("make -C %s patch-repo", imageBuilderProjectPath)
if err := executeMakeBuildCommand(upstreamPatchCommand, commandEnvVars...); err != nil {
log.Fatalf("Error executing upstream patch command: %v", err)
if b.AirGapped {
airGapEnvVars, err := getAirGapCmdEnvVars(b.NutanixConfig.ImageBuilderRepoUrl, detectedEksaVersion, b.ReleaseChannel)
if err != nil {
log.Fatalf("Error getting air gapped env variables: %v", err)
}
commandEnvVars = append(commandEnvVars, airGapEnvVars...)
}

// Read and set the nutanix connection data
Expand All @@ -204,6 +246,13 @@ func (b *BuildOptions) BuildImage() {

log.Printf("Image Build Successful\n Please find the image uploaded under Nutanix Image Service with name %s\n", b.NutanixConfig.ImageName)
} else if b.Hypervisor == CloudStack {
if b.AirGapped {
airGapEnvVars, err := getAirGapCmdEnvVars(b.CloudstackConfig.ImageBuilderRepoUrl, detectedEksaVersion, b.ReleaseChannel)
if err != nil {
log.Fatalf("Error getting air gapped env variables: %v", err)
}
commandEnvVars = append(commandEnvVars, airGapEnvVars...)
}
// Set proxy on RHSM if available
if b.Os == RedHat && b.CloudstackConfig.HttpProxy != "" {
if err := setRhsmProxy(&b.CloudstackConfig.ProxyConfig, &b.CloudstackConfig.RhsmConfig); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions projects/aws/image-builder/builder/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ const (
devEksaReleaseManifestURL string = "https://dev-release-assets.eks-anywhere.model-rocket.aws.dev/eks-a-release.yaml"
devBranchEksaReleaseManifestURL string = "https://dev-release-assets.eks-anywhere.model-rocket.aws.dev/%s/eks-a-release.yaml"
eksDistroProdDomain string = "distro.eks.amazonaws.com"
eksAnywhereAssetsProdDomain string = "anywhere-assets.eks.amazonaws.com"
eksDistroManifestFileNameFormat string = "eks-d-%s.yaml"
eksAnywhereManifestFileName string = "eks-a-manifest.yaml"
eksAnywhereBundlesFileNameFormat string = "eks-a-bundles-%s.yaml"
manifestsTarballName string = "eks-a-manifests.tar"
manifestsDirName string = "eks-a-d-manifests"

// Environment variables
branchNameEnvVar string = "BRANCH_NAME"
Expand All @@ -41,13 +43,16 @@ const (
releaseBranchEnvVar string = "RELEASE_BRANCH"
eksAReleaseVersionEnvVar string = "EKSA_RELEASE_VERSION"
eksAReleaseManifestURLEnvVar string = "EKSA_RELEASE_MANIFEST_URL"
eksABundlesURLEnvVar string = "EKSA_BUNDLE_MANIFEST_URL"
eksDManifestURLEnvVar string = "EKSD_MANIFEST_URL"
packerAdditionalFilesConfigFileEnvVar string = "PACKER_ADDITIONAL_FILES_VAR_FILES"
rhelUsernameEnvVar string = "RHSM_USERNAME"
rhelPasswordEnvVar string = "RHSM_PASSWORD"
rhsmActivationKeyEnvVar string = "RHSM_ACTIVATION_KEY"
rhsmOrgIDEnvVar string = "RHSM_ORG_ID"
packerTypeVarFilesEnvVar string = "PACKER_TYPE_VAR_FILES"
eksaUseDevReleaseEnvVar string = "EKSA_USE_DEV_RELEASE"
cloneUrlEnvVar string = "CLONE_URL"

// Miscellaneous
mainBranch string = "main"
Expand Down
18 changes: 16 additions & 2 deletions projects/aws/image-builder/builder/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (b *BuildOptions) DownloadManifests() error {
}

buildToolingRepoPath := getBuildToolingPath(cwd)
_, err = prepBuildToolingRepo(buildToolingRepoPath, "", b.Force)
_, err = b.prepBuildToolingRepo(buildToolingRepoPath)
if err != nil {
return err
}
Expand Down Expand Up @@ -58,6 +58,11 @@ func downloadEKSDManifests(outputPath string) error {
return err
}

// Create output directory path
if err = os.MkdirAll(outputPath, 0755); err != nil {
return err
}

for branch, number := range eksDReleaseBranchesWithNumber {
manifestUrl := fmt.Sprintf("https://%s/kubernetes-%s/kubernetes-%s-eks-%s.yaml", eksDistroProdDomain, branch, branch, number)
manifestFileName := fmt.Sprintf(eksDistroManifestFileNameFormat, branch)
Expand All @@ -73,7 +78,16 @@ func downloadEKSDManifests(outputPath string) error {

func downloadEKSAManifests(outputPath string) error {
// Download Release manifest
releaseManifestUrl := getEksAReleasesManifestURL()
releaseManifestUrl, err := getEksAReleasesManifestURL(false)
if err != nil {
return err
}

// Create output directory path
if err = os.MkdirAll(outputPath, 0755); err != nil {
return err
}

releaseManifestPath := filepath.Join(outputPath, eksAnywhereManifestFileName)
log.Printf("Downloading eks-a release manifest")
if err := downloadFile(releaseManifestPath, releaseManifestUrl); err != nil {
Expand Down
13 changes: 13 additions & 0 deletions projects/aws/image-builder/builder/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type BuildOptions struct {
FilesConfig *AdditionalFilesConfig
ReleaseChannel string
Force bool
AirGapped bool
ManifestTarball string
Firmware string
EKSAReleaseVersion string
}
Expand All @@ -72,6 +74,7 @@ type VsphereConfig struct {
ProxyConfig
ExtraPackagesConfig
ExtraOverridesConfig
AirGappedConfig
}

type BaremetalConfig struct {
Expand All @@ -81,6 +84,7 @@ type BaremetalConfig struct {
ProxyConfig
ExtraPackagesConfig
ExtraOverridesConfig
AirGappedConfig
}

type CloudstackConfig struct {
Expand All @@ -90,6 +94,7 @@ type CloudstackConfig struct {
ProxyConfig
ExtraPackagesConfig
ExtraOverridesConfig
AirGappedConfig
}

type IsoConfig struct {
Expand Down Expand Up @@ -118,6 +123,7 @@ type NutanixConfig struct {
ProxyConfig
ExtraPackagesConfig
ExtraOverridesConfig
AirGappedConfig
}

type AMIConfig struct {
Expand Down Expand Up @@ -168,3 +174,10 @@ type ExtraOverridesConfig struct {
DisablePublicRepos string `json:"disable_public_repos,omitempty"`
ReenablePublicRepos string `json:"reenable_public_repos,omitempty"`
}

type AirGappedConfig struct {
EksABuildToolingRepoUrl string `json:"eksa_build_tooling_repo_url,omitempty"`
ImageBuilderRepoUrl string `json:"image_builder_repo_url,omitempty"`
PrivateServerEksDDomainUrl string `json:"private_artifacts_eksd_fqdn,omitempty"`
PrivateServerEksADomainUrl string `json:"private_artifacts_eksa_fqdn,omitempty"`
}
Loading

0 comments on commit 638f129

Please sign in to comment.