From e6cbf58f7336c4ff032a354cf2631bd53609f642 Mon Sep 17 00:00:00 2001 From: Rafael Fonseca Date: Fri, 10 May 2024 00:58:34 +0200 Subject: [PATCH 1/2] CORS-3460: capi: collect generated assets in hidden dir This way they don't pollute the workdir neither confuse users by their existence. --- pkg/infrastructure/clusterapi/clusterapi.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/infrastructure/clusterapi/clusterapi.go b/pkg/infrastructure/clusterapi/clusterapi.go index 05344abb44..b35dafa5cd 100644 --- a/pkg/infrastructure/clusterapi/clusterapi.go +++ b/pkg/infrastructure/clusterapi/clusterapi.go @@ -51,6 +51,9 @@ const ( ignitionStage = "Bootstrap Ignition Provisioning" machineStage = "Machine Provisioning" postProvisionStage = "Infrastructure Post-provisioning" + + // CAPIArtifactsDir is the directory where the manifests generated by CAPI are stored. + CAPIArtifactsDir = ".clusterapi_output" ) // InfraProvider implements common Cluster API logic and @@ -338,7 +341,7 @@ func (i *InfraProvider) Provision(ctx context.Context, dir string, parents asset if err != nil { return fileList, fmt.Errorf("failed to get GVK for manifest: %w", err) } - fileName := fmt.Sprintf("%s-%s-%s.yaml", gvk.Kind, m.GetNamespace(), m.GetName()) + fileName := filepath.Join(CAPIArtifactsDir, fmt.Sprintf("%s-%s-%s.yaml", gvk.Kind, m.GetNamespace(), m.GetName())) objData, err := yaml.Marshal(m) if err != nil { return fileList, fmt.Errorf("failed to create infrastructure manifest %s from InstallConfig: %w", fileName, err) @@ -454,9 +457,10 @@ func extractIPAddress(manifestPath string) (string, error) { // ExtractHostAddresses extracts the IPs of the bootstrap and control plane machines. func (i *InfraProvider) ExtractHostAddresses(dir string, config *types.InstallConfig, ha *infrastructure.HostAddresses) error { - logrus.Debugf("Looking for machine manifests in %s", dir) + manifestsDir := filepath.Join(dir, CAPIArtifactsDir) + logrus.Debugf("Looking for machine manifests in %s", manifestsDir) - bootstrapFiles, err := filepath.Glob(filepath.Join(dir, "Machine\\-openshift\\-cluster\\-api\\-guests\\-*\\-bootstrap.yaml")) + bootstrapFiles, err := filepath.Glob(filepath.Join(manifestsDir, "Machine\\-openshift\\-cluster\\-api\\-guests\\-*\\-bootstrap.yaml")) if err != nil { return fmt.Errorf("failed to list bootstrap manifests: %w", err) } @@ -472,7 +476,7 @@ func (i *InfraProvider) ExtractHostAddresses(dir string, config *types.InstallCo logrus.Debugf("found bootstrap address: %s", addr) ha.Bootstrap = addr - masterFiles, err := filepath.Glob(filepath.Join(dir, "Machine\\-openshift\\-cluster\\-api\\-guests\\-*\\-master\\-?.yaml")) + masterFiles, err := filepath.Glob(filepath.Join(manifestsDir, "Machine\\-openshift\\-cluster\\-api\\-guests\\-*\\-master\\-?.yaml")) if err != nil { return fmt.Errorf("failed to list master machine manifests: %w", err) } From fa8074a5f7b2ff2e969097408f5974eff3fa5b8e Mon Sep 17 00:00:00 2001 From: Rafael Fonseca Date: Fri, 10 May 2024 01:02:53 +0200 Subject: [PATCH 2/2] CORS-3460: capi: save generated manifests into log bundle These manifests could provide debugging information about the capi resources configuration and last known state. --- cmd/openshift-install/gather.go | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/cmd/openshift-install/gather.go b/cmd/openshift-install/gather.go index 21b7e027fc..71d88776ae 100644 --- a/cmd/openshift-install/gather.go +++ b/cmd/openshift-install/gather.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "io/fs" "net" "os" "path/filepath" @@ -27,6 +28,7 @@ import ( "github.com/openshift/installer/pkg/gather/service" "github.com/openshift/installer/pkg/gather/ssh" "github.com/openshift/installer/pkg/infrastructure" + "github.com/openshift/installer/pkg/infrastructure/clusterapi" infra "github.com/openshift/installer/pkg/infrastructure/platform" _ "github.com/openshift/installer/pkg/gather/aws" @@ -142,6 +144,13 @@ func gatherBootstrap(bootstrap string, port int, masters []string, directory str gatherID := time.Now().Format("20060102150405") archives := map[string]string{} + if capiManifestsBundlePath, err := gatherCAPIManifests(directory, gatherID); err != nil { + // Do not fail the whole gather if we can't find capi manifests (we can be running terraform) + logrus.Infof("Failed to gather Cluster API manifests: %s", err.Error()) + } else { + archives[capiManifestsBundlePath] = "clusterapi" + } + serialLogBundle := filepath.Join(directory, fmt.Sprintf("serial-log-bundle-%s.tar.gz", gatherID)) serialLogBundlePath, err := filepath.Abs(serialLogBundle) if err != nil { @@ -237,3 +246,37 @@ func logClusterOperatorConditions(ctx context.Context, config *rest.Config) erro return nil } + +func gatherCAPIManifests(directory, gatherID string) (string, error) { + logrus.Infoln("Pulling Cluster API manifests") + dir, err := filepath.Abs(directory) + if err != nil { + return "", fmt.Errorf("failed to get absolute path for %s: %w", directory, err) + } + + capiDir := filepath.Join(dir, clusterapi.CAPIArtifactsDir) + if _, err := os.Stat(capiDir); err != nil { + if errors.Is(err, fs.ErrNotExist) { + return "", fmt.Errorf("either Cluster API manifests not generated or terraform provision") + } + return "", fmt.Errorf("failed to stat Cluster API output directory: %w", err) + } + + bundleDir := filepath.Join(dir, fmt.Sprintf("capi-manifests-bundle-%s", gatherID)) + // Symlink the hidden directory so the manifests are not hidden in the archive + if err := os.Symlink(capiDir, bundleDir); err != nil { + return "", fmt.Errorf("failed to copy Cluster API manifests: %w", err) + } + defer os.Remove(bundleDir) + + capiManifests, err := filepath.Glob(filepath.Join(bundleDir, "*.yaml")) + if err != nil { + return "", fmt.Errorf("failed to gather Cluster API manifests: %w", err) + } + + capiManifestsBundlePath := fmt.Sprintf("%s.tar.gz", bundleDir) + if err := serialgather.CreateArchive(capiManifests, capiManifestsBundlePath); err != nil { + return "", fmt.Errorf("failed to create clusterapi bundle file: %w", err) + } + return capiManifestsBundlePath, nil +}