From bebde3a2ea9f49c7da5ed8a7e7123c51ecf87d1e Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Wed, 25 Jul 2018 16:17:05 +0100 Subject: [PATCH] cmd/pkg: Build a build context from 'sources' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the final piece. If 'sources' are defined, tar up the sources and rewrite them accordingly. Pass it as build build context to 'docker'. This allows building from something like this: ├── etc │   ├── foo └── foo ├── Dockerfile ├── build.yml └── main.go With 'build.yml': image: foo extra-sources: - ../etc:etc Signed-off-by: Rolf Neugebauer --- src/cmd/linuxkit/pkglib/build.go | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/cmd/linuxkit/pkglib/build.go b/src/cmd/linuxkit/pkglib/build.go index fee17a572..9a8567efc 100644 --- a/src/cmd/linuxkit/pkglib/build.go +++ b/src/cmd/linuxkit/pkglib/build.go @@ -1,12 +1,18 @@ package pkglib import ( + "archive/tar" "encoding/json" "fmt" + "io" "os" + "path" + "path/filepath" "runtime" + "strings" "github.com/linuxkit/linuxkit/src/cmd/linuxkit/version" + log "github.com/sirupsen/logrus" ) type buildOpts struct { @@ -141,6 +147,8 @@ func (p Pkg) Build(bos ...BuildOpt) error { args = append(args, "--label=org.mobyproject.linuxkit.version="+version.Version) args = append(args, "--label=org.mobyproject.linuxkit.revision="+version.GitCommit) + d.ctx = &buildCtx{sources: p.sources} + if err := d.build(p.Tag()+suffix, p.path, args...); err != nil { return err } @@ -191,3 +199,59 @@ func (p Pkg) Build(bos ...BuildOpt) error { return nil } + +type buildCtx struct { + sources []pkgSource +} + +// Copy iterates over the sources, tars up the content after rewriting the paths. +// It assumes that sources is sane, ie is well formed and the first part is an absolute path +// and that it exists. NewFromCLI() ensures that. +func (c *buildCtx) Copy(w io.WriteCloser) error { + tw := tar.NewWriter(w) + defer func() { + tw.Close() + w.Close() + }() + + for _, s := range c.sources { + log.Debugf("Adding to build context: %s -> %s", s.src, s.dst) + + f := func(p string, i os.FileInfo, err error) error { + if err != nil { + return fmt.Errorf("ctx: Walk error on %s: %v", p, err) + } + + h, err := tar.FileInfoHeader(i, "") + if err != nil { + return fmt.Errorf("ctx: Converting FileInfo for %s: %v", p, err) + } + h.Name = path.Join(s.dst, strings.TrimPrefix(p, s.src)) + if err := tw.WriteHeader(h); err != nil { + return fmt.Errorf("ctx: Writing header for %s: %v", p, err) + } + + if !i.Mode().IsRegular() { + return nil + } + + f, err := os.Open(p) + if err != nil { + return fmt.Errorf("ctx: Open %s: %v", p, err) + } + defer f.Close() + + _, err = io.Copy(tw, f) + if err != nil { + return fmt.Errorf("ctx: Writing %s: %v", p, err) + } + return nil + } + + if err := filepath.Walk(s.src, f); err != nil { + return err + } + } + + return nil +}