func main()

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.")
}