Add a build package (#1926)

* Add a build package

* fix go mod

* package tar
This commit is contained in:
Asim Aslam
2020-08-11 16:51:58 +01:00
committed by GitHub
parent e162e6d505
commit fae4151027
13 changed files with 298 additions and 74 deletions

View File

@@ -1,34 +0,0 @@
// Package build builds a micro runtime package
package build
import (
"github.com/micro/go-micro/v3/runtime/local/source"
)
// Builder builds binaries
type Builder interface {
// Build builds a package
Build(*Source) (*Package, error)
// Clean deletes the package
Clean(*Package) error
}
// Source is the source of a build
type Source struct {
// Language is the language of code
Language string
// Location of the source
Repository *source.Repository
}
// Package is micro service package
type Package struct {
// Name of the binary
Name string
// Location of the binary
Path string
// Type of binary
Type string
// Source of the binary
Source *Source
}

View File

@@ -1,93 +0,0 @@
// Package docker builds docker images
package docker
import (
"archive/tar"
"bytes"
"io/ioutil"
"os"
"path/filepath"
docker "github.com/fsouza/go-dockerclient"
"github.com/micro/go-micro/v3/logger"
"github.com/micro/go-micro/v3/runtime/local/build"
)
type Builder struct {
Options build.Options
Client *docker.Client
}
func (d *Builder) Build(s *build.Source) (*build.Package, error) {
image := filepath.Join(s.Repository.Path, s.Repository.Name)
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
defer tw.Close()
dockerFile := "Dockerfile"
// open docker file
f, err := os.Open(filepath.Join(s.Repository.Path, s.Repository.Name, dockerFile))
if err != nil {
return nil, err
}
// read docker file
by, err := ioutil.ReadAll(f)
if err != nil {
return nil, err
}
tarHeader := &tar.Header{
Name: dockerFile,
Size: int64(len(by)),
}
err = tw.WriteHeader(tarHeader)
if err != nil {
return nil, err
}
_, err = tw.Write(by)
if err != nil {
return nil, err
}
tr := bytes.NewReader(buf.Bytes())
err = d.Client.BuildImage(docker.BuildImageOptions{
Name: image,
Dockerfile: dockerFile,
InputStream: tr,
OutputStream: ioutil.Discard,
RmTmpContainer: true,
SuppressOutput: true,
})
if err != nil {
return nil, err
}
return &build.Package{
Name: image,
Path: image,
Type: "docker",
Source: s,
}, nil
}
func (d *Builder) Clean(b *build.Package) error {
image := filepath.Join(b.Path, b.Name)
return d.Client.RemoveImage(image)
}
func NewBuilder(opts ...build.Option) build.Builder {
options := build.Options{}
for _, o := range opts {
o(&options)
}
endpoint := "unix:///var/run/docker.sock"
client, err := docker.NewClient(endpoint)
if err != nil {
logger.Fatal(err)
}
return &Builder{
Options: options,
Client: client,
}
}

View File

@@ -1,70 +0,0 @@
// Package golang is a go package manager
package golang
import (
"os"
"os/exec"
"path/filepath"
"github.com/micro/go-micro/v3/runtime/local/build"
)
type Builder struct {
Options build.Options
Cmd string
Path string
}
// whichGo locates the go command
func whichGo() string {
// check GOROOT
if gr := os.Getenv("GOROOT"); len(gr) > 0 {
return filepath.Join(gr, "bin", "go")
}
// check path
for _, p := range filepath.SplitList(os.Getenv("PATH")) {
bin := filepath.Join(p, "go")
if _, err := os.Stat(bin); err == nil {
return bin
}
}
// best effort
return "go"
}
func (g *Builder) Build(s *build.Source) (*build.Package, error) {
binary := filepath.Join(g.Path, s.Repository.Name)
source := filepath.Join(s.Repository.Path, s.Repository.Name)
cmd := exec.Command(g.Cmd, "build", "-o", binary, source)
if err := cmd.Run(); err != nil {
return nil, err
}
return &build.Package{
Name: s.Repository.Name,
Path: binary,
Type: "go",
Source: s,
}, nil
}
func (g *Builder) Clean(b *build.Package) error {
binary := filepath.Join(b.Path, b.Name)
return os.Remove(binary)
}
func NewBuild(opts ...build.Option) build.Builder {
options := build.Options{
Path: os.TempDir(),
}
for _, o := range opts {
o(&options)
}
return &Builder{
Options: options,
Cmd: whichGo(),
Path: options.Path,
}
}

View File

@@ -1,15 +0,0 @@
package build
type Options struct {
// local path to download source
Path string
}
type Option func(o *Options)
// Local path for repository
func Path(p string) Option {
return func(o *Options) {
o.Path = p
}
}

View File

@@ -13,13 +13,13 @@ import (
"github.com/micro/go-micro/v3/runtime/local/process"
)
func (p *Process) Exec(exe *process.Executable) error {
func (p *Process) Exec(exe *process.Binary) error {
cmd := exec.Command(exe.Package.Path)
cmd.Dir = exe.Dir
return cmd.Run()
}
func (p *Process) Fork(exe *process.Executable) (*process.PID, error) {
func (p *Process) Fork(exe *process.Binary) (*process.PID, error) {
// create command
cmd := exec.Command(exe.Package.Path, exe.Args...)

View File

@@ -4,22 +4,22 @@ package process
import (
"io"
"github.com/micro/go-micro/v3/runtime/local/build"
"github.com/micro/go-micro/v3/build"
)
// Process manages a running process
type Process interface {
// Executes a process to completion
Exec(*Executable) error
Exec(*Binary) error
// Creates a new process
Fork(*Executable) (*PID, error)
Fork(*Binary) (*PID, error)
// Kills the process
Kill(*PID) error
// Waits for a process to exit
Wait(*PID) error
}
type Executable struct {
type Binary struct {
// Package containing executable
Package *build.Package
// The env variables

View File

@@ -9,9 +9,9 @@ import (
"sync"
"time"
"github.com/micro/go-micro/v3/build"
"github.com/micro/go-micro/v3/logger"
"github.com/micro/go-micro/v3/runtime"
"github.com/micro/go-micro/v3/runtime/local/build"
"github.com/micro/go-micro/v3/runtime/local/process"
proc "github.com/micro/go-micro/v3/runtime/local/process/os"
)
@@ -35,7 +35,7 @@ type service struct {
// process creator
Process *proc.Process
// Exec
Exec *process.Executable
Exec *process.Binary
// process pid
PID *process.PID
}
@@ -72,7 +72,7 @@ func newService(s *runtime.Service, c runtime.CreateOptions) *service {
return &service{
Service: s,
Process: new(proc.Process),
Exec: &process.Executable{
Exec: &process.Binary{
Package: &build.Package{
Name: s.Name,
Path: exec,