Created
November 21, 2018 03:16
-
-
Save gdanko/94aaf2770f586d0490c3c4a941544c13 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"archive/tar" | |
"bytes" | |
"context" | |
"encoding/json" | |
"fmt" | |
"github.com/docker/docker/api/types" | |
"github.com/docker/docker/client" | |
"io" | |
"io/ioutil" | |
"os" | |
"path/filepath" | |
"strings" | |
) | |
type StreamMessage struct { | |
Stream string `json:"stream,omitempty"` | |
} | |
type AuxMessage struct { | |
Aux struct { | |
ID string `json:"ID"` | |
} `json:"aux"` | |
} | |
func main() { | |
cli, err := generateDockerCLI() | |
if err != nil { | |
panic(err) | |
} | |
dockerPath := "/Users/gdanko/go/planB" | |
dockerFile := "Dockerfile" | |
dockerBuildContext, err := getBuildContext(dockerPath) | |
if err != nil { | |
panic(err) | |
} | |
options := types.ImageBuildOptions{ | |
// https://godoc.org/docker.io/go-docker/api/types#ImageBuildOptions | |
SuppressOutput: false, | |
NoCache: true, | |
CgroupParent: "cgroup_parent", | |
Tags: []string{"dummy:latest"}, | |
Context: dockerBuildContext, | |
Dockerfile: dockerFile, | |
Remove: true, | |
} | |
imageBuildResponse, err := cli.ImageBuild( | |
context.Background(), | |
dockerBuildContext, | |
options, | |
) | |
if err != nil { | |
fmt.Println("*** error ***") | |
panic(err) | |
} else { | |
fmt.Println("*** success ***") | |
fmt.Println(imageBuildResponse) | |
} | |
defer imageBuildResponse.Body.Close() | |
fmt.Println("") | |
fmt.Println("*** ImageBuild output ***") | |
buf := new(bytes.Buffer) | |
buf.ReadFrom(imageBuildResponse.Body) | |
var streamMessage StreamMessage | |
var auxMessage AuxMessage | |
for _, line := range strings.Split(buf.String(), "\n") { | |
if err = json.Unmarshal([]byte(line), &streamMessage); err == nil { | |
if streamMessage.Stream != "\n" { | |
fmt.Println(strings.TrimSpace(streamMessage.Stream)) | |
} | |
// the AuxMessage struct is being caught above. Why? | |
} else if err = json.Unmarshal([]byte(line), &auxMessage); err == nil { | |
fmt.Printf(auxMessage.Aux.ID) | |
} | |
} | |
} | |
func generateDockerCLI() (cli *client.Client, err error) { | |
cli, err = client.NewClientWithOpts(client.WithVersion("1.37")) | |
return cli, err | |
} | |
func getBuildContext(uuidPath string) (dockerFileTarReader io.Reader, err error) { | |
buf := new(bytes.Buffer) | |
tw := tar.NewWriter(buf) | |
defer tw.Close() | |
err = filepath.Walk(uuidPath, func(path string, info os.FileInfo, err error) error { | |
f, err := os.Stat(path) | |
if err != nil { | |
return err | |
} | |
// Excluding .git folder | |
// TBD: parse .dockerignore and exclude the files listed from context | |
if f.IsDir() == false && !strings.HasPrefix(path, uuidPath+"/.git") { | |
pathReader, err := os.Open(path) | |
if err != nil { | |
panic(err) | |
} | |
defer pathReader.Close() | |
readPath, err := ioutil.ReadAll(pathReader) | |
if err != nil { | |
panic(err) | |
} | |
file, err := os.OpenFile(path, os.O_RDONLY, 0600) | |
if err != nil { | |
return err | |
} | |
defer file.Close() | |
info, err := file.Stat() | |
if err != nil { | |
return err | |
} | |
rel, err := filepath.Rel(uuidPath, path) | |
if err != nil { | |
return err | |
} | |
fmt.Printf("\x1b[21m\x1b[34mTarring => %s\x1b[0m\n", rel) | |
tarHeader := &tar.Header{ | |
Name: rel, | |
Size: info.Size(), | |
Mode: int64(info.Mode()), | |
ModTime: info.ModTime(), | |
} | |
if err := tw.WriteHeader(tarHeader); err != nil { | |
fmt.Printf("\x1b[1m\033[31mUnable to write tar header: %s\x1b[0m", err) | |
return err | |
} | |
if _, err = tw.Write(readPath); err != nil { | |
fmt.Printf("\x1b[1m\033[31mUnable to write tar body: %s\x1b[0m", err) | |
return err | |
} | |
} | |
return nil | |
}) | |
if err != nil { | |
return bytes.NewReader(buf.Bytes()), err | |
} | |
dockerFileTarReader = bytes.NewReader(buf.Bytes()) | |
return dockerFileTarReader, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment