Example #1
0
func main() {
	name := filepath.Base(os.Args[0])
	if name == "golem_runner" {
		runnerMain()
		return
	}
	if name == "golem_tapper" {
		tapperMain()
		return
	}
	var (
		cacheDir    string
		startDaemon bool
		debug       bool
	)

	cm := runner.NewConfigurationManager(name)

	cm.FlagSet.StringVar(&cacheDir, "cache", "", "Cache directory")
	cm.FlagSet.BoolVar(&startDaemon, "rundaemon", false, "Start daemon")
	cm.FlagSet.BoolVar(&debug, "debug", false, "Whether to output debug logs")

	if err := cm.ParseFlags(os.Args[1:]); err != nil {
		logrus.Fatalf("Invalid options: %v", err)
	}

	if debug {
		logrus.SetLevel(logrus.DebugLevel)
	}

	runConfig, err := cm.RunnerConfiguration()
	if err != nil {
		logrus.Fatalf("Error creating run configuration: %v", err)
	}

	if cacheDir == "" {
		td, err := ioutil.TempDir("", "golem-cache-")
		if err != nil {
			logrus.Fatalf("Error creating tempdir: %v", err)
		}
		cacheDir = td
		defer os.RemoveAll(td)
	}

	cacheConfig := runner.CacheConfiguration{
		ImageCache: runner.NewImageCache(filepath.Join(cacheDir, "images")),
	}

	var client runner.DockerClient
	if startDaemon {
		logger := runner.NewConsoleLogCapturer()
		c, shutdown, err := runner.StartDaemon(context.Background(), "docker", logger)
		if err != nil {
			logrus.Fatalf("Error starting deamon: %v", err)
		}
		defer shutdown()
		client = c
	} else {
		c, err := cm.DockerClient()
		if err != nil {
			logrus.Fatalf("Failed to create client: %v", err)
		}
		client = c
	}

	// require running on docker 1.10 to ensure content addressable
	// image identifiers are used
	if err := client.CheckServerVersion(versionutil.StaticVersion(1, 10, 0)); err != nil {
		logrus.Fatal(err)
	}

	r := runner.NewRunner(runConfig, cacheConfig, debug)

	if err := r.Build(client); err != nil {
		logrus.Fatalf("Error building test images: %v", err)
	}

	if err := r.Run(client); err != nil {
		logrus.Fatalf("Error running tests: %v", err)
	}
}
Example #2
0
func runnerMain() {
	var (
		command string
		dind    bool
		clean   bool
	)

	// TODO: Parse runner options
	flag.StringVar(&command, "command", "bats", "Command to run")
	flag.BoolVar(&dind, "docker", false, "Whether to run docker")
	flag.BoolVar(&clean, "clean", false, "Whether to ensure /var/lib/docker is empty")

	flag.Parse()

	// TODO: Allow quiet and verbose mode
	logrus.SetLevel(logrus.DebugLevel)

	logrus.Debugf("Runner!")

	// Check if has compose file
	composeFile := "/runner/docker-compose.yml"
	var composeCapturer runner.LogCapturer
	if _, err := os.Stat(composeFile); err == nil {
		composeCapturer = newFileCapturer("compose")
		defer composeCapturer.Close()
	} else {
		logrus.Debugf("No compose file found at %s", composeFile)
	}

	scriptCapturer := newFileCapturer("scripts")
	defer scriptCapturer.Close()
	loadCapturer := newFileCapturer("load")
	defer loadCapturer.Close()
	daemonCapturer := newFileCapturer("daemon")
	defer daemonCapturer.Close()
	testCapturer := runner.NewConsoleLogCapturer()
	defer testCapturer.Close()

	instanceF, err := os.Open("/instance.json")
	if err != nil {
		logrus.Fatalf("Error opening instance file: %v", err)
	}

	var instanceConfig runner.RunConfiguration
	if err := json.NewDecoder(instanceF).Decode(&instanceConfig); err != nil {
		logrus.Fatalf("Error decoding instance configuration: %v", err)
	}

	suiteConfig := runner.SuiteRunnerConfiguration{
		DockerLoadLogCapturer: loadCapturer,
		DockerLogCapturer:     daemonCapturer,

		RunConfiguration: instanceConfig,
		SetupLogCapturer: scriptCapturer,
		TestCapturer:     testCapturer,

		CleanDockerGraph: clean,
		DockerInDocker:   dind,
	}

	if composeCapturer != nil {
		suiteConfig.ComposeCapturer = composeCapturer
		suiteConfig.ComposeFile = composeFile

	}

	r := runner.NewSuiteRunner(suiteConfig)

	if err := r.Setup(); err != nil {
		logrus.Fatalf("Setup error: %v", err)
	}

	runErr := r.RunTests()

	if err := r.TearDown(); err != nil {
		logrus.Errorf("TearDown error: %v", err)
	}

	if runErr != nil {
		logrus.Fatalf("Test errored: %v", runErr)
	}
}
Example #3
0
func runnerMain() {
	var (
		command        string
		forwardAddress string
		tapSocket      string
		dind           bool
		clean          bool
		debug          bool
	)

	flag.StringVar(&command, "command", "bats", "Command to run")
	flag.StringVar(&forwardAddress, "forward", "", "Address to forward logs to")
	flag.StringVar(&tapSocket, "tap-socket", "/var/run/golem-logs", "Socket to spawn log tapper")
	flag.BoolVar(&dind, "docker", false, "Whether to run docker")
	flag.BoolVar(&clean, "clean", false, "Whether to ensure /var/lib/docker is empty")
	flag.BoolVar(&debug, "debug", false, "Whether to output debug logs")

	flag.Parse()

	if debug {
		logrus.SetLevel(logrus.DebugLevel)
	}

	router := runner.NewLogRouter("/var/log/docker")

	if tapSocket != "" {
		l, err := net.Listen("unix", tapSocket)
		if err != nil {
			logrus.Fatalf("Error creating listener for %s: %#v", tapSocket, err)
		}

		go runner.TapServer(l, router)
	}

	if forwardAddress != "" {
		logrus.Debugf("Forwarding logs to %s, not yet supported", forwardAddress)
		// TODO: Create forwarder with address
		// add forwarder using router.AddForwarder
	}

	logrus.Debugf("Runner!")

	logrus.Debugf("Environment: %#v", os.Environ())

	// Check if has compose file
	composeFile := "/runner/docker-compose.yml"
	var composeCapturer runner.LogCapturer
	if _, err := os.Stat(composeFile); err == nil {
		composeCapturer, err = router.RouteLogCapturer("compose")
		if err != nil {
			logrus.Fatalf("Error creating log capturer: %v", err)
		}
		defer composeCapturer.Close()
	} else {
		logrus.Debugf("No compose file found at %s", composeFile)
	}

	scriptCapturer, err := router.RouteLogCapturer("scripts")
	if err != nil {
		logrus.Fatalf("Error creating log capturer: %v", err)
	}
	defer scriptCapturer.Close()
	loadCapturer, err := router.RouteLogCapturer("load")
	if err != nil {
		logrus.Fatalf("Error creating log capturer: %v", err)
	}
	defer loadCapturer.Close()
	daemonCapturer, err := router.RouteLogCapturer("daemon")
	if err != nil {
		logrus.Fatalf("Error creating log capturer: %v", err)
	}
	defer daemonCapturer.Close()
	testCapturer, err := router.RouteLogCapturer("test")
	if err != nil {
		logrus.Fatalf("Error creating log capturer: %v", err)
	}
	defer testCapturer.Close()

	if forwardAddress == "" {
		logrus.Debugf("Logs not forwarded, dumping test output to console")
		if err := router.AddCapturer("test", runner.NewConsoleLogCapturer()); err != nil {
			logrus.Fatalf("Error creating test capturer")
		}
	}

	instanceF, err := os.Open("/instance.json")
	if err != nil {
		logrus.Fatalf("Error opening instance file: %v", err)
	}

	var instanceConfig runner.RunConfiguration
	if err := json.NewDecoder(instanceF).Decode(&instanceConfig); err != nil {
		logrus.Fatalf("Error decoding instance configuration: %v", err)
	}

	suiteConfig := runner.SuiteRunnerConfiguration{
		DockerLoadLogCapturer: loadCapturer,
		DockerLogCapturer:     daemonCapturer,

		RunConfiguration: instanceConfig,
		SetupLogCapturer: scriptCapturer,
		TestCapturer:     testCapturer,

		CleanDockerGraph: clean,
		DockerInDocker:   dind,
	}

	if composeCapturer != nil {
		suiteConfig.ComposeCapturer = composeCapturer
		suiteConfig.ComposeFile = composeFile

	}

	r := runner.NewSuiteRunner(suiteConfig)

	if err := r.Setup(); err != nil {
		logrus.Fatalf("Setup error: %v", err)
	}

	runErr := r.RunTests()

	if err := r.TearDown(); err != nil {
		logrus.Errorf("TearDown error: %v", err)
	}

	if runErr != nil {
		logrus.Fatalf("Test errored: %v", runErr)
	}

	logrus.Debugf("Shutting down log router")
	router.Shutdown()
}