Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ var TektonInstallersetNamePrefixes [34]string = [34]string{

var PrefixesOfDefaultPipelines [9]string = [9]string{"buildah", "s2i-dotnet", "s2i-go", "s2i-java", "s2i-nodejs", "s2i-perl", "s2i-php", "s2i-python", "s2i-ruby"}

var (
HubKubeconfig = os.Getenv("HUB_KUBECONFIG")
SpokeKubeconfig = os.Getenv("SPOKE_KUBECONFIG")
)

// Flags holds the command line flags or defaults for settings in the user's environment.
// See EnvironmentFlags for a list of supported fields
// Todo: change initialization of falgs when required by parsing them or from environment variable
Expand Down
71 changes: 69 additions & 2 deletions pkg/oc/oc.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,56 @@ func Delete(path_dir, namespace string) {
log.Printf("output: %s\n", cmd.MustSuccedIncreasedTimeout(time.Second*300, "oc", "delete", "-f", config.Path(path_dir), "-n", namespace).Stdout())
}

// CreateNewProject Helps you to create new project
// CreateNewProject creates a new project on the local cluster, and also
// mirrors the project + a Kueue LocalQueue on hub and spoke clusters when
// HUB_KUBECONFIG / SPOKE_KUBECONFIG environment variables are set.
func CreateNewProject(ns string) {
log.Printf("output: %s\n", cmd.MustSucceed("oc", "new-project", ns).Stdout())
setupRemoteClusters(ns)
}

func setupRemoteClusters(ns string) {
for _, kc := range []struct {
name string
kubeconfig string
}{
{"hub", config.HubKubeconfig},
{"spoke", config.SpokeKubeconfig},
} {
if kc.kubeconfig == "" {
continue
}
log.Printf("Setting up project %q on %s cluster", ns, kc.name)
createProjectOnRemoteCluster(ns, kc.kubeconfig, kc.name)
createLocalQueueOnRemoteCluster(ns, kc.kubeconfig, kc.name)
}
}

func createProjectOnRemoteCluster(ns, kubeconfig, clusterName string) {
result := cmd.Run("oc", "new-project", ns, "--kubeconfig", kubeconfig)
if result.ExitCode != 0 {
log.Printf("Warning: failed to create project %q on %s cluster: %s", ns, clusterName, result.Stderr())
return
}
log.Printf("Created project %q on %s cluster", ns, clusterName)
}

func createLocalQueueOnRemoteCluster(ns, kubeconfig, clusterName string) {
localQueueYAML := fmt.Sprintf(`apiVersion: kueue.x-k8s.io/v1beta2
kind: LocalQueue
metadata:
name: pipelines-queue
namespace: %s
spec:
clusterQueue: cluster-queue`, ns)

result := cmd.Run("bash", "-c",
fmt.Sprintf("echo '%s' | oc apply --kubeconfig %s -f -", localQueueYAML, kubeconfig))
if result.ExitCode != 0 {
log.Printf("Warning: failed to create LocalQueue in %q on %s cluster: %s", ns, clusterName, result.Stderr())
return
}
log.Printf("Created LocalQueue 'pipelines-queue' in %q on %s cluster", ns, clusterName)
}

// DeleteProject Helps you to delete new project
Expand All @@ -48,6 +95,26 @@ func DeleteProject(ns string) {

func DeleteProjectIgnoreErors(ns string) {
log.Printf("output: %s\n", cmd.Run("oc", "delete", "project", ns).Stdout())
cleanupRemoteClusters(ns)
}

func cleanupRemoteClusters(ns string) {
for _, kc := range []struct {
name string
kubeconfig string
}{
{"hub", config.HubKubeconfig},
{"spoke", config.SpokeKubeconfig},
} {
if kc.kubeconfig == "" {
continue
}
log.Printf("Deleting project %q on %s cluster", ns, kc.name)
result := cmd.Run("oc", "delete", "project", ns, "--kubeconfig", kc.kubeconfig)
if result.ExitCode != 0 {
log.Printf("Warning: failed to delete project %q on %s cluster: %s", ns, kc.name, result.Stderr())
}
}
}

func LinkSecretToSA(secretname, sa, namespace string) {
Expand Down Expand Up @@ -172,4 +239,4 @@ func CopySecret(secretName string, sourceNamespace string, destNamespace string)
cmdOutput := cmd.MustSucceed("bash", "-c", fmt.Sprintf(`echo '%s' | jq 'del(.metadata["namespace", "creationTimestamp", "resourceVersion", "selfLink", "uid", "annotations"]) | .data |= with_entries(if .key == "github-auth-key" then .key = "token" else . end)'`, secretJson)).Stdout()
cmd.MustSucceed("bash", "-c", fmt.Sprintf(`echo '%s' | kubectl apply -n %s -f -`, cmdOutput, destNamespace))
log.Printf("Successfully copied secret %s from %s to %s", secretName, sourceNamespace, destNamespace)
}
}
39 changes: 38 additions & 1 deletion pkg/pac/pac.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,44 @@ func generatePipelineRun(eventType, branch, fileName string) error {
if err := pacgenerate.Generate(opts, true); err != nil {
return fmt.Errorf("failed to generate PipelineRun: %v", err)
}
return nil
return shortenPipelineRunName(fileName, eventType)
}

// shortenPipelineRunName replaces the long auto-generated PipelineRun name
// (e.g. "release-tests-fork-12345678-pull-request") with a compact name
// like "pac-pull-request". Only the top-level metadata.name is replaced.
func shortenPipelineRunName(fileName, eventType string) error {
data, err := os.ReadFile(filepath.Clean(fileName))
if err != nil {
return fmt.Errorf("failed to read generated file: %v", err)
}

shortName := "pac-" + strings.ReplaceAll(eventType, "_", "-")

var content map[string]any
if err := yaml.Unmarshal(data, &content); err != nil {
return fmt.Errorf("failed to parse generated YAML: %v", err)
}

if meta, ok := content["metadata"].(map[any]any); ok {
meta["name"] = shortName
}

if spec, ok := content["spec"].(map[any]any); ok {
taskRunTemplate, ok := spec["taskRunTemplate"].(map[any]any)
if !ok {
taskRunTemplate = map[any]any{}
spec["taskRunTemplate"] = taskRunTemplate
}
taskRunTemplate["serviceAccountName"] = "pipeline"
}

out, err := yaml.Marshal(content)
if err != nil {
return fmt.Errorf("failed to marshal YAML: %v", err)
}

return os.WriteFile(fileName, out, 0o600)
}

// Validate generated yaml file from pac generate cmd
Expand Down