func main() { var insecureDockerRegistries registries var dockerRegistryIPs ips flagSet := flag.NewFlagSet("builder", flag.ExitOnError) dockerImageURL := flagSet.String( "dockerImageURL", "", "docker image uri in docker://[registry/][scope/]repository[#tag] format", ) dockerRef := flagSet.String( "dockerRef", "", "docker image reference in standard docker string format", ) outputFilename := flagSet.String( "outputMetadataJSONFilename", "/tmp/result/result.json", "filename in which to write the app metadata", ) flagSet.Var( &insecureDockerRegistries, "insecureDockerRegistries", "insecure Docker Registry addresses (host:port)", ) dockerDaemonExecutablePath := flagSet.String( "dockerDaemonExecutablePath", "/tmp/docker_app_lifecycle/docker", "path to the 'docker' executable", ) cacheDockerImage := flagSet.Bool( "cacheDockerImage", false, "Caches Docker images to private docker registry", ) flagSet.Var( &dockerRegistryIPs, "dockerRegistryIPs", "Docker Registry IPs", ) dockerRegistryHost := flagSet.String( "dockerRegistryHost", "", "Docker Registry host", ) dockerRegistryPort := flagSet.Int( "dockerRegistryPort", 8080, "Docker Registry port", ) dockerLoginServer := flagSet.String( "dockerLoginServer", registry.IndexServerAddress(), "Docker Login server address", ) dockerUser := flagSet.String( "dockerUser", "", "User for pulling from docker registry", ) dockerPassword := flagSet.String( "dockerPassword", "", "Password for pulling from docker registry", ) dockerEmail := flagSet.String( "dockerEmail", "", "Email for pulling from docker registry", ) if err := flagSet.Parse(os.Args[1:len(os.Args)]); err != nil { println(err.Error()) os.Exit(1) } var repoName string var tag string if len(*dockerImageURL) > 0 { parts, err := url.Parse(*dockerImageURL) if err != nil { println("invalid dockerImageURL: " + *dockerImageURL) flagSet.PrintDefaults() os.Exit(1) } repoName, tag = helpers.ParseDockerURL(parts) } else if len(*dockerRef) > 0 { repoName, tag = helpers.ParseDockerRef(*dockerRef) } else { println("missing flag: dockerImageURL or dockerRef required") flagSet.PrintDefaults() os.Exit(1) } builder := Builder{ RepoName: repoName, Tag: tag, OutputFilename: *outputFilename, DockerDaemonExecutablePath: *dockerDaemonExecutablePath, InsecureDockerRegistries: insecureDockerRegistries, DockerDaemonTimeout: 10 * time.Second, CacheDockerImage: *cacheDockerImage, DockerRegistryIPs: dockerRegistryIPs, DockerRegistryHost: *dockerRegistryHost, DockerRegistryPort: *dockerRegistryPort, DockerLoginServer: *dockerLoginServer, DockerUser: *dockerUser, DockerPassword: *dockerPassword, DockerEmail: *dockerEmail, } members := grouper.Members{ {"builder", ifrit.RunFunc(builder.Run)}, } if *cacheDockerImage { if len(dockerRegistryIPs) == 0 { println("missing flag: dockerRegistryIPs required") os.Exit(1) } if len(*dockerRegistryHost) == 0 { println("missing flag: dockerRegistryHost required") os.Exit(1) } if strings.Contains(*dockerRegistryHost, ":") { println("invalid host format", *dockerRegistryHost) os.Exit(1) } if *dockerRegistryPort < 0 { println("negative port number", *dockerRegistryPort) os.Exit(1) } if *dockerRegistryPort > 65535 { println("port number too big", *dockerRegistryPort) os.Exit(1) } validateCredentials(*dockerLoginServer, *dockerUser, *dockerPassword, *dockerEmail) if _, err := os.Stat(*dockerDaemonExecutablePath); err != nil { println("docker daemon not found in", *dockerDaemonExecutablePath) os.Exit(1) } dockerDaemon := DockerDaemon{ DockerDaemonPath: *dockerDaemonExecutablePath, InsecureDockerRegistries: insecureDockerRegistries, DockerRegistryIPs: dockerRegistryIPs, DockerRegistryHost: *dockerRegistryHost, } members = append(members, grouper.Member{"docker_daemon", ifrit.RunFunc(dockerDaemon.Run)}) } group := grouper.NewParallel(os.Interrupt, members) process := ifrit.Invoke(sigmon.New(group)) fmt.Println("Staging process started ...") err := <-process.Wait() if err != nil { println("Staging process failed:", err.Error()) os.Exit(2) } fmt.Println("Staging process finished") }
var ( lifecycle ifrit.Process fakeDeamonRunner func(signals <-chan os.Signal, ready chan<- struct{}) error ) BeforeEach(func() { builder := main.Builder{ RepoName: "ubuntu", Tag: "latest", OutputFilename: "/tmp/result/result.json", DockerDaemonTimeout: 300 * time.Millisecond, CacheDockerImage: true, } lifecycle = ifrit.Background(grouper.NewParallel(os.Interrupt, grouper.Members{ {"builder", ifrit.RunFunc(builder.Run)}, {"fake_docker_daemon", ifrit.RunFunc(fakeDeamonRunner)}, })) }) AfterEach(func() { ginkgomon.Interrupt(lifecycle) }) Context("when the daemon won't start", func() { fakeDeamonRunner = func(signals <-chan os.Signal, ready chan<- struct{}) error { close(ready) select { case signal := <-signals: return errors.New(signal.String()) case <-time.After(1 * time.Second): // Daemon "crashes" after a while
Δ time.Duration = 10 * time.Millisecond ) BeforeEach(func() { childRunner1 = fake_runner.NewTestRunner() childRunner2 = fake_runner.NewTestRunner() childRunner3 = fake_runner.NewTestRunner() members = grouper.Members{ {"child1", childRunner1}, {"child2", childRunner2}, {"child3", childRunner3}, } groupRunner = grouper.NewParallel(os.Interrupt, members) }) AfterEach(func() { childRunner1.EnsureExit() childRunner2.EnsureExit() childRunner3.EnsureExit() ginkgomon.Kill(groupProcess) }) Describe("Start", func() { BeforeEach(func() { groupProcess = ifrit.Background(groupRunner) })