Skip to content

Commit

Permalink
move builder image code to v1 apis
Browse files Browse the repository at this point in the history
  • Loading branch information
bparees committed Jan 3, 2018
1 parent b27d4b4 commit 66c9d91
Show file tree
Hide file tree
Showing 17 changed files with 347 additions and 310 deletions.
3 changes: 1 addition & 2 deletions hack/import-restrictions.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@
"allowedImportPackages": [
"vendor/k8s.io/kubernetes/pkg/apis/core",
"vendor/k8s.io/kubernetes/pkg/apis/core/v1",
"github.com/openshift/origin/pkg/image/apis/image",
"vendor/github.com/golang/glog"
"github.com/openshift/origin/pkg/image/apis/image"
]
},

Expand Down
54 changes: 0 additions & 54 deletions pkg/build/apis/build/helpers.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package build

import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kapi "k8s.io/kubernetes/pkg/apis/core"

"github.com/golang/glog"
)

// BuildToPodLogOptions builds a PodLogOptions object out of a BuildLogOptions.
Expand Down Expand Up @@ -81,55 +76,6 @@ func HasTriggerType(triggerType BuildTriggerType, bc *BuildConfig) bool {
return len(matches) > 0
}

// RecordStageAndStepInfo records details about each build stage and step
func RecordStageAndStepInfo(stages []StageInfo, stageName StageName, stepName StepName, startTime metav1.Time, endTime metav1.Time) []StageInfo {
// If the stage already exists in the slice, update the DurationMilliseconds, and append the new step.
for stageKey, stageVal := range stages {
if stageVal.Name == stageName {
for _, step := range stages[stageKey].Steps {
if step.Name == stepName {
glog.V(4).Infof("error recording build timing information, step %v already exists in stage %v", stepName, stageName)
}
}
stages[stageKey].DurationMilliseconds = endTime.Time.Sub(stages[stageKey].StartTime.Time).Nanoseconds() / int64(time.Millisecond)
if len(stages[stageKey].Steps) == 0 {
stages[stageKey].Steps = make([]StepInfo, 0)
}
stages[stageKey].Steps = append(stages[stageKey].Steps, StepInfo{
Name: stepName,
StartTime: startTime,
DurationMilliseconds: endTime.Time.Sub(startTime.Time).Nanoseconds() / int64(time.Millisecond),
})
return stages
}
}

// If the stageName does not exist, add it to the slice along with the new step.
var steps []StepInfo
steps = append(steps, StepInfo{
Name: stepName,
StartTime: startTime,
DurationMilliseconds: endTime.Time.Sub(startTime.Time).Nanoseconds() / int64(time.Millisecond),
})
stages = append(stages, StageInfo{
Name: stageName,
StartTime: startTime,
DurationMilliseconds: endTime.Time.Sub(startTime.Time).Nanoseconds() / int64(time.Millisecond),
Steps: steps,
})
return stages
}

// AppendStageAndStepInfo appends the step info from one stages slice into another.
func AppendStageAndStepInfo(stages []StageInfo, stagesToMerge []StageInfo) []StageInfo {
for _, stage := range stagesToMerge {
for _, step := range stage.Steps {
stages = RecordStageAndStepInfo(stages, stage.Name, step.Name, step.StartTime, metav1.NewTime(step.StartTime.Add(time.Duration(step.DurationMilliseconds)*time.Millisecond)))
}
}
return stages
}

// GetInputReference returns the From ObjectReference associated with the
// BuildStrategy.
func GetInputReference(strategy BuildStrategy) *kapi.ObjectReference {
Expand Down
57 changes: 26 additions & 31 deletions pkg/build/builder/cmd/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,34 @@ import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api/legacyscheme"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
restclient "k8s.io/client-go/rest"

s2iapi "github.com/openshift/source-to-image/pkg/api"
s2igit "github.com/openshift/source-to-image/pkg/scm/git"

buildapi "github.com/openshift/origin/pkg/build/apis/build"
"github.com/openshift/origin/pkg/build/apis/build/validation"
buildapiv1 "github.com/openshift/api/build/v1"
buildclientv1 "github.com/openshift/client-go/build/clientset/versioned/typed/build/v1"
bld "github.com/openshift/origin/pkg/build/builder"
"github.com/openshift/origin/pkg/build/builder/cmd/scmauth"
"github.com/openshift/origin/pkg/build/builder/timing"
buildclient "github.com/openshift/origin/pkg/build/generated/internalclientset"
buildinternalversion "github.com/openshift/origin/pkg/build/generated/internalclientset/typed/build/internalversion"
builderutil "github.com/openshift/origin/pkg/build/builder/util"
buildutil "github.com/openshift/origin/pkg/build/util"
"github.com/openshift/origin/pkg/generate/git"
"github.com/openshift/origin/pkg/version"
)

type builder interface {
Build(dockerClient bld.DockerClient, sock string, buildsClient buildinternalversion.BuildResourceInterface, build *buildapi.Build, cgLimits *s2iapi.CGroupLimits) error
Build(dockerClient bld.DockerClient, sock string, buildsClient buildclientv1.BuildInterface, build *buildapiv1.Build, cgLimits *s2iapi.CGroupLimits) error
}

type builderConfig struct {
out io.Writer
build *buildapi.Build
build *buildapiv1.Build
sourceSecretDir string
dockerClient *docker.Client
dockerEndpoint string
buildsClient buildinternalversion.BuildResourceInterface
buildsClient buildclientv1.BuildInterface
}

func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderConfig, error) {
Expand All @@ -51,16 +48,17 @@ func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderC
cfg.out = out

buildStr := os.Getenv("BUILD")
cfg.build = &buildapi.Build{}

obj, groupVersionKind, err := legacyscheme.Codecs.UniversalDecoder().Decode([]byte(buildStr), nil, nil)
cfg.build = &buildapiv1.Build{}

obj, groupVersionKind, err := legacyscheme.Codecs.UniversalDecoder().Decode([]byte(buildStr), nil, cfg.build)
if err != nil {
return nil, fmt.Errorf("unable to parse build string: %v", err)
}
ok := false
cfg.build, ok = obj.(*buildapi.Build)
cfg.build, ok = obj.(*buildapiv1.Build)
if !ok {
return nil, fmt.Errorf("build string is not a build: %v", err)
return nil, fmt.Errorf("build string %s is not a build: %#v", buildStr, obj)
}
if glog.V(4) {
redactedBuild := buildutil.SafeForLoggingBuild(cfg.build)
Expand All @@ -73,11 +71,8 @@ func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderC
}
glog.V(4).Infof("redacted build: %v", string(bytes))
}
if errs := validation.ValidateBuild(cfg.build); len(errs) > 0 {
return nil, errors.NewInvalid(schema.GroupKind{Kind: "Build"}, cfg.build.Name, errs)
}

masterVersion := os.Getenv(buildapi.OriginVersion)
masterVersion := os.Getenv(builderutil.OriginVersion)
thisVersion := version.Get().String()
if len(masterVersion) != 0 && masterVersion != thisVersion {
glog.V(3).Infof("warning: OpenShift server version %q differs from this image %q\n", masterVersion, thisVersion)
Expand All @@ -102,11 +97,11 @@ func newBuilderConfigFromEnvironment(out io.Writer, needsDocker bool) (*builderC
if err != nil {
return nil, fmt.Errorf("cannot connect to the server: %v", err)
}
buildsClient, err := buildclient.NewForConfig(clientConfig)
buildsClient, err := buildclientv1.NewForConfig(clientConfig)
if err != nil {
return nil, fmt.Errorf("failed to get client: %v", err)
}
cfg.buildsClient = buildsClient.Build().Builds(cfg.build.Namespace)
cfg.buildsClient = buildsClient.Builds(cfg.build.Namespace)

return cfg, nil
}
Expand Down Expand Up @@ -158,7 +153,7 @@ func (c *builderConfig) setupGitEnvironment() (string, []string, error) {
// clone is responsible for cloning the source referenced in the buildconfig
func (c *builderConfig) clone() error {
ctx := timing.NewContext(context.Background())
var sourceRev *buildapi.SourceRevision
var sourceRev *buildapiv1.SourceRevision
defer func() {
c.build.Status.Stages = timing.GetStages(ctx)
bld.HandleBuildStatusUpdate(c.build, c.buildsClient, sourceRev)
Expand All @@ -174,9 +169,9 @@ func (c *builderConfig) clone() error {
buildDir := buildutil.InputContentPath
sourceInfo, err := bld.GitClone(ctx, gitClient, c.build.Spec.Source.Git, c.build.Spec.Revision, buildDir)
if err != nil {
c.build.Status.Phase = buildapi.BuildPhaseFailed
c.build.Status.Reason = buildapi.StatusReasonFetchSourceFailed
c.build.Status.Message = buildapi.StatusMessageFetchSourceFailed
c.build.Status.Phase = buildapiv1.BuildPhaseFailed
c.build.Status.Reason = buildapiv1.StatusReasonFetchSourceFailed
c.build.Status.Message = builderutil.StatusMessageFetchSourceFailed
return err
}

Expand All @@ -186,18 +181,18 @@ func (c *builderConfig) clone() error {

err = bld.ExtractInputBinary(os.Stdin, c.build.Spec.Source.Binary, buildDir)
if err != nil {
c.build.Status.Phase = buildapi.BuildPhaseFailed
c.build.Status.Reason = buildapi.StatusReasonFetchSourceFailed
c.build.Status.Message = buildapi.StatusMessageFetchSourceFailed
c.build.Status.Phase = buildapiv1.BuildPhaseFailed
c.build.Status.Reason = buildapiv1.StatusReasonFetchSourceFailed
c.build.Status.Message = builderutil.StatusMessageFetchSourceFailed
return err
}

if len(c.build.Spec.Source.ContextDir) > 0 {
if _, err := os.Stat(filepath.Join(buildDir, c.build.Spec.Source.ContextDir)); os.IsNotExist(err) {
err = fmt.Errorf("provided context directory does not exist: %s", c.build.Spec.Source.ContextDir)
c.build.Status.Phase = buildapi.BuildPhaseFailed
c.build.Status.Reason = buildapi.StatusReasonInvalidContextDirectory
c.build.Status.Message = buildapi.StatusMessageInvalidContextDirectory
c.build.Status.Phase = buildapiv1.BuildPhaseFailed
c.build.Status.Reason = buildapiv1.StatusReasonInvalidContextDirectory
c.build.Status.Message = builderutil.StatusMessageInvalidContextDirectory
return err
}
}
Expand Down Expand Up @@ -238,14 +233,14 @@ func (c *builderConfig) execute(b builder) error {
type dockerBuilder struct{}

// Build starts a Docker build.
func (dockerBuilder) Build(dockerClient bld.DockerClient, sock string, buildsClient buildinternalversion.BuildResourceInterface, build *buildapi.Build, cgLimits *s2iapi.CGroupLimits) error {
func (dockerBuilder) Build(dockerClient bld.DockerClient, sock string, buildsClient buildclientv1.BuildInterface, build *buildapiv1.Build, cgLimits *s2iapi.CGroupLimits) error {
return bld.NewDockerBuilder(dockerClient, buildsClient, build, cgLimits).Build()
}

type s2iBuilder struct{}

// Build starts an S2I build.
func (s2iBuilder) Build(dockerClient bld.DockerClient, sock string, buildsClient buildinternalversion.BuildResourceInterface, build *buildapi.Build, cgLimits *s2iapi.CGroupLimits) error {
func (s2iBuilder) Build(dockerClient bld.DockerClient, sock string, buildsClient buildclientv1.BuildInterface, build *buildapiv1.Build, cgLimits *s2iapi.CGroupLimits) error {
return bld.NewS2IBuilder(dockerClient, sock, buildsClient, build, cgLimits).Build()
}

Expand Down
35 changes: 18 additions & 17 deletions pkg/build/builder/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ import (
s2igit "github.com/openshift/source-to-image/pkg/scm/git"
"github.com/openshift/source-to-image/pkg/util"

buildapi "github.com/openshift/origin/pkg/build/apis/build"
buildapiv1 "github.com/openshift/api/build/v1"
"github.com/openshift/origin/pkg/build/builder/timing"
builderutil "github.com/openshift/origin/pkg/build/builder/util"
"github.com/openshift/origin/pkg/build/builder/util/dockerfile"
buildutil "github.com/openshift/origin/pkg/build/util"
"github.com/openshift/origin/pkg/generate/git"
imageapi "github.com/openshift/origin/pkg/image/apis/image"
utilglog "github.com/openshift/origin/pkg/util/glog"

buildinternalversion "github.com/openshift/origin/pkg/build/generated/internalclientset/typed/build/internalversion"
buildclientv1 "github.com/openshift/client-go/build/clientset/versioned/typed/build/v1"
)

// glog is a placeholder until the builders pass an output stream down
Expand Down Expand Up @@ -62,7 +63,7 @@ type GitClient interface {

// buildInfo returns a slice of KeyValue pairs with build metadata to be
// inserted into Docker images produced by build.
func buildInfo(build *buildapi.Build, sourceInfo *git.SourceInfo) []KeyValue {
func buildInfo(build *buildapiv1.Build, sourceInfo *git.SourceInfo) []KeyValue {
kv := []KeyValue{
{"OPENSHIFT_BUILD_NAME", build.Name},
{"OPENSHIFT_BUILD_NAMESPACE", build.Namespace},
Expand Down Expand Up @@ -118,7 +119,7 @@ func containerName(strategyName, buildName, namespace, containerPurpose string)
// postCommitSpec in a new ephemeral Docker container running the given image.
// It returns an error if the hook cannot be run or returns a non-zero exit
// code.
func execPostCommitHook(ctx context.Context, client DockerClient, postCommitSpec buildapi.BuildPostCommitSpec, image, containerName string) error {
func execPostCommitHook(ctx context.Context, client DockerClient, postCommitSpec buildapiv1.BuildPostCommitSpec, image, containerName string) error {
command := postCommitSpec.Command
args := postCommitSpec.Args
script := postCommitSpec.Script
Expand Down Expand Up @@ -174,26 +175,26 @@ func execPostCommitHook(ctx context.Context, client DockerClient, postCommitSpec
Stdout: true,
Stderr: true,
})
timing.RecordNewStep(ctx, buildapi.StagePostCommit, buildapi.StepExecPostCommitHook, startTime, metav1.Now())
timing.RecordNewStep(ctx, buildapiv1.StagePostCommit, buildapiv1.StepExecPostCommitHook, startTime, metav1.Now())

return err
}

// GetSourceRevision returns a SourceRevision object either from the build (if it already had one)
// or by creating one from the sourceInfo object passed in.
func GetSourceRevision(build *buildapi.Build, sourceInfo *git.SourceInfo) *buildapi.SourceRevision {
func GetSourceRevision(build *buildapiv1.Build, sourceInfo *git.SourceInfo) *buildapiv1.SourceRevision {
if build.Spec.Revision != nil {
return build.Spec.Revision
}
return &buildapi.SourceRevision{
Git: &buildapi.GitSourceRevision{
return &buildapiv1.SourceRevision{
Git: &buildapiv1.GitSourceRevision{
Commit: sourceInfo.CommitID,
Message: sourceInfo.Message,
Author: buildapi.SourceControlUser{
Author: buildapiv1.SourceControlUser{
Name: sourceInfo.AuthorName,
Email: sourceInfo.AuthorEmail,
},
Committer: buildapi.SourceControlUser{
Committer: buildapiv1.SourceControlUser{
Name: sourceInfo.CommitterName,
Email: sourceInfo.CommitterEmail,
},
Expand All @@ -203,8 +204,8 @@ func GetSourceRevision(build *buildapi.Build, sourceInfo *git.SourceInfo) *build

// HandleBuildStatusUpdate handles updating the build status
// retries occur on update conflict and unreachable api server
func HandleBuildStatusUpdate(build *buildapi.Build, client buildinternalversion.BuildResourceInterface, sourceRev *buildapi.SourceRevision) {
var latestBuild *buildapi.Build
func HandleBuildStatusUpdate(build *buildapiv1.Build, client buildclientv1.BuildInterface, sourceRev *buildapiv1.SourceRevision) {
var latestBuild *buildapiv1.Build
var err error

updateBackoff := wait.Backoff{
Expand All @@ -231,7 +232,7 @@ func HandleBuildStatusUpdate(build *buildapi.Build, client buildinternalversion.
latestBuild.Status.Reason = build.Status.Reason
latestBuild.Status.Message = build.Status.Message
latestBuild.Status.Output.To = build.Status.Output.To
latestBuild.Status.Stages = buildapi.AppendStageAndStepInfo(latestBuild.Status.Stages, build.Status.Stages)
latestBuild.Status.Stages = timing.AppendStageAndStepInfo(latestBuild.Status.Stages, build.Status.Stages)

_, err = client.UpdateDetails(latestBuild.Name, latestBuild)

Expand All @@ -255,7 +256,7 @@ func HandleBuildStatusUpdate(build *buildapi.Build, client buildinternalversion.

// buildEnv converts the buildInfo output to a format that appendEnv can
// consume.
func buildEnv(build *buildapi.Build, sourceInfo *git.SourceInfo) []dockerfile.KeyValue {
func buildEnv(build *buildapiv1.Build, sourceInfo *git.SourceInfo) []dockerfile.KeyValue {
bi := buildInfo(build, sourceInfo)
kv := make([]dockerfile.KeyValue, len(bi))
for i, item := range bi {
Expand All @@ -282,15 +283,15 @@ func toS2ISourceInfo(sourceInfo *git.SourceInfo) *s2igit.SourceInfo {

// buildLabels returns a slice of KeyValue pairs in a format that appendLabel can
// consume.
func buildLabels(build *buildapi.Build, sourceInfo *git.SourceInfo) []dockerfile.KeyValue {
func buildLabels(build *buildapiv1.Build, sourceInfo *git.SourceInfo) []dockerfile.KeyValue {
labels := map[string]string{}
if sourceInfo == nil {
sourceInfo = &git.SourceInfo{}
}
if len(build.Spec.Source.ContextDir) > 0 {
sourceInfo.ContextDir = build.Spec.Source.ContextDir
}
labels = util.GenerateLabelsFromSourceInfo(labels, toS2ISourceInfo(sourceInfo), buildapi.DefaultDockerLabelNamespace)
labels = util.GenerateLabelsFromSourceInfo(labels, toS2ISourceInfo(sourceInfo), builderutil.DefaultDockerLabelNamespace)
addBuildLabels(labels, build)

kv := make([]dockerfile.KeyValue, 0, len(labels)+len(build.Spec.Output.ImageLabels))
Expand Down Expand Up @@ -329,7 +330,7 @@ func readSourceInfo() (*git.SourceInfo, error) {
// addBuildParameters checks if a Image is set to replace the default base image.
// If that's the case then change the Dockerfile to make the build with the given image.
// Also append the environment variables and labels in the Dockerfile.
func addBuildParameters(dir string, build *buildapi.Build, sourceInfo *git.SourceInfo) error {
func addBuildParameters(dir string, build *buildapiv1.Build, sourceInfo *git.SourceInfo) error {
dockerfilePath := getDockerfilePath(dir, build)
node, err := parseDockerfile(dockerfilePath)
if err != nil {
Expand Down
Loading

0 comments on commit 66c9d91

Please sign in to comment.