github.com/jonsyu1/godel@v0.0.0-20171017211503-64567a0cf169/apps/distgo/cmd/docker/publish.go (about)

     1  // Copyright 2016 Palantir Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package docker
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io"
    21  	"io/ioutil"
    22  	"os/exec"
    23  	"path"
    24  
    25  	"github.com/pkg/errors"
    26  
    27  	"github.com/palantir/godel/apps/distgo/cmd/build"
    28  	"github.com/palantir/godel/apps/distgo/params"
    29  )
    30  
    31  func Publish(products []string, cfg params.Project, wd, baseRepo string, verbose bool, stdout io.Writer) error {
    32  	// find all products with docker images and tag them with correct version and push
    33  	_, productsToPublishImage, err := productsToDistAndBuildImage(products, cfg)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	buildSpecsWithDeps, err := build.SpecsWithDepsForArgs(cfg, productsToPublishImage, wd)
    38  	if err != nil {
    39  		return err
    40  	}
    41  	dockerWriter := ioutil.Discard
    42  	if verbose {
    43  		dockerWriter = stdout
    44  	}
    45  	for _, specWithDeps := range buildSpecsWithDeps {
    46  		versionTag := specWithDeps.Spec.ProductVersion
    47  		for _, image := range specWithDeps.Spec.DockerImages {
    48  			repo := image.Repository
    49  			if baseRepo != "" {
    50  				repo = path.Join(baseRepo, repo)
    51  			}
    52  			buildTag := fmt.Sprintf("%s:%s", repo, image.Tag)
    53  			publishTag := fmt.Sprintf("%s:%s", repo, versionTag)
    54  			if err := tagImage(buildTag, publishTag, dockerWriter); err != nil {
    55  				return err
    56  			}
    57  			if err := pushImage(publishTag, dockerWriter); err != nil {
    58  				return err
    59  			}
    60  		}
    61  	}
    62  	return nil
    63  }
    64  
    65  func tagImage(original, new string, stdout io.Writer) error {
    66  	var args []string
    67  	args = append(args, "tag")
    68  	args = append(args, original)
    69  	args = append(args, new)
    70  
    71  	buildCmd := exec.Command("docker", args...)
    72  	bufWriter := &bytes.Buffer{}
    73  	buildCmd.Stdout = io.MultiWriter(stdout, bufWriter)
    74  	buildCmd.Stderr = bufWriter
    75  	if err := buildCmd.Run(); err != nil {
    76  		return errors.Wrap(err, fmt.Sprintf("docker tag failed with error:\n%s\n Make sure to run docker build before docker publish.\n", bufWriter.String()))
    77  	}
    78  	return nil
    79  }
    80  
    81  func pushImage(tag string, stdout io.Writer) error {
    82  	var args []string
    83  	args = append(args, "push")
    84  	args = append(args, tag)
    85  
    86  	buildCmd := exec.Command("docker", args...)
    87  	bufWriter := &bytes.Buffer{}
    88  	buildCmd.Stdout = io.MultiWriter(stdout, bufWriter)
    89  	buildCmd.Stderr = bufWriter
    90  	if err := buildCmd.Run(); err != nil {
    91  		return errors.Wrap(err, fmt.Sprintf("docker push failed with error:\n%s\n", bufWriter.String()))
    92  	}
    93  	return nil
    94  }