Skip to content

Commit af5bf7d

Browse files
committed
images/builder: Allow GCB builds from arbitrary build directories
- Remove cdToRootDir This function was not actually cd-ing into directories - Add --build-dir flag to support builds that require the entire repo/workspace to be uploaded to GCB - Add a validation method to ensure config directory and cloudbuild.yaml exist before submitting build Signed-off-by: Stephen Augustus <saugustus@vmware.com>
1 parent 301883e commit af5bf7d

File tree

1 file changed

+56
-21
lines changed

1 file changed

+56
-21
lines changed

images/builder/main.go

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,26 @@ func getVersion() (string, error) {
5454
return fmt.Sprintf("v%s-%s", t, strings.TrimSpace(string(output))), nil
5555
}
5656

57-
func cdToRootDir() error {
58-
if bazelWorkspace := os.Getenv("BUILD_WORKSPACE_DIRECTORY"); bazelWorkspace != "" {
59-
if err := os.Chdir(bazelWorkspace); err != nil {
60-
return fmt.Errorf("failed to chdir to bazel workspace (%s): %v", bazelWorkspace, err)
61-
}
57+
func (o *options) validateConfigDir() error {
58+
configDir := o.configDir
59+
dirInfo, err := os.Stat(o.configDir)
60+
if os.IsNotExist(err) {
61+
log.Fatalf("Config directory (%s) does not exist", configDir)
6262
}
63-
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
64-
output, err := cmd.Output()
65-
if err != nil {
66-
return err
63+
64+
if !dirInfo.IsDir() {
65+
log.Fatalf("Config directory (%s) is not actually a directory", configDir)
6766
}
68-
return os.Chdir(strings.TrimSpace(string(output)))
67+
68+
_, err = os.Stat(path.Join(configDir, o.cloudbuildFile))
69+
if os.IsNotExist(err) {
70+
log.Fatalf("%s does not exist", o.cloudbuildFile)
71+
}
72+
73+
return nil
6974
}
7075

71-
func uploadWorkingDir(targetBucket string) (string, error) {
76+
func (o *options) uploadBuildDir(targetBucket string) (string, error) {
7277
f, err := ioutil.TempFile("", "")
7378
if err != nil {
7479
return "", fmt.Errorf("failed to create temp file: %v", err)
@@ -112,7 +117,7 @@ func runSingleJob(o options, jobName, uploaded, version string, subs map[string]
112117
s = append(s, "_GIT_TAG="+version)
113118
args := []string{
114119
"builds", "submit",
115-
"--config", path.Join(o.imageDirectory, "cloudbuild.yaml"),
120+
"--config", o.cloudbuildFile,
116121
"--substitutions", strings.Join(s, ","),
117122
}
118123
if o.project != "" {
@@ -153,7 +158,7 @@ func runSingleJob(o options, jobName, uploaded, version string, subs map[string]
153158
type variants map[string]map[string]string
154159

155160
func getVariants(o options) (variants, error) {
156-
content, err := ioutil.ReadFile(path.Join(o.imageDirectory, "variants.yaml"))
161+
content, err := ioutil.ReadFile("variants.yaml")
157162
if err != nil {
158163
if !os.IsNotExist(err) {
159164
return nil, fmt.Errorf("failed to load variants.yaml: %v", err)
@@ -183,7 +188,7 @@ func runBuildJobs(o options) []error {
183188
var uploaded string
184189
if o.scratchBucket != "" {
185190
var err error
186-
uploaded, err = uploadWorkingDir(o.scratchBucket + gcsSourceDir)
191+
uploaded, err = o.uploadBuildDir(o.scratchBucket + gcsSourceDir)
187192
if err != nil {
188193
return []error{fmt.Errorf("failed to upload source: %v", err)}
189194
}
@@ -236,9 +241,11 @@ func runBuildJobs(o options) []error {
236241
}
237242

238243
type options struct {
244+
buildDir string
245+
configDir string
246+
cloudbuildFile string
239247
logDir string
240248
scratchBucket string
241-
imageDirectory string
242249
project string
243250
allowDirty bool
244251
variant string
@@ -257,30 +264,58 @@ func mergeMaps(maps ...map[string]string) map[string]string {
257264

258265
func parseFlags() options {
259266
o := options{}
267+
flag.StringVar(&o.buildDir, "build-dir", "", "If provided, this directory will be uploaded as the source for the Google Cloud Build run.")
268+
flag.StringVar(&o.cloudbuildFile, "gcb-config", "cloudbuild.yaml", "If provided, this will be used as the name of the Google Cloud Build config file.")
260269
flag.StringVar(&o.logDir, "log-dir", "", "If provided, build logs will be sent to files in this directory instead of to stdout/stderr.")
261270
flag.StringVar(&o.scratchBucket, "scratch-bucket", "", "The complete GCS path for Cloud Build to store scratch files (sources, logs).")
262271
flag.StringVar(&o.project, "project", "", "If specified, use a non-default GCP project.")
263272
flag.BoolVar(&o.allowDirty, "allow-dirty", false, "If true, allow pushing dirty builds.")
264273
flag.StringVar(&o.variant, "variant", "", "If specified, build only the given variant. An error if no variants are defined.")
265-
flag.StringVar(&o.envPassthrough, "env-passthrough", "", "Comma-separated list of specified environment variables to be passed to GCB as subtitutions with an _ prefix. If the variable doesn't exist, the substitution will exist but be empty.")
274+
flag.StringVar(&o.envPassthrough, "env-passthrough", "", "Comma-separated list of specified environment variables to be passed to GCB as substitutions with an _ prefix. If the variable doesn't exist, the substitution will exist but be empty.")
275+
266276
flag.Parse()
277+
267278
if flag.NArg() < 1 {
268-
_, _ = fmt.Fprintln(os.Stderr, "expected an image directory to be provided")
279+
_, _ = fmt.Fprintln(os.Stderr, "expected a config directory to be provided")
269280
os.Exit(1)
270281
}
271-
o.imageDirectory = flag.Arg(0)
282+
283+
o.configDir = strings.TrimSuffix(flag.Arg(0), "/")
284+
272285
return o
273286
}
274287

275288
func main() {
276289
o := parseFlags()
277-
if err := cdToRootDir(); err != nil {
278-
log.Fatalf("Failed to cd to root: %v\n", err)
290+
291+
if bazelWorkspace := os.Getenv("BUILD_WORKSPACE_DIRECTORY"); bazelWorkspace != "" {
292+
if err := os.Chdir(bazelWorkspace); err != nil {
293+
log.Fatalf("Failed to chdir to bazel workspace (%s): %v", bazelWorkspace, err)
294+
}
295+
}
296+
297+
configDirErr := o.validateConfigDir()
298+
if configDirErr != nil {
299+
log.Fatalf("Could not validate config directory: %v", configDirErr)
300+
}
301+
302+
if o.buildDir != "" {
303+
o.cloudbuildFile = path.Join(o.configDir, o.cloudbuildFile)
304+
} else {
305+
o.buildDir = o.configDir
306+
}
307+
308+
log.Printf("Build directory: %s\n", o.buildDir)
309+
log.Printf("Config directory: %s\n", o.configDir)
310+
311+
log.Printf("cd-ing to build directory: %s\n", o.buildDir)
312+
if err := os.Chdir(o.buildDir); err != nil {
313+
log.Fatalf("Failed to chdir to build directory (%s): %v", o.buildDir, err)
279314
}
280315

281316
errors := runBuildJobs(o)
282317
if len(errors) != 0 {
283-
log.Fatalf("Failed to push some images: %v", errors)
318+
log.Fatalf("Failed to run some build jobs: %v", errors)
284319
}
285320
log.Println("Finished.")
286321
}

0 commit comments

Comments
 (0)