|
@@ -1,5 +1,238 @@
|
|
|
package buildme
|
|
|
|
|
|
+import (
|
|
|
+ "buildme/utils"
|
|
|
+ "context"
|
|
|
+ "io"
|
|
|
+ "os"
|
|
|
+
|
|
|
+ "dev.hexasoftware.com/hxs/prettylog"
|
|
|
+ "dev.hexasoftware.com/x/seq"
|
|
|
+
|
|
|
+ "github.com/docker/docker/api/types"
|
|
|
+ "github.com/docker/docker/api/types/container"
|
|
|
+ docker "github.com/docker/docker/client"
|
|
|
+)
|
|
|
+
|
|
|
+func RunContainerX(imageName string, containerName string, command string) error {
|
|
|
+ log := prettylog.New("RUN CONTAINER")
|
|
|
+
|
|
|
+ cli, err := docker.NewEnvClient()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ ctx := context.Background()
|
|
|
+
|
|
|
+ log.Println("inspecting container:", containerName)
|
|
|
+ res, err := cli.ContainerInspect(ctx, containerName)
|
|
|
+ if err != nil {
|
|
|
+ containerCfg := &container.Config{
|
|
|
+ Image: imageName,
|
|
|
+ Cmd: []string{"ls"},
|
|
|
+ }
|
|
|
+ log.Println("===> Creating container")
|
|
|
+ _, err := cli.ContainerCreate(ctx, containerCfg, nil, nil, containerName)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // Inspec again
|
|
|
+ res, err = cli.ContainerInspect(ctx, containerName)
|
|
|
+ //return err
|
|
|
+ }
|
|
|
+ log.Println("Check if container running")
|
|
|
+ if !res.State.Running {
|
|
|
+ s := seq.New()
|
|
|
+ s.Add("Commit", cli.ContainerCommit, ctx, containerName, types.ContainerCommitOptions{Config: res.Config})
|
|
|
+ s.Add("Tag", func(imgRes types.IDResponse) error { return cli.ImageTag(ctx, imgRes.ID, imageName+"build-1") }, seq.SeqReturn(0, 0))
|
|
|
+ s.Add("Remove", cli.ContainerRemove, ctx, containerName, types.ContainerRemoveOptions{})
|
|
|
+ s.Add("Create", func(imgRes types.IDResponse) (container.ContainerCreateCreatedBody, error) {
|
|
|
+ return cli.ContainerCreate(ctx, &container.Config{Image: imgRes.ID, Cmd: utils.ParseField(command)}, res.HostConfig, nil, res.Name)
|
|
|
+ }, seq.SeqReturn(0, 0))
|
|
|
+
|
|
|
+ s.Add("Start", func(ncon container.ContainerCreateCreatedBody) error {
|
|
|
+ return cli.ContainerStart(ctx, ncon.ID, types.ContainerStartOptions{})
|
|
|
+ }, seq.SeqReturn(3, 0))
|
|
|
+ s.Add("Wait", func(ncon container.ContainerCreateCreatedBody) (int64, error) {
|
|
|
+ return cli.ContainerWait(ctx, ncon.ID)
|
|
|
+ }, seq.SeqReturn(3, 0))
|
|
|
+ s.Add("Copy", func(ncon container.ContainerCreateCreatedBody) (io.ReadCloser, types.ContainerPathStat, error) {
|
|
|
+ return cli.CopyFromContainer(ctx, ncon.ID, "/buildme/dist.tar.gz")
|
|
|
+ }, seq.SeqReturn(3, 0))
|
|
|
+
|
|
|
+ s.Add("Save", func(rd io.ReadCloser) error {
|
|
|
+ f, err := os.OpenFile("./data/dist.tar.gz", os.O_CREATE|os.O_WRONLY, os.FileMode(0644))
|
|
|
+ io.Copy(f, rd)
|
|
|
+ return err
|
|
|
+ }, seq.SeqReturn(6, 0))
|
|
|
+
|
|
|
+ err := s.Exec()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ log.Println("ContainerExecCreate")
|
|
|
+ r, err := cli.ContainerExecCreate(ctx, containerName, types.ExecConfig{Cmd: utils.ParseField(command)})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("Executing command in Exec")
|
|
|
+ err = cli.ContainerExecStart(ctx, r.ID, types.ExecStartCheck{})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ log.Println("Is this a new container??:", r.ID)
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// Docker helper
|
|
|
+// RunContainer Run command in container
|
|
|
+// First check if container is running, then exec
|
|
|
+//
|
|
|
+func RunContainer(imageName string, containerName string, command string) error {
|
|
|
+ log := prettylog.New("RUN CONTAINER")
|
|
|
+
|
|
|
+ cli, err := docker.NewEnvClient()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ ctx := context.Background()
|
|
|
+
|
|
|
+ log.Println("inspecting container:", containerName)
|
|
|
+ res, err := cli.ContainerInspect(ctx, containerName)
|
|
|
+ if err != nil {
|
|
|
+ containerCfg := &container.Config{
|
|
|
+ Image: imageName,
|
|
|
+ Cmd: []string{"ls"},
|
|
|
+ }
|
|
|
+ log.Println("===> Creating container")
|
|
|
+ _, err := cli.ContainerCreate(ctx, containerCfg, nil, nil, containerName)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // Inspec again
|
|
|
+ res, err = cli.ContainerInspect(ctx, containerName)
|
|
|
+ //return err
|
|
|
+ }
|
|
|
+ log.Println("Check if container running")
|
|
|
+ if !res.State.Running {
|
|
|
+
|
|
|
+ //nImageName := containerName + "-tmp"
|
|
|
+ log.Println("Container commit to")
|
|
|
+ imgRes, err := cli.ContainerCommit(ctx, containerName, types.ContainerCommitOptions{Config: res.Config})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ cli.ImageTag(ctx, imgRes.ID, imageName+"build-1")
|
|
|
+ // Remove Container and start other
|
|
|
+ log.Println("Removing container")
|
|
|
+ err = cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("Starting new container with", imgRes.ID)
|
|
|
+ timeout := 10
|
|
|
+ ncon, err := cli.ContainerCreate(ctx, &container.Config{AttachStdin: true, AttachStderr: true, AttachStdout: true, OpenStdin: true, StopTimeout: &timeout,
|
|
|
+ Image: imgRes.ID, Cmd: utils.ParseField(command)}, res.HostConfig, nil, res.Name)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ log.Println("Starting the created container timeout was:", timeout)
|
|
|
+ err = cli.ContainerStart(ctx, ncon.ID, types.ContainerStartOptions{})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ ret, err := cli.ContainerWait(ctx, ncon.ID)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ log.Println("Returning withcode:", ret)
|
|
|
+
|
|
|
+ } else {
|
|
|
+ log.Println("ContainerExecCreate")
|
|
|
+ r, err := cli.ContainerExecCreate(ctx, containerName, types.ExecConfig{Cmd: utils.ParseField(command)})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("Executing command in Exec")
|
|
|
+ err = cli.ContainerExecStart(ctx, r.ID, types.ExecStartCheck{})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ log.Println("Is this a new container??:", r.ID)
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+//RunImageCmd run command in image and commit
|
|
|
+func RunImageCmd(image string, command string) error {
|
|
|
+ log.Println("Executing in image", command, "image", image)
|
|
|
+ cli, err := docker.NewEnvClient()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer cli.Close()
|
|
|
+ ctx := context.Background()
|
|
|
+
|
|
|
+ containerCfg := &container.Config{
|
|
|
+ AttachStdout: true,
|
|
|
+ AttachStdin: true,
|
|
|
+ AttachStderr: true,
|
|
|
+
|
|
|
+ Image: image,
|
|
|
+ Cmd: utils.ParseField(command),
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("===> Creating container")
|
|
|
+ containerRes, err := cli.ContainerCreate(ctx, containerCfg, nil, nil, image)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // Remove container
|
|
|
+ defer func() {
|
|
|
+ log.Println("===> Removing container", containerRes.ID)
|
|
|
+ err := cli.ContainerRemove(ctx, containerRes.ID, types.ContainerRemoveOptions{})
|
|
|
+ if err != nil {
|
|
|
+ log.Println("Error removing container", err)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ log.Println("===> Starting container")
|
|
|
+ err = cli.ContainerStart(ctx, containerRes.ID, types.ContainerStartOptions{})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("===> Waiting for container", containerRes.ID)
|
|
|
+ retCode, err := cli.ContainerWait(ctx, containerRes.ID)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ log.Println("Returned:", retCode)
|
|
|
+
|
|
|
+ commitCfg := types.ContainerCommitOptions{
|
|
|
+ Config: containerCfg,
|
|
|
+ }
|
|
|
+ log.Println("===> Commiting container")
|
|
|
+ commitRes, err := cli.ContainerCommit(ctx, containerRes.ID, commitCfg)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("===> Tagging container")
|
|
|
+ err = cli.ImageTag(ctx, commitRes.ID, image)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
func DockerBuild(p *Project) error {
|
|
|
log.Println("New docker environ")
|