예제 #1
0
파일: main.go 프로젝트: tyrken/rocker
func buildCommand(c *cli.Context) {
	configFilename := c.String("file")

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	if !filepath.IsAbs(configFilename) {
		configFilename = filepath.Clean(path.Join(wd, configFilename))
	}

	// we do not want to outpu anything if "print" was asked
	// TODO: find a more clean way to suppress output
	if !c.Bool("print") {
		fmt.Printf("[Rocker] Building...\n")
	}

	dockerClient, err := dockerclient.NewFromCli(c)
	if err != nil {
		log.Fatal(err)
	}

	// Initialize context dir
	args := c.Args()
	contextDir := filepath.Dir(configFilename)
	if len(args) > 0 {
		if filepath.IsAbs(args[0]) {
			contextDir = args[0]
		} else {
			contextDir = filepath.Clean(path.Join(wd, args[0]))
		}
	}

	cliVars, err := template.VarsFromStrings(c.StringSlice("var"))
	if err != nil {
		log.Fatal(err)
	}

	vars := template.Vars{}.Merge(cliVars)

	// obtain git info about current directory
	gitInfo, err := git.Info(filepath.Dir(configFilename))
	if err != nil {
		// Ignore if given directory is not a git repo
		if _, ok := err.(*git.ErrNotGitRepo); !ok {
			log.Fatal(err)
		}
	}

	// some additional useful vars
	vars["commit"] = stringOr(os.Getenv("GIT_COMMIT"), gitInfo.Sha)
	vars["branch"] = stringOr(os.Getenv("GIT_BRANCH"), gitInfo.Branch)
	vars["git_url"] = stringOr(os.Getenv("GIT_URL"), gitInfo.URL)
	vars["commit_message"] = gitInfo.Message
	vars["commit_author"] = gitInfo.Author

	auth := &docker.AuthConfiguration{}
	authParam := c.String("auth")
	if strings.Contains(authParam, ":") {
		userPass := strings.Split(authParam, ":")
		auth.Username = userPass[0]
		auth.Password = userPass[1]
	}

	builder := build.Builder{
		Rockerfile:    configFilename,
		ContextDir:    contextDir,
		UtilizeCache:  !c.Bool("no-cache"),
		Push:          c.Bool("push"),
		NoReuse:       c.Bool("no-reuse"),
		Verbose:       c.Bool("verbose"),
		Attach:        c.Bool("attach"),
		Print:         c.Bool("print"),
		Auth:          auth,
		Vars:          vars,
		CliVars:       cliVars,
		InStream:      os.Stdin,
		OutStream:     os.Stdout,
		Docker:        dockerClient,
		AddMeta:       c.Bool("meta"),
		Pull:          c.Bool("pull"),
		ID:            c.String("id"),
		ArtifactsPath: c.String("artifacts-path"),
	}

	if _, err := builder.Build(); err != nil {
		log.Fatal(err)
	}
}
예제 #2
0
파일: main.go 프로젝트: tyrken/rocker
func showCommand(c *cli.Context) {
	dockerClient, err := dockerclient.NewFromCli(c)
	if err != nil {
		log.Fatal(err)
	}

	// Initialize context dir
	args := c.Args()
	if len(args) == 0 {
		log.Fatal("Missing image argument")
	}
	//parse parameter to name
	imageName := imagename.NewFromString(args[0])
	infos := []*build.RockerImageData{}

	if imageName.IsStrict() {
		image, err := dockerClient.InspectImage(args[0])
		if err != nil && err.Error() == "no such image" {
			image, err = imagename.RegistryGet(imageName)
			if err != nil {
				log.Fatal(err)
			}
		} else if err != nil {
			log.Fatal(err)
		}
		info, err := toInfo(imageName, image)
		if err != nil {
			log.Fatal(err)
		}
		infos = append(infos, info)
	} else {
		images, err := imagename.RegistryListTags(imageName)
		if err != nil {
			log.Fatal(err)
		}

		type resp struct {
			name  *imagename.ImageName
			image *docker.Image
			err   error
		}
		chResp := make(chan resp, len(images))

		for _, img := range images {
			go func(img *imagename.ImageName) {
				r := resp{name: img}
				r.image, r.err = imagename.RegistryGet(img)
				chResp <- r
			}(img)
		}

		for _ = range images {
			r := <-chResp
			if r.err != nil {
				log.Println(r.err)
			} else if info, err := toInfo(r.name, r.image); err == nil {
				infos = append(infos, info)
			}
		}
	}

	if c.Bool("json") {
		res, err := json.Marshal(infos)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(string(res))
	} else {
		for _, res := range infos {
			fmt.Println(res.PrettyString())
		}
	}
}
예제 #3
0
파일: main.go 프로젝트: romank87/rocker
func buildCommand(c *cli.Context) {

	var (
		rockerfile *build.Rockerfile
		err        error
	)

	initLogs(c)

	// We don't want info level for 'print' mode
	// So log only errors unless 'debug' is on
	if c.Bool("print") && log.StandardLogger().Level != log.DebugLevel {
		log.StandardLogger().Level = log.ErrorLevel
	}

	vars, err := template.VarsFromFileMulti(c.StringSlice("vars"))
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	cliVars, err := template.VarsFromStrings(c.StringSlice("var"))
	if err != nil {
		log.Fatal(err)
	}

	vars = vars.Merge(cliVars)

	if c.Bool("demand-artifacts") {
		vars["DemandArtifacts"] = true
	}

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	configFilename := c.String("file")
	contextDir := wd

	if configFilename == "-" {

		rockerfile, err = build.NewRockerfile(filepath.Base(wd), os.Stdin, vars, template.Funs{})
		if err != nil {
			log.Fatal(err)
		}

	} else {

		if !filepath.IsAbs(configFilename) {
			configFilename = filepath.Join(wd, configFilename)
		}

		rockerfile, err = build.NewRockerfileFromFile(configFilename, vars, template.Funs{})
		if err != nil {
			log.Fatal(err)
		}

		// Initialize context dir
		contextDir = filepath.Dir(configFilename)
	}

	args := c.Args()
	if len(args) > 0 {
		contextDir = args[0]
		if !filepath.IsAbs(contextDir) {
			contextDir = filepath.Join(wd, args[0])
		}
	}

	log.Debugf("Context directory: %s", contextDir)

	if c.Bool("print") {
		fmt.Print(rockerfile.Content)
		os.Exit(0)
	}

	dockerignore := []string{}

	dockerignoreFilename := filepath.Join(contextDir, ".dockerignore")
	if _, err := os.Stat(dockerignoreFilename); err == nil {
		if dockerignore, err = build.ReadDockerignoreFile(dockerignoreFilename); err != nil {
			log.Fatal(err)
		}
	}

	dockerClient, err := dockerclient.NewFromCli(c)
	if err != nil {
		log.Fatal(err)
	}

	auth := docker.AuthConfiguration{}
	authParam := c.String("auth")
	if strings.Contains(authParam, ":") {
		userPass := strings.Split(authParam, ":")
		auth.Username = userPass[0]
		auth.Password = userPass[1]
	}

	client := build.NewDockerClient(dockerClient, auth, log.StandardLogger())

	var cache build.Cache
	if !c.Bool("no-cache") {
		cacheDir, err := util.MakeAbsolute(c.String("cache-dir"))
		if err != nil {
			log.Fatal(err)
		}
		cache = build.NewCacheFS(cacheDir)
	}

	builder := build.New(client, rockerfile, cache, build.Config{
		InStream:      os.Stdin,
		OutStream:     os.Stdout,
		ContextDir:    contextDir,
		Dockerignore:  dockerignore,
		ArtifactsPath: c.String("artifacts-path"),
		Pull:          c.Bool("pull"),
		NoGarbage:     c.Bool("no-garbage"),
		Attach:        c.Bool("attach"),
		Verbose:       c.GlobalBool("verbose"),
		ID:            c.String("id"),
		NoCache:       c.Bool("no-cache"),
		ReloadCache:   c.Bool("reload-cache"),
		Push:          c.Bool("push"),
	})

	plan, err := build.NewPlan(rockerfile.Commands(), true)
	if err != nil {
		log.Fatal(err)
	}

	// Check the docker connection before we actually run
	if err := dockerclient.Ping(dockerClient, 5000); err != nil {
		log.Fatal(err)
	}

	if err := builder.Run(plan); err != nil {
		log.Fatal(err)
	}

	size := fmt.Sprintf("final size %s (+%s from the base image)",
		units.HumanSize(float64(builder.VirtualSize)),
		units.HumanSize(float64(builder.ProducedSize)),
	)

	log.Infof("Successfully built %.12s | %s", builder.GetImageID(), size)
}