Quellcode durchsuchen

Added sequencer

luisf vor 8 Jahren
Ursprung
Commit
e018695f5f

+ 1 - 1
Makefile

@@ -17,7 +17,7 @@ clean:
 	rm -rf DIST 
 
 distclean: clean
-	rm -rf .deps
+	rm -rf deps
 	rm -rf bin
 	rm -rf pkg
 

+ 2 - 1
buildme.yml

@@ -8,7 +8,8 @@ images:
 tasks:
   build:
     use: builder
-    command: make dist
+    command: 
+      - make dist
     copy: /dist.tar.gz ./test.tar.gz
 
 

+ 3 - 2
src/buildme/cmd/builder/main.go

@@ -46,10 +46,11 @@ func main() {
 	}
 	buildme.Prepare(proj) //XXX: This will change
 	err = proj.Task("build")
-
-	/*err = buildme.Build(fetchType, fetchPath, fetchName)*/
 	if err != nil {
 		log.Println("Error building", err)
 	}
+	proj.Close()
+
+	/*err = buildme.Build(fetchType, fetchPath, fetchName)*/
 
 }

+ 233 - 0
src/buildme/docker.go

@@ -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")

+ 17 - 46
src/buildme/project.go

@@ -2,7 +2,6 @@ package buildme
 
 import (
 	"bufio"
-	"buildme/utils"
 	"context"
 	"encoding/json"
 	"fmt"
@@ -11,7 +10,6 @@ import (
 	"strings"
 
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/container"
 	docker "github.com/docker/docker/client"
 )
 
@@ -113,13 +111,8 @@ func (p *Project) Task(name string) error {
 			log.Println("Container FOUND state:", r.State)
 		}*/
 		// Execute inside container
-		dbuildOptions := types.ImageBuildOptions{
-			Tags:        []string{dockerTag},
-			Dockerfile:  imgconf.Dockerfile,
-			ForceRemove: true,
-		}
-
-		res, err := cli.ImageBuild(ctx, p.Reader(), dbuildOptions)
+		log.Println("===== Building IMAGE")
+		res, err := cli.ImageBuild(ctx, p.Reader(), types.ImageBuildOptions{Tags: []string{dockerTag}, Dockerfile: imgconf.Dockerfile, Remove: true})
 		if err != nil {
 			return err
 		}
@@ -143,48 +136,26 @@ func (p *Project) Task(name string) error {
 		}
 		// Just output
 	}
-	{
-		log.Println("Testing running the builder")
-		containerCfg := &container.Config{Image: dockerTag, AttachStdout: true, Cmd: utils.ParseField(taskconf.Command)}
-		containerRes, err := cli.ContainerCreate(ctx, containerCfg, nil, nil, dockerTag)
-		if err != nil {
-			return err
-		}
-		// Remove container after finish
-		defer cli.ContainerRemove(ctx, containerRes.ID, types.ContainerRemoveOptions{})
-
-		log.Println("Created container ID:", containerRes.ID, "with image: ", dockerTag)
-		log.Println(" ============= Starting container")
-		err = cli.ContainerStart(ctx, containerRes.ID, types.ContainerStartOptions{})
-		if err != nil {
-			return err
-		}
-
-		log.Println("Commit container")
-		log.Println("============= Commiting container")
-		_, err = cli.ContainerCommit(ctx, containerRes.ID, types.ContainerCommitOptions{Config: containerCfg})
-		if err != nil {
-			return err
-		}
 
-		// Artifact??
-		/*cr, _, err := cli.CopyFromContainer(ctx, res.ID, "/buildme/dist.tar.gz")
-		if err != nil {
-			log.Println("Copy error", err)
-			return err
-		}
-		defer cr.Close()
+	/*containerCfg := &container.Config{
+		Image: dockerTag,
+		Cmd:   []string{"ls"},
+	}
+	log.Println("===> Creating container")
+	containerRes, err := cli.ContainerCreate(ctx, containerCfg, nil, nil, dockerTag)
+	if err != nil {
+		return err
+	}
+	_ = containerRes*/
 
-		log.Println("Creating writing file")
-		f, err := os.OpenFile("test.tar.gz", os.O_CREATE|os.O_WRONLY, os.FileMode(0600))
+	log.Println("Executing commands")
+	// Builds image
+	for _, cmd := range taskconf.Command {
+		log.Println("Exec:", cmd)
+		err = RunContainerX(dockerTag, dockerTag, cmd)
 		if err != nil {
-			log.Println("Error opening file", err)
 			return err
 		}
-		defer f.Close()
-
-		io.Copy(f, cr)
-		f.Sync()*/
 	}
 
 	return nil

+ 2 - 2
src/buildme/project_conf.go

@@ -12,7 +12,7 @@ type ImageConf struct {
 }
 
 type TaskConf struct {
-	Use     string `yaml:"use"`
-	Command string `yaml:"command"`
+	Use     string   `yaml:"use"`
+	Command []string `yaml:"command"`
 	//Copy after run
 }

+ 11 - 0
src/buildme/utils/error.go

@@ -0,0 +1,11 @@
+package utils
+
+func ErrChecker(r ...interface{}) []interface{} {
+	for _, v := range r {
+		_, ok := v.(error)
+		if ok {
+			panic(v)
+		}
+	}
+	return r
+}

+ 58 - 0
src/buildme/utils/seq.go

@@ -0,0 +1,58 @@
+package utils
+
+import "reflect"
+
+type seqEntry struct {
+	fn     interface{} // Function
+	fnVal  reflect.Value
+	params []interface{}
+
+	res []reflect.Value
+}
+
+type Seq struct {
+	seq []seqEntry
+}
+
+func NewSeq() *Seq {
+	return &Seq{[]seqEntry{}}
+}
+
+func (s *Seq) Add(fn interface{}, params ...interface{}) {
+	fnTyp := reflect.TypeOf(fn)
+	fnVal := reflect.ValueOf(fn)
+	if fnTyp.Kind() != reflect.Func {
+		log.Fatal("First paran should be a func")
+	}
+	if fnTyp.NumIn() != len(params) {
+		log.Fatal("Param len mismatch required")
+	}
+
+	if reflect.TypeOf(fn).Kind() != reflect.Func {
+		panic("First param should be a function")
+
+	}
+	s.seq = append(s.seq, seqEntry{fn: fn, fnVal: fnVal, params: params, res: []reflect.Value{}})
+}
+
+func (s *Seq) Exec() error {
+	for _, v := range s.seq {
+		vVal := reflect.ValueOf(v)
+		vparam := []reflect.Value{}
+		for _, p := range v.params {
+			vparam = append(vparam, reflect.ValueOf(p))
+		}
+		v.res = vVal.Call(vparam)
+
+		for _, r := range v.res {
+			err, ok := r.Interface().(error)
+			if ok {
+				log.Println("Error in a func:", err)
+				// We got error
+				return err
+			}
+		}
+	}
+
+	return nil
+}

+ 1 - 4
src/buildme/utils/string.go

@@ -1,21 +1,18 @@
 package utils
 
 import (
-	"log"
 	"regexp"
 	"strings"
 )
 
 // Smart splitter
-
+//ParseField
 func ParseField(s string) []string {
 	res := []string{}
 
 	re := regexp.MustCompile("[^\\\\]\"") // Non escaped '"'
 
 	fparts := re.Split(s, -1)
-	log.Println("Field parts", fparts)
-
 	for i, v := range fparts {
 		if i&0x1 == 1 { // Even
 			res = append(res, v)

+ 7 - 0
src/buildme/utils/utils.go

@@ -0,0 +1,7 @@
+package utils
+
+import "dev.hexasoftware.com/hxs/prettylog"
+
+var (
+	log = prettylog.New("utils")
+)