Skip to content

Commit

Permalink
add docker buildImage
Browse files Browse the repository at this point in the history
* add docker buildImage

* deploy: create pushImage function
  • Loading branch information
guilhermebr authored Jun 20, 2018
1 parent fdc0dce commit 4cd5fa9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 22 deletions.
53 changes: 39 additions & 14 deletions deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,7 @@ func tagAndPush(dockerClient *docker.Client, imgID, imageName string, auth docke
if err != nil {
return fmt.Errorf("error tagging image %v: %v", img, err)
}
fmt.Fprintf(w, " ---> Sending image to repository (%s)\n", img)
for i := 0; i < retries; i++ {
err = dockerClient.Push(context.Background(), auth, img)
if err != nil {
fmt.Fprintf(w, "Could not send image, trying again. Original error: %v\n", err)
time.Sleep(time.Second)
continue
}
break
}
if err != nil {
return fmt.Errorf("Error pushing image: %v", err)
}
return nil
return pushImage(dockerClient, img, auth, retries, w)
}

func inspect(dockerClient *docker.Client, image string, filesystem Filesystem, w io.Writer, errW io.Writer) error {
Expand Down Expand Up @@ -150,3 +137,41 @@ func inspect(dockerClient *docker.Client, image string, filesystem Filesystem, w
}
return nil
}

func buildAndPush(dockerClient *docker.Client, imageName string, fileName string, config Config, w io.Writer) error {
auth := docker.AuthConfig{
Username: config.RegistryAuthUser,
Password: config.RegistryAuthPass,
Email: config.RegistryAuthEmail,
ServerAddress: config.RegistryAddress,
}
file, err := os.Open(fileName)
if err != nil {
return fmt.Errorf("failed to open input file %q: %v", fileName, err)
}
defer file.Close()
err = dockerClient.BuildImage(context.Background(), imageName, file)
if err != nil {
return fmt.Errorf("error building image %v: %v", imageName, err)
}
img := docker.ParseImageName(imageName)
return pushImage(dockerClient, img, auth, config.RegistryPushRetries, w)
}

func pushImage(dockerClient *docker.Client, img docker.Image, auth docker.AuthConfig, retries int, w io.Writer) error {
fmt.Fprintf(w, " ---> Sending image to repository (%s)\n", img)
var err error
for i := 0; i < retries; i++ {
err = dockerClient.Push(context.Background(), auth, img)
if err != nil {
fmt.Fprintf(w, "Could not send image, trying again. Original error: %v\n", err)
time.Sleep(time.Second)
continue
}
break
}
if err != nil {
return fmt.Errorf("Error pushing image: %v", err)
}
return nil
}
35 changes: 27 additions & 8 deletions internal/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,7 @@ func (c *Client) ListContainersByLabels(ctx context.Context, labels map[string]s
}

func (c *Client) Commit(ctx context.Context, containerID, image string) (string, error) {
registry, repo, tag := splitImageName(image)
img := Image{
registry: registry,
repository: repo,
tag: tag,
}
img := ParseImageName(image)
commitedImg, err := c.api.CommitContainer(docker.CommitContainerOptions{
Container: containerID,
Repository: img.repository,
Expand All @@ -113,8 +108,8 @@ func (c *Client) Commit(ctx context.Context, containerID, image string) (string,

// Tag tags the image given by imgID with the given imageName
func (c *Client) Tag(ctx context.Context, imgID, imageName string) (Image, error) {
reg, rep, tag := splitImageName(imageName)
img := Image{registry: reg, repository: rep, tag: tag, ID: imgID}
img := ParseImageName(imageName)
img.ID = imgID
return img, c.api.TagImage(img.ID, docker.TagImageOptions{
Repo: img.Name(),
Tag: img.tag,
Expand Down Expand Up @@ -151,6 +146,30 @@ func (c *Client) Inspect(ctx context.Context, img string) (ImageInspect, error)
return ImageInspect(*inspect), err
}

func (c *Client) BuildImage(ctx context.Context, imageName string, inputFile io.Reader) error {
buildOptions := docker.BuildImageOptions{
Name: imageName,
Pull: true,
NoCache: true,
RmTmpContainer: true,
InputStream: inputFile,
OutputStream: &errorCheckWriter{W: os.Stdout},
Context: ctx,
InactivityTimeout: streamInactivityTimeout,
RawJSONStream: true,
}
return c.api.BuildImage(buildOptions)
}

func ParseImageName(imageName string) Image {
registry, repo, tag := splitImageName(imageName)
return Image{
registry: registry,
repository: repo,
tag: tag,
}
}

func splitImageName(imageName string) (registry, repo, tag string) {
imgNameSplit := strings.Split(imageName, ":")
switch len(imgNameSplit) {
Expand Down
22 changes: 22 additions & 0 deletions internal/docker/docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,25 @@ func (s *S) TestInspect(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(img.ID, check.Not(check.DeepEquals), "")
}

func (s *S) TestClientBuildImage(c *check.C) {
client, err := NewClient(s.dockerserver.URL())
c.Assert(err, check.IsNil)

data := bytes.NewBuffer([]byte("FROM tsuru/go"))
dataSize := int64(data.Len())
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
err = tw.WriteHeader(&tar.Header{
Name: "Dockerfile",
Mode: 0666,
Size: dataSize,
})
c.Assert(err, check.IsNil)
defer tw.Close()
n, err := io.Copy(tw, data)
c.Assert(err, check.IsNil)
c.Assert(n, check.Equals, dataSize)
err = client.BuildImage(context.Background(), "tsuru/teste-go", buf)
c.Assert(err, check.IsNil)
}
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Config struct {
DestinationImages []string `split_words:"true"`
SourceImage string `split_words:"true"`
InputFile string `split_words:"true"`
DockerfileBuild bool `split_words:"true"`
RegistryPushRetries int `split_words:"true" default:"3"`
RegistryAuthEmail string `split_words:"true"`
RegistryAuthPass string `split_words:"true"`
Expand Down Expand Up @@ -58,6 +59,12 @@ func main() {
if err != nil {
fatalf("failed to create docker client: %v", err)
}
if config.DockerfileBuild {
if err := buildAndPush(dockerClient, config.DestinationImages[0], config.InputFile, config, os.Stdout); err != nil {
fatalf("failed to build and push image: %v", err)
}
return
}
sideCar, err := setupSidecar(dockerClient, config)
if err != nil {
fatalf("failed to create sidecar: %v", err)
Expand Down

0 comments on commit 4cd5fa9

Please sign in to comment.