Skip to content
Merged
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
53 changes: 44 additions & 9 deletions pkg/build/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ type BuildStatus string

// Valid values for BuildStatus.
const (
// BuildNew is automatically assigned to a newly created build.
// BuildStatusNew is automatically assigned to a newly created build.
BuildStatusNew BuildStatus = "New"

// BuildPending indicates that a pod name has been assigned and a build is
// BuildStatusPending indicates that a pod name has been assigned and a build is
// about to start running.
BuildStatusPending BuildStatus = "Pending"

// BuildRunning indicates that a pod has been created and a build is running.
// BuildStatusRunning indicates that a pod has been created and a build is running.
BuildStatusRunning BuildStatus = "Running"

// BuildComplete indicates that a build has been successful.
// BuildStatusComplete indicates that a build has been successful.
BuildStatusComplete BuildStatus = "Complete"

// BuildFailed indicates that a build has executed and failed.
// BuildStatusFailed indicates that a build has executed and failed.
BuildStatusFailed BuildStatus = "Failed"

// BuildError indicates that an error prevented the build from executing.
// BuildStatusError indicates that an error prevented the build from executing.
BuildStatusError BuildStatus = "Error"

// BuildStatusCancelled indicates that a running/pending build was stopped from executing.
Expand All @@ -72,7 +72,7 @@ type BuildSourceType string

// Valid values for BuildSourceType.
const (
//BuildGitSource is a Git SCM
//BuildSourceGit is a Git SCM
BuildSourceGit BuildSourceType = "Git"
)

Expand Down Expand Up @@ -150,6 +150,15 @@ const (
CustomBuildStrategyType BuildStrategyType = "Custom"
)

const (
// CustomBuildStrategyBaseImageKey is the environment variable that indicates the base image to be used when
// performing a custom build, if needed.
CustomBuildStrategyBaseImageKey = "OPENSHIFT_CUSTOM_BUILD_BASE_IMAGE"

// DefaultImageTag is used when an image tag is needed and the configuration does not specify a tag to use.
DefaultImageTag string = "latest"
)

// CustomBuildStrategy defines input parameters specific to Custom build.
type CustomBuildStrategy struct {
// Image is the image required to execute the build. If not specified
Expand All @@ -175,6 +184,11 @@ type DockerBuildStrategy struct {
// NoCache if set to true indicates that the docker build must be executed with the
// --no-cache=true flag
NoCache bool `json:"noCache,omitempty" yaml:"noCache,omitempty"`

// BaseImage is optional and indicates the image that the dockerfile for this
// build should "FROM". If present, the build process will substitute this value
// into the FROM line of the dockerfile.
BaseImage string `json:"baseImage,omitempty" yaml:"baseImage,omitempty"`
}

// STIBuildStrategy defines input parameters specific to an STI build.
Expand Down Expand Up @@ -222,6 +236,20 @@ type WebHookTrigger struct {
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
}

// ImageChangeTrigger allows builds to be triggered when an ImageRepository changes
type ImageChangeTrigger struct {
// Image is used to specify the value in the BuildConfig to replace with the
// immutable image id supplied by the ImageRepository when this trigger fires.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should stick with proper naming, so id -> name, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you referring to the RepositoryName field? i'm maintaining consistency w/ deployments:
https://github.com/openshift/origin/blob/master/pkg/deploy/api/types.go#L153

however the entire field is going to change to be an ObjectRef shortly so i'll consider a name change to just "repository" at that point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have this correct here - refs to foo should be "FooRef" as the field name

Image string `json:"image" yaml:"image"`
// ImageRepositoryRef a reference to a Docker image repository to watch for changes.
ImageRepositoryRef *kapi.ObjectReference `json:"imageRepositoryRef" yaml:"imageRepositoryRef"`
// Tag is the name of an image repository tag to watch for changes.
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
// LastTriggeredImageID is used internally by the ImageChangeController to save last
// used image ID for build
LastTriggeredImageID string `json:"lastTriggeredImageID,omitempty" yaml:"lastTriggeredImageID,omitempty"`
}

// BuildTriggerPolicy describes a policy for a single trigger that results in a new Build.
type BuildTriggerPolicy struct {
// Type is the type of build trigger
Expand All @@ -232,6 +260,9 @@ type BuildTriggerPolicy struct {

// GenericWebHook contains the parameters for a Generic webhook type of trigger
GenericWebHook *WebHookTrigger `json:"generic,omitempty" yaml:"generic,omitempty"`

// ImageChange contains parameters for an ImageChange type of trigger
ImageChange *ImageChangeTrigger `json:"imageChange,omitempty" yaml:"imageChange,omitempty"`
}

// BuildTriggerType refers to a specific BuildTriggerPolicy implementation.
Expand All @@ -240,11 +271,15 @@ type BuildTriggerType string
const (
// GithubWebHookType represents a trigger that launches builds on
// Github webhook invocations
GithubWebHookType BuildTriggerType = "github"
GithubWebHookBuildTriggerType BuildTriggerType = "github"

// GenericWebHookType represents a trigger that launches builds on
// generic webhook invocations
GenericWebHookType BuildTriggerType = "generic"
GenericWebHookBuildTriggerType BuildTriggerType = "generic"

// ImageChangeType represents a trigger that launches builds on
// availability of a new version of an image
ImageChangeBuildTriggerType BuildTriggerType = "imageChange"
)

// BuildList is a collection of Builds.
Expand Down
36 changes: 29 additions & 7 deletions pkg/build/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ type BuildStatus string

// Valid values for BuildStatus.
const (
// BuildNew is automatically assigned to a newly created build.
// BuildStatusNew is automatically assigned to a newly created build.
BuildStatusNew BuildStatus = "New"

// BuildPending indicates that a pod name has been assigned and a build is
// BuildStatusPending indicates that a pod name has been assigned and a build is
// about to start running.
BuildStatusPending BuildStatus = "Pending"

// BuildRunning indicates that a pod has been created and a build is running.
// BuildStatusRunning indicates that a pod has been created and a build is running.
BuildStatusRunning BuildStatus = "Running"

// BuildComplete indicates that a build has been successful.
BuildStatusComplete BuildStatus = "Complete"
// BuildStatusComplete indicates that a build has been successful.

// BuildFailed indicates that a build has executed and failed.
// BuildStatusFailed indicates that a build has executed and failed.
BuildStatusFailed BuildStatus = "Failed"

// BuildError indicates that an error prevented the build from executing.
// BuildStatusError indicates that an error prevented the build from executing.
BuildStatusError BuildStatus = "Error"

// BuildStatusCancelled indicates that a running/pending build was stopped from executing.
Expand All @@ -72,7 +72,7 @@ type BuildSourceType string

// Valid values for BuildSourceType.
const (
//BuildGitSource is a Git SCM
//BuildSourceGit is a Git SCM
BuildSourceGit BuildSourceType = "Git"
)

Expand Down Expand Up @@ -175,6 +175,11 @@ type DockerBuildStrategy struct {
// NoCache if set to true indicates that the docker build must be executed with the
// --no-cache=true flag
NoCache bool `json:"noCache,omitempty" yaml:"noCache,omitempty"`

// BaseImage is optional and indicates the image that the dockerfile for this
// build should "FROM". If present, the build process will substitute this value
// into the FROM line of the dockerfile.
BaseImage string `json:"baseImage,omitempty" yaml:"baseImage,omitempty"`
}

// STIBuildStrategy defines input parameters specific to an STI build.
Expand Down Expand Up @@ -226,6 +231,20 @@ type WebHookTrigger struct {
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
}

// ImageChangeTrigger allows builds to be triggered when an ImageRepository changes
type ImageChangeTrigger struct {
// Image is used to specify the value in the BuildConfig to replace with the
// immutable image id supplied by the ImageRepository when this trigger fires.
Image string `json:"image" yaml:"image"`
// ImageRepositoryRef a reference to a Docker image repository to watch for changes.
ImageRepositoryRef *kapi.ObjectReference `json:"imageRepositoryRef" yaml:"imageRepositoryRef"`
// Tag is the name of an image repository tag to watch for changes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specify what the behavior is if no tag is specified.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to update this, none of these fields are going to be optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If tag isn't optional, we should make it not optional on all APIs. Or is tag not optional in the other places its used?

----- Original Message -----

@@ -223,6 +228,17 @@ type WebHookTrigger struct {
Secret string json:"secret,omitempty" yaml:"secret,omitempty"
}

+// BuildTriggerImageChangeParams represents the parameters to the
ImageChange trigger.
+type ImageChangeTrigger struct {

  • // Image is used to specify the value in the BuildConfig to replace with
    the
  • // immutable image id supplied by the ImageRepository when this trigger
    fires.
  • Image string json:"image,omitempty" yaml:"image,omitempty"
  • // ImageRepositoryRef a reference to a Docker image repository to watch
    for changes.
  • ImageRepositoryRef kapi.ObjectReference
    json:"imageRepositoryRef,omitempty" yaml:"imageRepositoryRef,omitempty"
  • // Tag is the name of an image repository tag to watch for changes.

I need to update this, none of these fields are going to be optional.


Reply to this email directly or view it on GitHub:
https://github.com/openshift/origin/pull/557/files#r22596231

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at all the other use cases, but in this use case, the only way we can make it non-optional is if we default to "latest". i'm fine with doing that if you prefer it, but there's no way to perform image change trigger logic without some tag value to be watching for changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, if deployment is defaulting "" to "latest" we should too. I think there's value in not requiring people to specify it, and some cost for clients to have to deal with it. If you don't default, everyone will pick their own (Git i.e. uses branch master by default, and origin as the remote by default, so everyone deals with it).

----- Original Message -----

@@ -223,6 +228,17 @@ type WebHookTrigger struct {
Secret string json:"secret,omitempty" yaml:"secret,omitempty"
}

+// BuildTriggerImageChangeParams represents the parameters to the
ImageChange trigger.
+type ImageChangeTrigger struct {

  • // Image is used to specify the value in the BuildConfig to replace with
    the
  • // immutable image id supplied by the ImageRepository when this trigger
    fires.
  • Image string json:"image,omitempty" yaml:"image,omitempty"
  • // ImageRepositoryRef a reference to a Docker image repository to watch
    for changes.
  • ImageRepositoryRef kapi.ObjectReference
    json:"imageRepositoryRef,omitempty" yaml:"imageRepositoryRef,omitempty"
  • // Tag is the name of an image repository tag to watch for changes.

I haven't looked at all the other use cases, but in this use case, the only
way we can make it non-optional is if we default to "latest". i'm fine with
doing that if you prefer it, but there's no way to perform image change
trigger logic without some tag value to be watching for changes.


Reply to this email directly or view it on GitHub:
https://github.com/openshift/origin/pull/557/files#r22607360

Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
// LastTriggeredImageID is used internally by the ImageChangeController to save last
// used image ID for build
LastTriggeredImageID string `json:"lastTriggeredImageID,omitempty" yaml:"lastTriggeredImageID,omitempty"`
}

// BuildTriggerPolicy describes a policy for a single trigger that results in a new Build.
type BuildTriggerPolicy struct {
// Type is the type of build trigger
Expand All @@ -236,6 +255,9 @@ type BuildTriggerPolicy struct {

// GenericWebHook contains the parameters for a Generic webhook type of trigger
GenericWebHook *WebHookTrigger `json:"generic,omitempty" yaml:"generic,omitempty"`

// ImageChange contains parameters for an ImageChange type of trigger
ImageChange *ImageChangeTrigger `json:"imageChange,omitempty" yaml:"imageChange,omitempty"`
}

// BuildTriggerType refers to a specific BuildTriggerPolicy implementation.
Expand Down
44 changes: 36 additions & 8 deletions pkg/build/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,18 @@ func validateStrategy(strategy *buildapi.BuildStrategy) errs.ValidationErrorList
allErrs = append(allErrs, validateSTIStrategy(strategy.STIStrategy).Prefix("stiStrategy")...)
}
case buildapi.DockerBuildStrategyType:
// DockerStrategy is currently optional
// DockerStrategy is currently optional, initialize it to a default state if it's not set.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smarterclayton does this address your validation concern?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the other types don't even test for nil

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STI does. Custom does not and should. i'll add that one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added.

if strategy.DockerStrategy == nil {
strategy.DockerStrategy = &buildapi.DockerBuildStrategy{}
}
case buildapi.CustomBuildStrategyType:
// CustomBuildStrategy requires 'image' to be specified in JSON
if len(strategy.CustomStrategy.Image) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("image", strategy.CustomStrategy.Image))
if strategy.CustomStrategy == nil {
allErrs = append(allErrs, errs.NewFieldRequired("customStrategy", strategy.CustomStrategy))
} else {
// CustomBuildStrategy requires 'image' to be specified in JSON
if len(strategy.CustomStrategy.Image) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("image", strategy.CustomStrategy.Image))
}
}
default:
allErrs = append(allErrs, errs.NewFieldInvalid("type", strategy.Type, "type is not in the enumerated list"))
Expand Down Expand Up @@ -138,25 +145,31 @@ func validateTrigger(trigger *buildapi.BuildTriggerPolicy) errs.ValidationErrorL

// Ensure that only parameters for the trigger's type are present
triggerPresence := map[buildapi.BuildTriggerType]bool{
buildapi.GithubWebHookType: trigger.GithubWebHook != nil,
buildapi.GenericWebHookType: trigger.GenericWebHook != nil,
buildapi.GithubWebHookBuildTriggerType: trigger.GithubWebHook != nil,
buildapi.GenericWebHookBuildTriggerType: trigger.GenericWebHook != nil,
}
allErrs = append(allErrs, validateTriggerPresence(triggerPresence, trigger.Type)...)

// Validate each trigger type
switch trigger.Type {
case buildapi.GithubWebHookType:
case buildapi.GithubWebHookBuildTriggerType:
if trigger.GithubWebHook == nil {
allErrs = append(allErrs, errs.NewFieldRequired("github", nil))
} else {
allErrs = append(allErrs, validateWebHook(trigger.GithubWebHook).Prefix("github")...)
}
case buildapi.GenericWebHookType:
case buildapi.GenericWebHookBuildTriggerType:
if trigger.GenericWebHook == nil {
allErrs = append(allErrs, errs.NewFieldRequired("generic", nil))
} else {
allErrs = append(allErrs, validateWebHook(trigger.GenericWebHook).Prefix("generic")...)
}
case buildapi.ImageChangeBuildTriggerType:
if trigger.ImageChange == nil {
allErrs = append(allErrs, errs.NewFieldRequired("imageChange", nil))
} else {
allErrs = append(allErrs, validateImageChange(trigger.ImageChange).Prefix("imageChange")...)
}
}
return allErrs
}
Expand All @@ -171,6 +184,21 @@ func validateTriggerPresence(params map[buildapi.BuildTriggerType]bool, t builda
return allErrs
}

func validateImageChange(imageChange *buildapi.ImageChangeTrigger) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(imageChange.Image) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("image", ""))
}
if imageChange.ImageRepositoryRef == nil {
allErrs = append(allErrs, errs.NewFieldRequired("imageRepositoryRef", ""))
} else if len(imageChange.ImageRepositoryRef.Name) == 0 {
nestedErrs := errs.ValidationErrorList{errs.NewFieldRequired("name", "")}
nestedErrs.Prefix("imageRepositoryRef")
allErrs = append(allErrs, nestedErrs...)
}
return allErrs
}

func validateWebHook(webHook *buildapi.WebHookTrigger) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(webHook.Secret) == 0 {
Expand Down
16 changes: 8 additions & 8 deletions pkg/build/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,39 +204,39 @@ func TestValidateTrigger(t *testing.T) {
expected: []*errs.ValidationError{errs.NewFieldRequired("type", "")},
},
"github type with no github webhook": {
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GithubWebHookType},
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GithubWebHookBuildTriggerType},
expected: []*errs.ValidationError{errs.NewFieldRequired("github", "")},
},
"github trigger with no secret": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GithubWebHookType,
Type: buildapi.GithubWebHookBuildTriggerType,
GithubWebHook: &buildapi.WebHookTrigger{},
},
expected: []*errs.ValidationError{errs.NewFieldRequired("github.secret", "")},
},
"github trigger with generic webhook": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GithubWebHookType,
Type: buildapi.GithubWebHookBuildTriggerType,
GenericWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
},
expected: []*errs.ValidationError{errs.NewFieldInvalid("generic", "", "long description")},
},
"generic trigger with no generic webhook": {
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GenericWebHookType},
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GenericWebHookBuildTriggerType},
expected: []*errs.ValidationError{errs.NewFieldRequired("generic", "")},
},
"generic trigger with no secret": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GenericWebHookType,
Type: buildapi.GenericWebHookBuildTriggerType,
GenericWebHook: &buildapi.WebHookTrigger{},
},
expected: []*errs.ValidationError{errs.NewFieldRequired("generic.secret", "")},
},
"generic trigger with github webhook": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GenericWebHookType,
Type: buildapi.GenericWebHookBuildTriggerType,
GithubWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
Expand All @@ -245,15 +245,15 @@ func TestValidateTrigger(t *testing.T) {
},
"valid github trigger": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GithubWebHookType,
Type: buildapi.GithubWebHookBuildTriggerType,
GithubWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
},
},
"valid generic trigger": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GenericWebHookType,
Type: buildapi.GenericWebHookBuildTriggerType,
GenericWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
Expand Down
Loading