in cli_tools/gce_image_publish/main.go [105:241]
func main() {
addFlags(os.Args[1:])
flag.Parse()
varMap := map[string]string{}
flag.Visit(func(flg *flag.Flag) {
if strings.HasPrefix(flg.Name, varFlagPrefix) {
varMap[strings.TrimPrefix(flg.Name, varFlagPrefix)] = flg.Value.String()
}
})
if *rolloutRate < 0 {
fmt.Println("-rollout_rate cannot be less than 0.")
os.Exit(1)
}
if *skipDup && *replace {
fmt.Println("Cannot set both -skip_duplicates and -replace")
os.Exit(1)
}
if *dateVersion && *publishVersion != "" {
fmt.Println("Cannot set both -date_version and -publish_version")
os.Exit(1)
}
if len(flag.Args()) == 0 {
fmt.Println("Not enough args, first arg needs to be the path to a publish template.")
os.Exit(1)
}
if *dateVersion {
*publishVersion = "v" + time.Now().UTC().Format("20060102")
}
var regex *regexp.Regexp
if *filter != "" {
var err error
regex, err = regexp.Compile(*filter)
if err != nil {
fmt.Println("-filter flag not valid:", err)
os.Exit(1)
}
}
ctx := context.Background()
var errs []error
var ws []*daisy.Workflow
imagesCache := map[string][]*computeAlpha.Image{}
for _, path := range flag.Args() {
p, err := publish.CreatePublish(
*sourceVersion, *publishVersion, *workProject, *publishProject, *sourceGCS, *sourceProject, *ce, path, varMap, imagesCache)
if err != nil {
loadErr := fmt.Errorf("Loading publish error %s from %q", err, path)
fmt.Println(loadErr)
errs = append(errs, loadErr)
continue
}
w, err := p.CreateWorkflows(ctx, varMap, regex, *rollback, *skipDup, *replace, *noRoot, *oauth, time.Now(), *rolloutRate)
if err != nil {
createWorkflowErr := fmt.Errorf("Workflow creation error: %s", err)
fmt.Println(createWorkflowErr)
errs = append(errs, createWorkflowErr)
continue
}
if w != nil {
ws = append(ws, w...)
}
}
errors := make(chan error, len(ws)+len(errs))
for _, err := range errs {
errors <- err
}
if len(ws) == 0 {
checkError(errors)
fmt.Println("[Publish] Nothing to do")
return
}
if *print {
for _, w := range ws {
fmt.Printf("[Publish] Printing workflow %q\n", w.Name)
w.Print(ctx)
}
checkError(errors)
return
}
if *validate {
for _, w := range ws {
fmt.Printf("[Publish] Validating workflow %q\n", w.Name)
if err := w.Validate(ctx); err != nil {
errors <- fmt.Errorf("Error validating workflow %s: %v", w.Name, err)
}
}
checkError(errors)
return
}
if !*noConfirm {
var c string
fmt.Print("\nContinue with publish? (y/N): ")
fmt.Scanln(&c)
c = strings.ToLower(c)
if c != "y" && c != "yes" {
return
}
}
var wg sync.WaitGroup
for _, w := range ws {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func(w *daisy.Workflow) {
select {
case <-c:
fmt.Printf("\nCtrl-C caught, sending cancel signal to %q...\n", w.Name)
w.CancelWorkflow()
errors <- fmt.Errorf("workflow %q was canceled", w.Name)
case <-w.Cancel:
}
}(w)
wg.Add(1)
go func(w *daisy.Workflow) {
defer wg.Done()
fmt.Printf("[Publish] Running workflow %q\n", w.Name)
if err := w.Run(ctx); err != nil {
errors <- fmt.Errorf("%s: %v", w.Name, err)
return
}
fmt.Printf("[Publish] Workflow %q finished\n", w.Name)
}(w)
}
wg.Wait()
checkError(errors)
fmt.Println("[Publish] Workflows completed successfully.")
}