Skip to content

Commit 0459e4a

Browse files
committed
krel: Initial commit of gcbmgr
Signed-off-by: Stephen Augustus <[email protected]>
1 parent 984cfab commit 0459e4a

File tree

6 files changed

+311
-3
lines changed

6 files changed

+311
-3
lines changed

cmd/krel/cmd/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go_library(
55
srcs = [
66
"changelog.go",
77
"ff.go",
8+
"gcbmgr.go",
89
"patch-announce.go",
910
"push.go",
1011
"root.go",
@@ -13,6 +14,7 @@ go_library(
1314
importpath = "k8s.io/release/cmd/krel/cmd",
1415
visibility = ["//visibility:public"],
1516
deps = [
17+
"//pkg/gcp/build:go_default_library",
1618
"//pkg/git:go_default_library",
1719
"//pkg/log:go_default_library",
1820
"//pkg/notes:go_default_library",

cmd/krel/cmd/gcbmgr.go

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cmd
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
"strings"
24+
25+
"github.com/pkg/errors"
26+
"github.com/sirupsen/logrus"
27+
"github.com/spf13/cobra"
28+
29+
"k8s.io/release/pkg/gcp/build"
30+
"k8s.io/release/pkg/release"
31+
"k8s.io/release/pkg/util"
32+
)
33+
34+
type gcbmgrOptions struct {
35+
stage bool
36+
release bool
37+
branch string
38+
releaseType string
39+
buildVersion string
40+
}
41+
42+
var (
43+
gcbmgrOpts = &gcbmgrOptions{}
44+
buildOpts = &build.Options{}
45+
)
46+
47+
const (
48+
// TODO: This should maybe be in pkg/release
49+
defaultReleaseToolRepo = "https://github.com/kubernetes/release"
50+
defaultReleaseToolBranch = "master"
51+
defaultProject = "kubernetes-release-test"
52+
//nolint
53+
defaultDiskSize = "300"
54+
55+
bucketPrefix = "kubernetes-release-"
56+
)
57+
58+
// gcbmgrCmd is the command when calling `krel version`
59+
var gcbmgrCmd = &cobra.Command{
60+
Use: "gcbmgr",
61+
Short: "Run gcbmgr",
62+
SilenceUsage: true,
63+
SilenceErrors: true,
64+
PreRunE: initLogging,
65+
RunE: func(cmd *cobra.Command, args []string) error {
66+
return runGcbmgr()
67+
},
68+
}
69+
70+
func init() {
71+
// Submit types
72+
gcbmgrCmd.PersistentFlags().BoolVar(
73+
&gcbmgrOpts.stage,
74+
"stage",
75+
false,
76+
"Submit a stage run to GCB",
77+
)
78+
gcbmgrCmd.PersistentFlags().BoolVar(
79+
&gcbmgrOpts.release,
80+
"release",
81+
false,
82+
"Submit a release run to GCB",
83+
)
84+
85+
gcbmgrCmd.PersistentFlags().StringVar(
86+
&gcbmgrOpts.branch,
87+
"branch",
88+
"",
89+
"Branch to run the specified GCB run against",
90+
)
91+
92+
// Release types
93+
gcbmgrCmd.PersistentFlags().StringVar(
94+
&gcbmgrOpts.releaseType,
95+
"type",
96+
"prerelease",
97+
"Release type (must be one of: 'prerelease', 'rc', 'official')",
98+
)
99+
100+
// TODO: Remove default once find_green_build logic exists
101+
gcbmgrCmd.PersistentFlags().StringVar(
102+
&gcbmgrOpts.buildVersion,
103+
"build-version",
104+
"FAKE+BUILD+POINT",
105+
"Build version",
106+
)
107+
108+
gcbmgrCmd.PersistentFlags().StringVar(
109+
&buildOpts.Project,
110+
"project",
111+
defaultProject,
112+
"Branch to run the specified GCB run against",
113+
)
114+
115+
rootCmd.AddCommand(gcbmgrCmd)
116+
}
117+
118+
func runGcbmgr() error {
119+
logrus.Infof("Running gcbmgr with the following options: %v", *gcbmgrOpts)
120+
logrus.Infof("Build options: %v", *buildOpts)
121+
122+
buildOpts.NoSource = true
123+
124+
if gcbmgrOpts.stage && gcbmgrOpts.release {
125+
logrus.Fatal("Cannot specify both the 'stage' and 'release' flag. Please resubmit with only one of those flags selected.")
126+
}
127+
128+
gcbSubs, gcbSubsErr := setGCBSubstitutions()
129+
if gcbSubsErr != nil {
130+
return gcbSubsErr
131+
}
132+
133+
if rootOpts.nomock {
134+
_, nomockSubmit, askErr := util.Ask(
135+
"Really submit a --nomock release job against the $RELEASE_BRANCH branch",
136+
"yes",
137+
3,
138+
)
139+
if askErr != nil {
140+
return askErr
141+
}
142+
143+
if nomockSubmit {
144+
gcbSubs["NOMOCK_TAG"] = "nomock"
145+
gcbSubs["NOMOCK"] = fmt.Sprintf("--%s", gcbSubs["NOMOCK_TAG"])
146+
}
147+
} else {
148+
// TODO: Remove once cloudbuild.yaml doesn't strictly require vars to be set.
149+
gcbSubs["NOMOCK_TAG"] = ""
150+
gcbSubs["NOMOCK"] = ""
151+
152+
userBucket := fmt.Sprintf("%s%s", bucketPrefix, gcbSubs["GCP_USER_TAG"])
153+
userBucketSetErr := os.Setenv("USER_BUCKET", userBucket)
154+
if userBucketSetErr != nil {
155+
return userBucketSetErr
156+
}
157+
158+
testBucket := fmt.Sprintf("%s%s", bucketPrefix, "gcb")
159+
testBucketSetErr := os.Setenv("BUCKET", testBucket)
160+
if testBucketSetErr != nil {
161+
return testBucketSetErr
162+
}
163+
}
164+
165+
toolRoot, err := os.Getwd()
166+
if err != nil {
167+
return err
168+
}
169+
170+
switch {
171+
case gcbmgrOpts.stage:
172+
return submitStage(toolRoot, gcbSubs)
173+
case gcbmgrOpts.release:
174+
return submitRelease()
175+
default:
176+
return listJobs()
177+
}
178+
}
179+
180+
func submitStage(toolRoot string, substitutions map[string]string) error {
181+
logrus.Infof("Submitting a stage to GCB")
182+
183+
buildOpts.CloudbuildFile = filepath.Join(toolRoot, "gcb/stage/cloudbuild.yaml")
184+
185+
// TODO: Need actual values
186+
var jobName, uploaded string
187+
version := "FAKEVERSION"
188+
189+
return build.RunSingleJob(buildOpts, jobName, uploaded, version, substitutions)
190+
}
191+
192+
func submitRelease() error {
193+
logrus.Infof("Submitting a release to GCB")
194+
//nolint:gocritic
195+
return nil // build.RunSingleJob(buildOpts, jobName, uploaded, version, subs)
196+
}
197+
198+
func setGCBSubstitutions() (map[string]string, error) {
199+
gcbSubs := make(map[string]string)
200+
201+
releaseToolRepo := os.Getenv("RELEASE_TOOL_REPO")
202+
if releaseToolRepo == "" {
203+
releaseToolRepo = defaultReleaseToolRepo
204+
}
205+
206+
releaseToolBranch := os.Getenv("RELEASE_TOOL_BRANCH")
207+
if releaseToolBranch == "" {
208+
releaseToolBranch = defaultReleaseToolBranch
209+
}
210+
211+
gcbSubs["RELEASE_TOOL_REPO"] = releaseToolRepo
212+
gcbSubs["RELEASE_TOOL_BRANCH"] = releaseToolBranch
213+
214+
// TODO: Need to find out if command.Execute supports capturing the command output
215+
gcpUser := "FAKEUSER"
216+
//nolint
217+
/*
218+
gcpUser := command.Execute(
219+
"gcloud",
220+
"auth",
221+
"list",
222+
"--filter=status:ACTIVE",
223+
`--format="value(account)"`,
224+
)
225+
if gcpUser != nil {
226+
return nil, gcpUserErr
227+
}
228+
*/
229+
230+
gcpUser = strings.ReplaceAll(gcpUser, "@", "-at-")
231+
gcpUser = strings.ReplaceAll(gcpUser, ".", "-")
232+
gcbSubs["GCP_USER_TAG"] = gcpUser
233+
234+
// TODO: The naming for these env vars is clumsy/confusing, but we're bound by anago right now.
235+
releaseType := gcbmgrOpts.releaseType
236+
switch releaseType {
237+
case "official":
238+
gcbSubs["OFFICIAL_TAG"] = releaseType
239+
gcbSubs["OFFICIAL"] = fmt.Sprintf("--%s", releaseType)
240+
241+
// TODO: Remove once cloudbuild.yaml doesn't strictly require vars to be set.
242+
gcbSubs["RC_TAG"] = ""
243+
gcbSubs["RC"] = ""
244+
case "rc":
245+
gcbSubs["RC_TAG"] = releaseType
246+
gcbSubs["RC"] = fmt.Sprintf("--%s", releaseType)
247+
248+
// TODO: Remove once cloudbuild.yaml doesn't strictly require vars to be set.
249+
gcbSubs["OFFICIAL_TAG"] = ""
250+
gcbSubs["OFFICIAL"] = ""
251+
case "prerelease":
252+
// TODO: Remove once cloudbuild.yaml doesn't strictly require vars to be set.
253+
gcbSubs["OFFICIAL_TAG"] = ""
254+
gcbSubs["OFFICIAL"] = ""
255+
gcbSubs["RC_TAG"] = ""
256+
gcbSubs["RC"] = ""
257+
}
258+
259+
// TODO: Remove once we remove support for --built-at-head.
260+
gcbSubs["BUILD_AT_HEAD"] = ""
261+
262+
buildpoint := gcbmgrOpts.buildVersion
263+
buildpoint = strings.ReplaceAll(buildpoint, "+", "-")
264+
gcbSubs["BUILD_POINT"] = buildpoint
265+
266+
buildVersion := gcbmgrOpts.buildVersion
267+
gcbSubs["BUILDVERSION"] = buildVersion
268+
269+
if gcbmgrOpts.branch != "" {
270+
gcbSubs["RELEASE_BRANCH"] = gcbmgrOpts.branch
271+
} else {
272+
return nil, errors.New("Release branch must be set to continue")
273+
}
274+
275+
gcbSubs["KUBE_CROSS_VERSION"] = release.GetKubecrossVersion()
276+
277+
// TODO: Need actual values
278+
279+
return gcbSubs, nil
280+
}
281+
282+
func listJobs() error {
283+
logrus.Info("Listing GCB jobs is not currently supported.")
284+
285+
// TODO: Add job listing logic
286+
// logrus.Info("Listing recent GCB jobs...")
287+
return nil
288+
}

gcb/release/cloudbuild.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ tags:
6262
- ${_OFFICIAL_TAG}
6363
- ${_RC_TAG}
6464
- RELEASE
65+
- ${_GIT_TAG}
6566

6667
options:
6768
machineType: N1_HIGHCPU_32
69+
70+
substitutions:
71+
# _GIT_TAG will be filled with a git-based tag of the form vYYYYMMDD-hash, and
72+
# can be used as a substitution
73+
_GIT_TAG: '12345'

gcb/stage/cloudbuild.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ tags:
106106
- ${_OFFICIAL_TAG}
107107
- ${_RC_TAG}
108108
- STAGE
109+
- ${_GIT_TAG}
109110

110111
options:
111112
machineType: N1_HIGHCPU_32
113+
114+
substitutions:
115+
# _GIT_TAG will be filled with a git-based tag of the form vYYYYMMDD-hash, and
116+
# can be used as a substitution
117+
_GIT_TAG: '12345'

pkg/gcp/build/build.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func getExtraSubs(o *Options) map[string]string {
123123
return subs
124124
}
125125

126-
func runSingleJob(o *Options, jobName, uploaded, version string, subs map[string]string) error {
126+
func RunSingleJob(o *Options, jobName, uploaded, version string, subs map[string]string) error {
127127
s := make([]string, 0, len(subs)+1)
128128
for k, v := range subs {
129129
s = append(s, fmt.Sprintf("_%s=%s", k, v))
@@ -246,7 +246,7 @@ func RunBuildJobs(o *Options) []error {
246246
}
247247
if len(vs) == 0 {
248248
log.Println("No variants.yaml, starting single build job...")
249-
if err := runSingleJob(o, "build", uploaded, tag, getExtraSubs(o)); err != nil {
249+
if err := RunSingleJob(o, "build", uploaded, tag, getExtraSubs(o)); err != nil {
250250
return []error{err}
251251
}
252252
return nil
@@ -262,7 +262,7 @@ func RunBuildJobs(o *Options) []error {
262262
go func(job string, vc map[string]string) {
263263
defer w.Done()
264264
log.Printf("Starting job %q...\n", job)
265-
if err := runSingleJob(o, job, uploaded, tag, mergeMaps(extraSubs, vc)); err != nil {
265+
if err := RunSingleJob(o, job, uploaded, tag, mergeMaps(extraSubs, vc)); err != nil {
266266
errors = append(errors, fmt.Errorf("job %q failed: %v", job, err))
267267
log.Printf("Job %q failed: %v\n", job, err)
268268
} else {

pkg/release/release.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@ func IsValidReleaseBuild(build string) (bool, error) {
7272
func IsDirtyBuild(build string) bool {
7373
return strings.Contains(build, "dirty")
7474
}
75+
76+
// GetKubecrossVersion returns the current kube-cross container version.
77+
func GetKubecrossVersion() string {
78+
// TODO: Remove hardcoded version
79+
return "v1.13.6-1"
80+
}

0 commit comments

Comments
 (0)