Replace creating jobs mechanism, small code fixes
This commit is contained in:
parent
ab1d3fb59b
commit
9f2fe2492e
|
|
@ -151,6 +151,10 @@ func (jenkins *jenkins) GetNodeSecret(name string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
match := regex.FindStringSubmatch(content)
|
match := regex.FindStringSubmatch(content)
|
||||||
|
if match == nil {
|
||||||
|
return "", errors.New("Node secret cannot be parsed")
|
||||||
|
}
|
||||||
|
|
||||||
result := make(map[string]string)
|
result := make(map[string]string)
|
||||||
|
|
||||||
for i, name := range regex.SubexpNames() {
|
for i, name := range regex.SubexpNames() {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package resources
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,12 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||||
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
|
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
|
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/jobs"
|
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/groovy"
|
||||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
"reflect"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
stackerr "github.com/pkg/errors"
|
stackerr "github.com/pkg/errors"
|
||||||
|
|
@ -26,16 +24,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ConfigureSeedJobsName this is the fixed seed job name
|
|
||||||
ConfigureSeedJobsName = constants.OperatorName + "-configure-seed-job"
|
|
||||||
|
|
||||||
idParameterName = "ID"
|
|
||||||
credentialIDParameterName = "CREDENTIAL_ID"
|
|
||||||
repositoryURLParameterName = "REPOSITORY_URL"
|
|
||||||
repositoryBranchParameterName = "REPOSITORY_BRANCH"
|
|
||||||
targetsParameterName = "TARGETS"
|
|
||||||
displayNameParameterName = "SEED_JOB_DISPLAY_NAME"
|
|
||||||
|
|
||||||
// UsernameSecretKey is username data key in Kubernetes secret used to create Jenkins username/password credential
|
// UsernameSecretKey is username data key in Kubernetes secret used to create Jenkins username/password credential
|
||||||
UsernameSecretKey = "username"
|
UsernameSecretKey = "username"
|
||||||
// PasswordSecretKey is password data key in Kubernetes secret used to create Jenkins username/password credential
|
// PasswordSecretKey is password data key in Kubernetes secret used to create Jenkins username/password credential
|
||||||
|
|
@ -49,9 +37,6 @@ const (
|
||||||
|
|
||||||
// AgentName is the name of seed job agent
|
// AgentName is the name of seed job agent
|
||||||
AgentName = "seed-job-agent"
|
AgentName = "seed-job-agent"
|
||||||
|
|
||||||
// AgentNamespace is the namespace of seed job agent
|
|
||||||
AgentNamespace = "default"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SeedJobs defines API for configuring and ensuring Jenkins Seed Jobs and Deploy Keys
|
// SeedJobs defines API for configuring and ensuring Jenkins Seed Jobs and Deploy Keys
|
||||||
|
|
@ -77,20 +62,35 @@ func (s *SeedJobs) EnsureSeedJobs(jenkins *v1alpha2.Jenkins) (done bool, err err
|
||||||
return false, s.restartJenkinsMasterPod(*jenkins)
|
return false, s.restartJenkinsMasterPod(*jenkins)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = s.createJob(); err != nil {
|
if len(jenkins.Spec.SeedJobs) > 0 {
|
||||||
s.logger.V(log.VWarn).Info("Couldn't create jenkins seed job")
|
err := s.createAgent(s.jenkinsClient, s.k8sClient, jenkins, jenkins.Namespace, AgentName)
|
||||||
return false, err
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
} else if len(jenkins.Spec.SeedJobs) == 0 {
|
||||||
|
err := s.k8sClient.Delete(context.TODO(), &appsv1.Deployment{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: jenkins.Namespace,
|
||||||
|
Name: fmt.Sprintf("%s-deployment", AgentName),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = s.ensureLabelsForSecrets(*jenkins); err != nil {
|
if err = s.ensureLabelsForSecrets(*jenkins); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
done, err = s.buildJobs(jenkins)
|
requeue, err := s.createJobs(jenkins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.V(log.VWarn).Info("Couldn't build jenkins seed job")
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
if requeue {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
seedJobIDs := s.getAllSeedJobIDs(*jenkins)
|
seedJobIDs := s.getAllSeedJobIDs(*jenkins)
|
||||||
if done && !reflect.DeepEqual(seedJobIDs, jenkins.Status.CreatedSeedJobs) {
|
if done && !reflect.DeepEqual(seedJobIDs, jenkins.Status.CreatedSeedJobs) {
|
||||||
|
|
@ -98,37 +98,35 @@ func (s *SeedJobs) EnsureSeedJobs(jenkins *v1alpha2.Jenkins) (done bool, err err
|
||||||
return false, stackerr.WithStack(s.k8sClient.Update(context.TODO(), jenkins))
|
return false, stackerr.WithStack(s.k8sClient.Update(context.TODO(), jenkins))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(seedJobIDs) > 0 {
|
return true, nil
|
||||||
err := CreateAgent(s.jenkinsClient, s.k8sClient, jenkins, jenkins.Namespace, AgentName)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else if len(seedJobIDs) == 0 {
|
|
||||||
err := s.k8sClient.Delete(context.TODO(), &appsv1.Deployment{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Namespace: AgentNamespace,
|
|
||||||
Name: fmt.Sprintf("%s-deployment", AgentName),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return done, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return done, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createJob is responsible for creating jenkins job which configures jenkins seed jobs and deploy keys
|
// createJob is responsible for creating jenkins job which configures jenkins seed jobs and deploy keys
|
||||||
func (s *SeedJobs) createJob() error {
|
func (s *SeedJobs) createJobs(jenkins *v1alpha2.Jenkins) (bool, error) {
|
||||||
_, created, err := s.jenkinsClient.CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName)
|
groovyClient := groovy.New(s.jenkinsClient, s.k8sClient, s.logger, jenkins, "user-groovy", jenkins.Spec.GroovyScripts.Customization)
|
||||||
if err != nil {
|
for _, seedJob := range jenkins.Spec.SeedJobs {
|
||||||
return err
|
credentialValue, err := s.credentialValue(jenkins.Namespace, seedJob)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
groovyScript := seedJobCreatingGroovyScript(seedJob)
|
||||||
|
|
||||||
|
hash := sha256.New()
|
||||||
|
hash.Write([]byte(groovyScript))
|
||||||
|
hash.Write([]byte(credentialValue))
|
||||||
|
requeue, err := groovyClient.EnsureSingle(seedJob.ID, fmt.Sprintf("%s.groovy", seedJob.ID), base64.URLEncoding.EncodeToString(hash.Sum(nil)), groovyScript)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if requeue {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if created {
|
|
||||||
s.logger.Info(fmt.Sprintf("'%s' job has been created", ConfigureSeedJobsName))
|
return false, nil
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensureLabelsForSecrets adds labels to Kubernetes secrets where are Jenkins credentials used for seed jobs,
|
// ensureLabelsForSecrets adds labels to Kubernetes secrets where are Jenkins credentials used for seed jobs,
|
||||||
|
|
@ -160,45 +158,6 @@ func (s *SeedJobs) ensureLabelsForSecrets(jenkins v1alpha2.Jenkins) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildJobs is responsible for running jenkins builds which configures jenkins seed jobs and deploy keys
|
|
||||||
func (s *SeedJobs) buildJobs(jenkins *v1alpha2.Jenkins) (done bool, err error) {
|
|
||||||
allDone := true
|
|
||||||
for _, seedJob := range jenkins.Spec.SeedJobs {
|
|
||||||
credentialValue, err := s.credentialValue(jenkins.Namespace, seedJob)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
parameters := map[string]string{
|
|
||||||
idParameterName: seedJob.ID,
|
|
||||||
credentialIDParameterName: seedJob.CredentialID,
|
|
||||||
repositoryURLParameterName: seedJob.RepositoryURL,
|
|
||||||
repositoryBranchParameterName: seedJob.RepositoryBranch,
|
|
||||||
targetsParameterName: seedJob.Targets,
|
|
||||||
displayNameParameterName: fmt.Sprintf("Seed Job from %s", seedJob.ID),
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := sha256.New()
|
|
||||||
hash.Write([]byte(parameters[idParameterName]))
|
|
||||||
hash.Write([]byte(parameters[credentialIDParameterName]))
|
|
||||||
hash.Write([]byte(credentialValue))
|
|
||||||
hash.Write([]byte(parameters[repositoryURLParameterName]))
|
|
||||||
hash.Write([]byte(parameters[repositoryBranchParameterName]))
|
|
||||||
hash.Write([]byte(parameters[targetsParameterName]))
|
|
||||||
hash.Write([]byte(parameters[displayNameParameterName]))
|
|
||||||
encodedHash := base64.URLEncoding.EncodeToString(hash.Sum(nil))
|
|
||||||
|
|
||||||
jobsClient := jobs.New(s.jenkinsClient, s.k8sClient, s.logger)
|
|
||||||
done, err := jobsClient.EnsureBuildJob(ConfigureSeedJobsName, encodedHash, parameters, jenkins, true)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if !done {
|
|
||||||
allDone = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allDone, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SeedJobs) credentialValue(namespace string, seedJob v1alpha2.SeedJob) (string, error) {
|
func (s *SeedJobs) credentialValue(namespace string, seedJob v1alpha2.SeedJob) (string, error) {
|
||||||
if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType {
|
if seedJob.JenkinsCredentialType == v1alpha2.BasicSSHCredentialType || seedJob.JenkinsCredentialType == v1alpha2.UsernamePasswordCredentialType {
|
||||||
secret := &corev1.Secret{}
|
secret := &corev1.Secret{}
|
||||||
|
|
@ -262,7 +221,7 @@ func (s *SeedJobs) isRecreatePodNeeded(jenkins v1alpha2.Jenkins) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAgent deploys Jenkins agent to Kubernetes cluster
|
// CreateAgent deploys Jenkins agent to Kubernetes cluster
|
||||||
func CreateAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string) error {
|
func (s SeedJobs) createAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string) error {
|
||||||
var exists bool
|
var exists bool
|
||||||
|
|
||||||
nodes, err := jenkinsClient.GetAllNodes()
|
nodes, err := jenkinsClient.GetAllNodes()
|
||||||
|
|
@ -286,41 +245,28 @@ func CreateAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, j
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deployments := &apps.DeploymentList{}
|
|
||||||
exists = false
|
|
||||||
secret, err := jenkinsClient.GetNodeSecret(agentName)
|
secret, err := jenkinsClient.GetNodeSecret(agentName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
deployment := agentDeployment(jenkinsManifest, namespace, agentName, secret)
|
deployment := agentDeployment(jenkinsManifest, namespace, agentName, secret)
|
||||||
err = k8sClient.List(context.TODO(), &client.ListOptions{}, deployments)
|
|
||||||
|
err = k8sClient.Create(context.TODO(), deployment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
err := k8sClient.Update(context.TODO(), deployment)
|
||||||
}
|
|
||||||
|
|
||||||
if len(deployments.Items) > 0 {
|
|
||||||
for _, deployment := range deployments.Items {
|
|
||||||
if deployment.ObjectMeta.Name == fmt.Sprintf("%s-deployment", agentName) {
|
|
||||||
exists = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create deployment if not exists
|
|
||||||
if !exists {
|
|
||||||
err = k8sClient.Create(context.TODO(), deployment)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string, secret string) *apps.Deployment {
|
func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string, secret string) *apps.Deployment {
|
||||||
return &apps.Deployment{
|
return &apps.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: fmt.Sprintf("%s-deployment", agentName),
|
Name: "jnlp",
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
},
|
},
|
||||||
Spec: apps.DeploymentSpec{
|
Spec: apps.DeploymentSpec{
|
||||||
|
|
@ -374,60 +320,26 @@ func agentDeployment(jenkinsManifest *v1alpha2.Jenkins, namespace string, agentN
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Status: apps.DeploymentStatus{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// seedJobConfigXML this is the XML representation of seed job
|
func seedJobCreatingGroovyScript(s v1alpha2.SeedJob) string {
|
||||||
var seedJobConfigXML = `
|
return `
|
||||||
<flow-definition plugin="workflow-job@2.30">
|
import hudson.model.FreeStyleProject;
|
||||||
<actions/>
|
import hudson.plugins.git.GitSCM;
|
||||||
<description>Configure Seed Jobs</description>
|
import hudson.plugins.git.BranchSpec;
|
||||||
<keepDependencies>false</keepDependencies>
|
import hudson.triggers.SCMTrigger;
|
||||||
<properties>
|
import hudson.util.Secret;
|
||||||
<hudson.model.ParametersDefinitionProperty>
|
import javaposse.jobdsl.plugin.*;
|
||||||
<parameterDefinitions>
|
import jenkins.model.Jenkins;
|
||||||
<hudson.model.StringParameterDefinition>
|
import jenkins.model.JenkinsLocationConfiguration;
|
||||||
<name>` + idParameterName + `</name>
|
import com.cloudbees.plugins.credentials.CredentialsScope;
|
||||||
<description></description>
|
import com.cloudbees.plugins.credentials.domains.Domain;
|
||||||
<defaultValue></defaultValue>
|
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
|
||||||
<trim>false</trim>
|
import jenkins.model.JenkinsLocationConfiguration;
|
||||||
</hudson.model.StringParameterDefinition>
|
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
||||||
<hudson.model.StringParameterDefinition>
|
import org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition;
|
||||||
<name>` + credentialIDParameterName + `</name>
|
|
||||||
<description></description>
|
|
||||||
<defaultValue></defaultValue>
|
|
||||||
<trim>false</trim>
|
|
||||||
</hudson.model.StringParameterDefinition>
|
|
||||||
<hudson.model.StringParameterDefinition>
|
|
||||||
<name>` + repositoryURLParameterName + `</name>
|
|
||||||
<description></description>
|
|
||||||
<defaultValue></defaultValue>
|
|
||||||
<trim>false</trim>
|
|
||||||
</hudson.model.StringParameterDefinition>
|
|
||||||
<hudson.model.StringParameterDefinition>
|
|
||||||
<name>` + repositoryBranchParameterName + `</name>
|
|
||||||
<description></description>
|
|
||||||
<defaultValue>master</defaultValue>
|
|
||||||
<trim>false</trim>
|
|
||||||
</hudson.model.StringParameterDefinition>
|
|
||||||
<hudson.model.StringParameterDefinition>
|
|
||||||
<name>` + displayNameParameterName + `</name>
|
|
||||||
<description></description>
|
|
||||||
<defaultValue></defaultValue>
|
|
||||||
<trim>false</trim>
|
|
||||||
</hudson.model.StringParameterDefinition>
|
|
||||||
<hudson.model.StringParameterDefinition>
|
|
||||||
<name>` + targetsParameterName + `</name>
|
|
||||||
<description></description>
|
|
||||||
<defaultValue>cicd/jobs/*.jenkins</defaultValue>
|
|
||||||
<trim>false</trim>
|
|
||||||
</hudson.model.StringParameterDefinition>
|
|
||||||
</parameterDefinitions>
|
|
||||||
</hudson.model.ParametersDefinitionProperty>
|
|
||||||
</properties>
|
|
||||||
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.61">
|
|
||||||
<script>
|
|
||||||
import hudson.model.FreeStyleProject
|
import hudson.model.FreeStyleProject
|
||||||
import hudson.model.labels.LabelAtom
|
import hudson.model.labels.LabelAtom
|
||||||
import hudson.plugins.git.BranchSpec
|
import hudson.plugins.git.BranchSpec
|
||||||
|
|
@ -443,23 +355,23 @@ import static com.google.common.collect.Lists.newArrayList
|
||||||
|
|
||||||
Jenkins jenkins = Jenkins.instance
|
Jenkins jenkins = Jenkins.instance
|
||||||
|
|
||||||
def jobDslSeedName = "${params.` + idParameterName + `}-` + constants.SeedJobSuffix + `"
|
def jobDslSeedName = "` + s.ID + `-` + constants.SeedJobSuffix + `";
|
||||||
def jobRef = jenkins.getItem(jobDslSeedName)
|
def jobRef = jenkins.getItem(jobDslSeedName)
|
||||||
|
|
||||||
def repoList = GitSCM.createRepoList("${params.` + repositoryURLParameterName + `}", "${params.` + credentialIDParameterName + `}")
|
def repoList = GitSCM.createRepoList("` + s.RepositoryURL + `", "` + s.CredentialID + `")
|
||||||
def gitExtensions = [new CloneOption(true, true, "", 10)]
|
def gitExtensions = [new CloneOption(true, true, ";", 10)]
|
||||||
def scm = new GitSCM(
|
def scm = new GitSCM(
|
||||||
repoList,
|
repoList,
|
||||||
newArrayList(new BranchSpec("${params.` + repositoryBranchParameterName + `}")),
|
newArrayList(new BranchSpec("` + s.RepositoryBranch + `")),
|
||||||
false,
|
false,
|
||||||
Collections.<SubmoduleConfig> emptyList(),
|
Collections.<SubmoduleConfig>emptyList(),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
gitExtensions
|
gitExtensions
|
||||||
)
|
)
|
||||||
|
|
||||||
def executeDslScripts = new ExecuteDslScripts()
|
def executeDslScripts = new ExecuteDslScripts()
|
||||||
executeDslScripts.setTargets("${params.` + targetsParameterName + `}")
|
executeDslScripts.setTargets("` + s.Targets + `")
|
||||||
executeDslScripts.setSandbox(false)
|
executeDslScripts.setSandbox(false)
|
||||||
executeDslScripts.setRemovedJobAction(RemovedJobAction.DELETE)
|
executeDslScripts.setRemovedJobAction(RemovedJobAction.DELETE)
|
||||||
executeDslScripts.setRemovedViewAction(RemovedViewAction.DELETE)
|
executeDslScripts.setRemovedViewAction(RemovedViewAction.DELETE)
|
||||||
|
|
@ -468,18 +380,15 @@ executeDslScripts.setLookupStrategy(LookupStrategy.SEED_JOB)
|
||||||
if (jobRef == null) {
|
if (jobRef == null) {
|
||||||
jobRef = jenkins.createProject(FreeStyleProject, jobDslSeedName)
|
jobRef = jenkins.createProject(FreeStyleProject, jobDslSeedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
jobRef.getBuildersList().clear()
|
jobRef.getBuildersList().clear()
|
||||||
jobRef.getBuildersList().add(executeDslScripts)
|
jobRef.getBuildersList().add(executeDslScripts)
|
||||||
jobRef.setDisplayName("${params.` + displayNameParameterName + `}")
|
jobRef.setDisplayName("` + fmt.Sprintf("Seed Job from %s", s.ID) + `")
|
||||||
jobRef.setScm(scm)
|
jobRef.setScm(scm)
|
||||||
// TODO don't use master executors
|
|
||||||
jobRef.setAssignedLabel(new LabelAtom("` + AgentName + `"))
|
jobRef.setAssignedLabel(new LabelAtom("` + AgentName + `"))
|
||||||
|
|
||||||
jenkins.getQueue().schedule(jobRef)
|
jenkins.getQueue().schedule(jobRef)
|
||||||
</script>
|
|
||||||
<sandbox>false</sandbox>
|
|
||||||
</definition>
|
|
||||||
<triggers/>
|
|
||||||
<disabled>false</disabled>
|
|
||||||
</flow-definition>
|
|
||||||
`
|
`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import (
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||||
|
|
@ -37,7 +36,6 @@ func TestEnsureSeedJobs(t *testing.T) {
|
||||||
jenkins := jenkinsCustomResource()
|
jenkins := jenkinsCustomResource()
|
||||||
err = fakeClient.Create(ctx, jenkins)
|
err = fakeClient.Create(ctx, jenkins)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
buildNumber := int64(1)
|
|
||||||
|
|
||||||
agentName := "seed-job-agent"
|
agentName := "seed-job-agent"
|
||||||
secret := "test-secret"
|
secret := "test-secret"
|
||||||
|
|
@ -52,78 +50,12 @@ func TestEnsureSeedJobs(t *testing.T) {
|
||||||
jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName).Return(testNode, nil)
|
jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName).Return(testNode, nil)
|
||||||
jenkinsClient.EXPECT().GetNode(agentName).Return(testNode, nil).AnyTimes()
|
jenkinsClient.EXPECT().GetNode(agentName).Return(testNode, nil).AnyTimes()
|
||||||
|
|
||||||
for reconcileAttempt := 1; reconcileAttempt <= 2; reconcileAttempt++ {
|
jenkinsClient.EXPECT().ExecuteScript(seedJobCreatingGroovyScript(jenkins.Spec.SeedJobs[0])).AnyTimes()
|
||||||
logger.Info(fmt.Sprintf("Reconcile attempt #%d", reconcileAttempt))
|
|
||||||
|
|
||||||
seedJobs := New(jenkinsClient, fakeClient, logger)
|
seedJobClient := New(jenkinsClient, fakeClient, logger)
|
||||||
|
|
||||||
// first run - should create job and schedule build
|
_, err = seedJobClient.EnsureSeedJobs(jenkins)
|
||||||
if reconcileAttempt == 1 {
|
assert.NoError(t, err)
|
||||||
jenkinsClient.
|
|
||||||
EXPECT().
|
|
||||||
CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName).
|
|
||||||
Return(nil, true, nil)
|
|
||||||
|
|
||||||
jenkinsClient.
|
|
||||||
EXPECT().
|
|
||||||
GetJob(ConfigureSeedJobsName).
|
|
||||||
Return(&gojenkins.Job{
|
|
||||||
Raw: &gojenkins.JobResponse{
|
|
||||||
NextBuildNumber: buildNumber,
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
jenkinsClient.
|
|
||||||
EXPECT().
|
|
||||||
BuildJob(ConfigureSeedJobsName, gomock.Any()).
|
|
||||||
Return(int64(0), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// second run - should update and finish job
|
|
||||||
if reconcileAttempt == 2 {
|
|
||||||
jenkinsClient.
|
|
||||||
EXPECT().
|
|
||||||
CreateOrUpdateJob(seedJobConfigXML, ConfigureSeedJobsName).
|
|
||||||
Return(nil, false, nil)
|
|
||||||
|
|
||||||
jenkinsClient.
|
|
||||||
EXPECT().
|
|
||||||
GetBuild(ConfigureSeedJobsName, gomock.Any()).
|
|
||||||
Return(&gojenkins.Build{
|
|
||||||
Raw: &gojenkins.BuildResponse{
|
|
||||||
Result: string(v1alpha2.BuildSuccessStatus),
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
done, err := seedJobs.EnsureSeedJobs(jenkins)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = fakeClient.Get(ctx, types.NamespacedName{Name: jenkins.Name, Namespace: jenkins.Namespace}, jenkins)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, 1, len(jenkins.Status.Builds), "There is one running job")
|
|
||||||
build := jenkins.Status.Builds[0]
|
|
||||||
assert.Equal(t, buildNumber, build.Number)
|
|
||||||
assert.Equal(t, ConfigureSeedJobsName, build.JobName)
|
|
||||||
assert.NotNil(t, build.CreateTime)
|
|
||||||
assert.NotEmpty(t, build.Hash)
|
|
||||||
assert.NotNil(t, build.LastUpdateTime)
|
|
||||||
assert.Equal(t, 0, build.Retires)
|
|
||||||
|
|
||||||
// first run - should create job and schedule build
|
|
||||||
if reconcileAttempt == 1 {
|
|
||||||
assert.False(t, done)
|
|
||||||
assert.Equal(t, string(v1alpha2.BuildRunningStatus), string(build.Status))
|
|
||||||
}
|
|
||||||
|
|
||||||
// second run - should update and finish job
|
|
||||||
if reconcileAttempt == 2 {
|
|
||||||
assert.False(t, done)
|
|
||||||
assert.Equal(t, string(v1alpha2.BuildSuccessStatus), string(build.Status))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func jenkinsCustomResource() *v1alpha2.Jenkins {
|
func jenkinsCustomResource() *v1alpha2.Jenkins {
|
||||||
|
|
@ -235,47 +167,6 @@ func TestSeedJobs_isRecreatePodNeeded(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateAgent(t *testing.T) {
|
func TestCreateAgent(t *testing.T) {
|
||||||
t.Run("happy", func(t *testing.T) {
|
|
||||||
// given
|
|
||||||
//logger := logf.ZapLogger(false)
|
|
||||||
ctrl := gomock.NewController(t)
|
|
||||||
ctx := context.TODO()
|
|
||||||
defer ctrl.Finish()
|
|
||||||
|
|
||||||
namespace := "test-namespace"
|
|
||||||
agentName := "test-agent"
|
|
||||||
secret := "test-secret"
|
|
||||||
jenkinsCustomRes := jenkinsCustomResource()
|
|
||||||
testNode := &gojenkins.Node{
|
|
||||||
Raw: &gojenkins.NodeResponse{
|
|
||||||
DisplayName: agentName,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
jenkinsClient := jenkinsclient.NewMockJenkins(ctrl)
|
|
||||||
fakeClient := fake.NewFakeClient()
|
|
||||||
err := v1alpha2.SchemeBuilder.AddToScheme(scheme.Scheme)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
jenkinsClient.EXPECT().GetNode(agentName).Return(testNode, nil)
|
|
||||||
jenkinsClient.EXPECT().GetNodeSecret(agentName).Return(secret, nil)
|
|
||||||
jenkinsClient.EXPECT().GetAllNodes().Return([]*gojenkins.Node{}, nil)
|
|
||||||
jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName).Return(testNode, nil)
|
|
||||||
|
|
||||||
// when
|
|
||||||
err = CreateAgent(jenkinsClient, fakeClient, jenkinsCustomRes, namespace, agentName)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
//then
|
|
||||||
err = fakeClient.Get(ctx, types.NamespacedName{Name: fmt.Sprintf("%s-deployment", agentName), Namespace: namespace}, &appsv1.Deployment{})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
node, err := jenkinsClient.GetNode(agentName)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, node.Raw.DisplayName, testNode.Raw.DisplayName)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("not fail when deployment is available", func(t *testing.T) {
|
t.Run("not fail when deployment is available", func(t *testing.T) {
|
||||||
// given
|
// given
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
|
|
@ -295,6 +186,8 @@ func TestCreateAgent(t *testing.T) {
|
||||||
jenkinsClient.EXPECT().GetAllNodes().Return([]*gojenkins.Node{}, nil)
|
jenkinsClient.EXPECT().GetAllNodes().Return([]*gojenkins.Node{}, nil)
|
||||||
jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName)
|
jenkinsClient.EXPECT().CreateNode(agentName, 1, "The jenkins-operator generated agent", "/home/jenkins", agentName)
|
||||||
|
|
||||||
|
seedJobsClient := New(jenkinsClient, fakeClient, nil)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
err = fakeClient.Create(ctx, &appsv1.Deployment{
|
err = fakeClient.Create(ctx, &appsv1.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
|
@ -306,7 +199,7 @@ func TestCreateAgent(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
err = CreateAgent(jenkinsClient, fakeClient, jenkinsCustomResource(), namespace, agentName)
|
err = seedJobsClient.createAgent(jenkinsClient, fakeClient, jenkinsCustomResource(), namespace, agentName)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue