projects/aws/image-builder/builder/manifests.go (168 lines of code) (raw):

package builder import ( "archive/tar" "fmt" "io" "log" "os" "path/filepath" "strings" releasev1 "github.com/aws/eks-anywhere/release/api/v1alpha1" k8syaml "sigs.k8s.io/yaml" ) // DownloadManifests connects to the internet, clones a fresh copy of eks-a-build-tooling repo // and pulls EKS-A and EKS-D artifacts for all supported releases and creates an archive. func (b *BuildOptions) DownloadManifests() error { // Clone build tooling from the latest release branch cwd, err := os.Getwd() if err != nil { return fmt.Errorf("Error retrieving current working directory: %v", err) } buildToolingRepoPath := getBuildToolingPath(cwd) _, _, err = b.prepBuildToolingRepo(buildToolingRepoPath) if err != nil { return err } // Download eks-d manifests manifestsPath := filepath.Join(cwd, "manifests") if err = downloadEKSDManifests(manifestsPath); err != nil { return err } // Download eks-a manifests if err = downloadEKSAManifests(manifestsPath); err != nil { return err } // Create tarball of the downloaded manifests log.Println("Creating tarball of downloaded manifests") if err = createTarball(manifestsTarballName, manifestsPath); err != nil { return err } log.Printf("Manifest tarball %s was successfully created", manifestsTarballName) // Clean up manifests directory if err = os.RemoveAll(manifestsPath); err != nil { return err } cleanup(buildToolingRepoPath) return nil } func downloadEKSDManifests(outputPath string) error { // Get all eksDReleases with their release numbers eksDReleaseBranchesWithNumber, err := getEksDReleaseBranchesWithNumber() if err != nil { return err } // Create output directory path if err = os.MkdirAll(outputPath, 0o755); 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) manifestFilePath := filepath.Join(outputPath, manifestFileName) log.Printf("Downloading eks-d manifest for release branch %s, release number %s", branch, number) if err := downloadFile(manifestFilePath, manifestUrl); err != nil { return err } } return nil } func downloadEKSAManifests(outputPath string) error { // Download Release manifest releaseManifestUrl, err := getEksAReleasesManifestURL(false) if err != nil { return err } // Create output directory path if err = os.MkdirAll(outputPath, 0o755); err != nil { return err } releaseManifestPath := filepath.Join(outputPath, eksAnywhereManifestFileName) log.Printf("Downloading eks-a release manifest") if err := downloadFile(releaseManifestPath, releaseManifestUrl); err != nil { return err } // Download all the bundles from release manifest releaseManifestData, err := os.ReadFile(releaseManifestPath) if err != nil { return err } releases := &releasev1.Release{} if err = k8syaml.Unmarshal(releaseManifestData, releases); err != nil { return err } for _, r := range releases.Spec.Releases { bundleName := fmt.Sprintf(eksAnywhereBundlesFileNameFormat, r.Version) bundleFilePath := filepath.Join(outputPath, bundleName) log.Printf("Downloading eks-a bundles manifest for eks-a version: %s", r.Version) if err = downloadFile(bundleFilePath, r.BundleManifestUrl); err != nil { return err } } return nil } // extractTarball extracts the provided tarball onto the path func extractTarball(tarball, path string) error { tarFile, err := os.Open(tarball) if err != nil { return err } defer tarFile.Close() // Create a new directory to extract the tarball into. if err = os.RemoveAll(path); err != nil { return err } err = os.MkdirAll(path, 0o755) if err != nil { return err } // Create a tar reader for the tarball. tarReader := tar.NewReader(tarFile) // Iterate over the tarball's entries. for { // Get the next header from the tarball. header, err := tarReader.Next() if err == io.EOF { // We've reached the end of the tarball. break } if err != nil { return err } // Create a new file for the tar entry. outFile, err := os.Create(filepath.Join(path, header.Name)) if err != nil { return err } defer outFile.Close() // Copy the tar entry's contents to the new file. _, err = io.Copy(outFile, tarReader) if err != nil { return err } outFile.Chmod(os.FileMode(header.Mode)) } return nil } 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 } if eksDMatch { log.Printf("Replacing EKS-D domain name in file: %s\n", file.Name()) 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: %t, Pattern: %s\n", file.Name(), eksAMatch, eksABundlesManifestFilePattern) if eksAMatch { log.Printf("Replacing EKS-A domain name in file: %s\n", file.Name()) if err = replaceStringInFile(absFilePath, fmt.Sprintf("https://%s", eksAnywhereAssetsProdDomain), privateEksAServerDomain); err != nil { return err } } } } return nil }