|
@@ -5,6 +5,7 @@ import (
|
|
|
"context"
|
|
|
"io"
|
|
|
"os"
|
|
|
+ "path"
|
|
|
|
|
|
"dev.hexasoftware.com/hxs/prettylog"
|
|
|
"dev.hexasoftware.com/x/seq"
|
|
@@ -14,7 +15,103 @@ import (
|
|
|
docker "github.com/docker/docker/client"
|
|
|
)
|
|
|
|
|
|
-func RunContainerX(imageName string, containerName string, command string) error {
|
|
|
+type ImageCtx struct {
|
|
|
+ imageName string // Starting image
|
|
|
+ //conID string
|
|
|
+ tmpImgID string
|
|
|
+ //containerName string // Temporary
|
|
|
+ cli *docker.Client
|
|
|
+}
|
|
|
+
|
|
|
+func ImageCli(imageName string) (*ImageCtx, error) {
|
|
|
+ cli, err := docker.NewEnvClient()
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return &ImageCtx{imageName, "", cli}, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (c *ImageCtx) Run(command []string) error {
|
|
|
+ log := prettylog.New("RUN in IMAGE:")
|
|
|
+ log.Println("RUN", command)
|
|
|
+
|
|
|
+ ctx := context.Background()
|
|
|
+
|
|
|
+ if c.tmpImgID == "" {
|
|
|
+ c.tmpImgID = c.imageName
|
|
|
+ }
|
|
|
+
|
|
|
+ conConfig := &container.Config{Image: c.tmpImgID, Cmd: command}
|
|
|
+ ncon, err := c.cli.ContainerCreate(ctx, conConfig, nil, nil, "")
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer c.cli.ContainerRemove(ctx, ncon.ID, types.ContainerRemoveOptions{})
|
|
|
+ //c.conID = ncon.ID
|
|
|
+
|
|
|
+ err = c.cli.ContainerStart(ctx, ncon.ID, types.ContainerStartOptions{})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ retCode, err := c.cli.ContainerWait(ctx, ncon.ID)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ _ = retCode
|
|
|
+ /*if retCode != 0 {
|
|
|
+ return errors.New("Container did not complete successfully")
|
|
|
+ }*/
|
|
|
+
|
|
|
+ imgRes, err := c.cli.ContainerCommit(ctx, ncon.ID, types.ContainerCommitOptions{Config: conConfig})
|
|
|
+ c.tmpImgID = imgRes.ID
|
|
|
+
|
|
|
+ c.cli.ImageTag(ctx, imgRes.ID, c.imageName+":building")
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (c *ImageCtx) Copy(src string, dst string) error {
|
|
|
+ log := prettylog.New("COPY in IMAGE:")
|
|
|
+ log.Println("COPY", src, dst)
|
|
|
+ ctx := context.Background()
|
|
|
+
|
|
|
+ conConfig := &container.Config{Image: c.tmpImgID}
|
|
|
+ // Create container
|
|
|
+ log.Println("ContainerCreate")
|
|
|
+ ncon, err := c.cli.ContainerCreate(ctx, conConfig, nil, nil, "")
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer c.cli.ContainerRemove(ctx, ncon.ID, types.ContainerRemoveOptions{})
|
|
|
+
|
|
|
+ rd, p, err := c.cli.CopyFromContainer(ctx, ncon.ID, src)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer rd.Close()
|
|
|
+ log.Println("Copy:", p)
|
|
|
+
|
|
|
+ dstStat, err := os.Stat(dst)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if dstStat.IsDir() {
|
|
|
+ dst = path.Join(dst, p.Name)
|
|
|
+ log.Println("Desitnation is dir, adding path", dst)
|
|
|
+ }
|
|
|
+
|
|
|
+ f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, p.Mode)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ io.Copy(f, rd)
|
|
|
+ f.Sync()
|
|
|
+ f.Close()
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func RunContainerX(imageName string, containerName string, command []string) error {
|
|
|
log := prettylog.New("RUN CONTAINER")
|
|
|
|
|
|
cli, err := docker.NewEnvClient()
|
|
@@ -41,29 +138,41 @@ func RunContainerX(imageName string, containerName string, command string) error
|
|
|
}
|
|
|
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))
|
|
|
+
|
|
|
+ var imgRes types.IDResponse
|
|
|
+ var ncon container.ContainerCreateCreatedBody
|
|
|
+
|
|
|
+ s := seq.NewSeq()
|
|
|
+ s.Add("Commit", func() error {
|
|
|
+ var err error
|
|
|
+ imgRes, err = cli.ContainerCommit(ctx, containerName, types.ContainerCommitOptions{Config: res.Config})
|
|
|
+ return err
|
|
|
+ })
|
|
|
+
|
|
|
+ s.Add("Tag", func() error { return cli.ImageTag(ctx, imgRes.ID, imageName+"build-1") })
|
|
|
+
|
|
|
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 {
|
|
|
+ s.Add("Create", func() (container.ContainerCreateCreatedBody, error) {
|
|
|
+ return cli.ContainerCreate(ctx, &container.Config{Image: imgRes.ID, Cmd: command}, res.HostConfig, nil, res.Name)
|
|
|
+ }).Grab(&ncon)
|
|
|
+
|
|
|
+ s.Add("Start", func() error {
|
|
|
return cli.ContainerStart(ctx, ncon.ID, types.ContainerStartOptions{})
|
|
|
- }, seq.SeqReturn(3, 0))
|
|
|
- s.Add("Wait", func(ncon container.ContainerCreateCreatedBody) (int64, error) {
|
|
|
+ })
|
|
|
+ s.Add("Wait", func() (int64, error) {
|
|
|
return cli.ContainerWait(ctx, ncon.ID)
|
|
|
- }, seq.SeqReturn(3, 0))
|
|
|
- s.Add("Copy", func(ncon container.ContainerCreateCreatedBody) (io.ReadCloser, types.ContainerPathStat, error) {
|
|
|
+ })
|
|
|
+ var rd io.ReadCloser
|
|
|
+ s.Add("Copy", func() (io.ReadCloser, types.ContainerPathStat, error) {
|
|
|
return cli.CopyFromContainer(ctx, ncon.ID, "/buildme/dist.tar.gz")
|
|
|
- }, seq.SeqReturn(3, 0))
|
|
|
+ }).Grab(&rd)
|
|
|
|
|
|
- s.Add("Save", func(rd io.ReadCloser) error {
|
|
|
+ s.Add("Save", func() 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 {
|
|
@@ -72,7 +181,7 @@ func RunContainerX(imageName string, containerName string, command string) error
|
|
|
|
|
|
} else {
|
|
|
log.Println("ContainerExecCreate")
|
|
|
- r, err := cli.ContainerExecCreate(ctx, containerName, types.ExecConfig{Cmd: utils.ParseField(command)})
|
|
|
+ r, err := cli.ContainerExecCreate(ctx, containerName, types.ExecConfig{Cmd: command})
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -122,32 +231,34 @@ func RunContainer(imageName string, containerName string, command string) error
|
|
|
|
|
|
//nImageName := containerName + "-tmp"
|
|
|
log.Println("Container commit to")
|
|
|
- imgRes, err := cli.ContainerCommit(ctx, containerName, types.ContainerCommitOptions{Config: res.Config})
|
|
|
- if err != nil {
|
|
|
+ var err error
|
|
|
+ var imgRes types.IDResponse
|
|
|
+
|
|
|
+ if imgRes, err = cli.ContainerCommit(ctx, containerName, types.ContainerCommitOptions{Config: res.Config}); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if err = cli.ImageTag(ctx, imgRes.ID, imageName+"build-1"); 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 {
|
|
|
+ if err = cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{}); 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 {
|
|
|
+ var ncon container.ContainerCreateCreatedBody
|
|
|
+ if ncon, err = cli.ContainerCreate(ctx, &container.Config{Image: imgRes.ID, Cmd: utils.ParseField(command)}, res.HostConfig, nil, res.Name); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- log.Println("Starting the created container timeout was:", timeout)
|
|
|
- err = cli.ContainerStart(ctx, ncon.ID, types.ContainerStartOptions{})
|
|
|
- if err != nil {
|
|
|
+
|
|
|
+ if err = cli.ContainerStart(ctx, ncon.ID, types.ContainerStartOptions{}); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- ret, err := cli.ContainerWait(ctx, ncon.ID)
|
|
|
- if err != nil {
|
|
|
+
|
|
|
+ var ret int64
|
|
|
+ if ret, err = cli.ContainerWait(ctx, ncon.ID); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
log.Println("Returning withcode:", ret)
|
|
@@ -232,70 +343,3 @@ func RunImageCmd(image string, command string) error {
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
-
|
|
|
-/*
|
|
|
-func DockerBuild(p *Project) error {
|
|
|
- log.Println("New docker environ")
|
|
|
- cli, err := docker.NewEnvClient()
|
|
|
- if err != nil {
|
|
|
- log.Println("Docker failed", err)
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- dockertag := fmt.Sprintf("%s-builder", p.conf.Meta.Project)
|
|
|
- log.Println("Building and tagging:", dockertag)
|
|
|
- ///////////////
|
|
|
- /// DOCKER OPERATION / BUILDER operation
|
|
|
- ctx := context.Background()
|
|
|
- {
|
|
|
- log.Println("Docker image build dockerfile:", p.Dockerfile)
|
|
|
- imageRes, err := cli.ImageBuild(ctx, p.Reader(), types.ImageBuildOptions{Tags: []string{dockertag}, Dockerfile: p.Dockerfile})
|
|
|
- if err != nil {
|
|
|
- log.Println("Error building image:", err)
|
|
|
- return err
|
|
|
- }
|
|
|
- defer imageRes.Body.Close()
|
|
|
- io.Copy(os.Stdout, imageRes.Body) // Do some treatment somehow
|
|
|
- //inf, err := cli.Info(ctx)
|
|
|
- //log.Println("Info:", inf, err)
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- log.Println("Testing running the builder")
|
|
|
- containerName := dockertag
|
|
|
- containerCfg := &container.Config{AttachStdout: true, Cmd: []string{"cat", "/buildme/dist.tar.gz"}}
|
|
|
- res, err := cli.ContainerCreate(ctx, containerCfg, nil, nil, containerName)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- log.Println("Created container ID:", res)
|
|
|
- log.Println("Starting container test")
|
|
|
-
|
|
|
- cr, _, err := cli.CopyFromContainer(ctx, res.ID, "/buildme/dist.tar.gz")
|
|
|
- if err != nil {
|
|
|
- log.Println("Copy error", err)
|
|
|
- return err
|
|
|
- }
|
|
|
- defer cr.Close()
|
|
|
-
|
|
|
- log.Println("Creating writing file")
|
|
|
- f, err := os.OpenFile("test.tar.gz", os.O_CREATE|os.O_WRONLY, os.FileMode(0600))
|
|
|
- if err != nil {
|
|
|
- log.Println("Error opening file", err)
|
|
|
- return err
|
|
|
- }
|
|
|
- defer f.Close()
|
|
|
-
|
|
|
- io.Copy(f, cr)
|
|
|
- f.Sync()
|
|
|
-
|
|
|
-
|
|
|
- log.Println("Please execute docker run", containerName, "> dist.tar.gz")
|
|
|
- log.Println("Trying to remove container", res)
|
|
|
- err = cli.ContainerRemove(ctx, res.ID, types.ContainerRemoveOptions{})
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
-}*/
|