From e3d8e79d9569f3e328facac7978ed3c2ad786eb7 Mon Sep 17 00:00:00 2001 From: Qi Wang Date: Mon, 11 Mar 2019 12:14:29 -0400 Subject: move formats pkg to and vendor from buildah Signed-off-by: Qi Wang --- cmd/podman/diff.go | 2 +- cmd/podman/formats/formats.go | 171 --------------------- cmd/podman/formats/formats_test.go | 42 ----- cmd/podman/formats/templates.go | 78 ---------- cmd/podman/history.go | 2 +- cmd/podman/images.go | 2 +- cmd/podman/info.go | 2 +- cmd/podman/inspect.go | 2 +- cmd/podman/mount.go | 2 +- cmd/podman/pod_ps.go | 2 +- cmd/podman/pod_stats.go | 2 +- cmd/podman/ps.go | 2 +- cmd/podman/search.go | 2 +- cmd/podman/stats.go | 2 +- cmd/podman/trust_set_show.go | 2 +- cmd/podman/version.go | 2 +- cmd/podman/volume_ls.go | 2 +- vendor.conf | 2 +- .../containers/buildah/imagebuildah/build.go | 2 +- .../buildah/imagebuildah/chroot_symlink.go | 10 +- .../containers/buildah/pkg/formats/formats.go | 171 +++++++++++++++++++++ .../containers/buildah/pkg/formats/templates.go | 78 ++++++++++ vendor/github.com/containers/buildah/run.go | 90 ++++++----- 23 files changed, 323 insertions(+), 349 deletions(-) delete mode 100644 cmd/podman/formats/formats.go delete mode 100644 cmd/podman/formats/formats_test.go delete mode 100644 cmd/podman/formats/templates.go create mode 100644 vendor/github.com/containers/buildah/pkg/formats/formats.go create mode 100644 vendor/github.com/containers/buildah/pkg/formats/templates.go diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index bd3a985b7..e77e562d4 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -2,8 +2,8 @@ package main import ( "fmt" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" diff --git a/cmd/podman/formats/formats.go b/cmd/podman/formats/formats.go deleted file mode 100644 index 37f9b8a20..000000000 --- a/cmd/podman/formats/formats.go +++ /dev/null @@ -1,171 +0,0 @@ -package formats - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "os" - "strings" - "text/tabwriter" - "text/template" - - "github.com/ghodss/yaml" - "github.com/pkg/errors" - "golang.org/x/crypto/ssh/terminal" -) - -const ( - // JSONString const to save on duplicate variable names - JSONString = "json" - // IDString const to save on duplicates for Go templates - IDString = "{{.ID}}" - - parsingErrorStr = "Template parsing error" -) - -// Writer interface for outputs -type Writer interface { - Out() error -} - -// JSONStructArray for JSON output -type JSONStructArray struct { - Output []interface{} -} - -// StdoutTemplateArray for Go template output -type StdoutTemplateArray struct { - Output []interface{} - Template string - Fields map[string]string -} - -// JSONStruct for JSON output -type JSONStruct struct { - Output interface{} -} - -// StdoutTemplate for Go template output -type StdoutTemplate struct { - Output interface{} - Template string - Fields map[string]string -} - -// YAMLStruct for YAML output -type YAMLStruct struct { - Output interface{} -} - -func setJSONFormatEncoder(isTerminal bool, w io.Writer) *json.Encoder { - enc := json.NewEncoder(w) - enc.SetIndent("", " ") - if isTerminal { - enc.SetEscapeHTML(false) - } - return enc -} - -// Out method for JSON Arrays -func (j JSONStructArray) Out() error { - buf := bytes.NewBuffer(nil) - enc := setJSONFormatEncoder(terminal.IsTerminal(int(os.Stdout.Fd())), buf) - if err := enc.Encode(j.Output); err != nil { - return err - } - data := buf.Bytes() - - // JSON returns a byte array with a literal null [110 117 108 108] in it - // if it is passed empty data. We used bytes.Compare to see if that is - // the case. - if diff := bytes.Compare(data, []byte("null")); diff == 0 { - data = []byte("[]") - } - - // If the we did get NULL back, we should spit out {} which is - // at least valid JSON for the consumer. - fmt.Printf("%s", data) - humanNewLine() - return nil -} - -// Out method for Go templates -func (t StdoutTemplateArray) Out() error { - w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) - if strings.HasPrefix(t.Template, "table") { - // replace any spaces with tabs in template so that tabwriter can align it - t.Template = strings.Replace(strings.TrimSpace(t.Template[5:]), " ", "\t", -1) - headerTmpl, err := template.New("header").Funcs(headerFunctions).Parse(t.Template) - if err != nil { - return errors.Wrapf(err, parsingErrorStr) - } - err = headerTmpl.Execute(w, t.Fields) - if err != nil { - return err - } - fmt.Fprintln(w, "") - } - t.Template = strings.Replace(t.Template, " ", "\t", -1) - tmpl, err := template.New("image").Funcs(basicFunctions).Parse(t.Template) - if err != nil { - return errors.Wrapf(err, parsingErrorStr) - } - for i, raw := range t.Output { - basicTmpl := tmpl.Funcs(basicFunctions) - if err := basicTmpl.Execute(w, raw); err != nil { - return errors.Wrapf(err, parsingErrorStr) - } - if i != len(t.Output)-1 { - fmt.Fprintln(w, "") - continue - } - } - fmt.Fprintln(w, "") - return w.Flush() -} - -// Out method for JSON struct -func (j JSONStruct) Out() error { - data, err := json.MarshalIndent(j.Output, "", " ") - if err != nil { - return err - } - fmt.Printf("%s", data) - humanNewLine() - return nil -} - -//Out method for Go templates -func (t StdoutTemplate) Out() error { - tmpl, err := template.New("image").Parse(t.Template) - if err != nil { - return errors.Wrapf(err, "template parsing error") - } - err = tmpl.Execute(os.Stdout, t.Output) - if err != nil { - return err - } - humanNewLine() - return nil -} - -// Out method for YAML -func (y YAMLStruct) Out() error { - var buf []byte - var err error - buf, err = yaml.Marshal(y.Output) - if err != nil { - return err - } - fmt.Printf("%s", string(buf)) - humanNewLine() - return nil -} - -// humanNewLine prints a new line at the end of the output only if stdout is the terminal -func humanNewLine() { - if terminal.IsTerminal(int(os.Stdout.Fd())) { - fmt.Println() - } -} diff --git a/cmd/podman/formats/formats_test.go b/cmd/podman/formats/formats_test.go deleted file mode 100644 index c75109d65..000000000 --- a/cmd/podman/formats/formats_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package formats - -import ( - "bytes" - "strings" - "testing" - - "github.com/containers/libpod/pkg/inspect" -) - -func TestSetJSONFormatEncoder(t *testing.T) { - tt := []struct { - name string - imageData *inspect.ImageData - expected string - isTerminal bool - }{ - { - name: "HTML tags are not escaped", - imageData: &inspect.ImageData{Author: "dave "}, - expected: `"Author": "dave "`, - isTerminal: true, - }, - { - name: "HTML tags are escaped", - imageData: &inspect.ImageData{Author: "dave "}, - expected: `"Author": "dave \u003cdave@corp.io\u003e"`, - isTerminal: false, - }, - } - - for _, tc := range tt { - buf := bytes.NewBuffer(nil) - enc := setJSONFormatEncoder(tc.isTerminal, buf) - if err := enc.Encode(tc.imageData); err != nil { - t.Errorf("test %#v failed encoding: %s", tc.name, err) - } - if !strings.Contains(buf.String(), tc.expected) { - t.Errorf("test %#v expected output to contain %#v. Output:\n%v\n", tc.name, tc.expected, buf.String()) - } - } -} diff --git a/cmd/podman/formats/templates.go b/cmd/podman/formats/templates.go deleted file mode 100644 index c2582552a..000000000 --- a/cmd/podman/formats/templates.go +++ /dev/null @@ -1,78 +0,0 @@ -package formats - -import ( - "bytes" - "encoding/json" - "strings" - "text/template" -) - -// basicFunctions are the set of initial -// functions provided to every template. -var basicFunctions = template.FuncMap{ - "json": func(v interface{}) string { - buf := &bytes.Buffer{} - enc := json.NewEncoder(buf) - enc.SetEscapeHTML(false) - _ = enc.Encode(v) - // Remove the trailing new line added by the encoder - return strings.TrimSpace(buf.String()) - }, - "split": strings.Split, - "join": strings.Join, - "title": strings.Title, - "lower": strings.ToLower, - "upper": strings.ToUpper, - "pad": padWithSpace, - "truncate": truncateWithLength, -} - -// HeaderFunctions are used to created headers of a table. -// This is a replacement of basicFunctions for header generation -// because we want the header to remain intact. -// Some functions like `split` are irrelevant so not added. -var headerFunctions = template.FuncMap{ - "json": func(v string) string { - return v - }, - "title": func(v string) string { - return v - }, - "lower": func(v string) string { - return v - }, - "upper": func(v string) string { - return v - }, - "truncate": func(v string, l int) string { - return v - }, -} - -// Parse creates a new anonymous template with the basic functions -// and parses the given format. -func Parse(format string) (*template.Template, error) { - return NewParse("", format) -} - -// NewParse creates a new tagged template with the basic functions -// and parses the given format. -func NewParse(tag, format string) (*template.Template, error) { - return template.New(tag).Funcs(basicFunctions).Parse(format) -} - -// padWithSpace adds whitespace to the input if the input is non-empty -func padWithSpace(source string, prefix, suffix int) string { - if source == "" { - return source - } - return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix) -} - -// truncateWithLength truncates the source string up to the length provided by the input -func truncateWithLength(source string, length int) string { - if len(source) < length { - return source - } - return source[:length] -} diff --git a/cmd/podman/history.go b/cmd/podman/history.go index f6cfe91b6..4b76ef0ca 100644 --- a/cmd/podman/history.go +++ b/cmd/podman/history.go @@ -6,8 +6,8 @@ import ( "strings" "time" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/adapter" "github.com/docker/go-units" diff --git a/cmd/podman/images.go b/cmd/podman/images.go index f92e5d44d..6133450be 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -9,8 +9,8 @@ import ( "time" "unicode" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/imagefilters" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/adapter" diff --git a/cmd/podman/info.go b/cmd/podman/info.go index de20eb009..195267c7f 100644 --- a/cmd/podman/info.go +++ b/cmd/podman/info.go @@ -4,8 +4,8 @@ import ( "fmt" rt "runtime" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/version" diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index 0af96088f..e14f25c24 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -5,8 +5,8 @@ import ( "encoding/json" "strings" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/pkg/adapter" cc "github.com/containers/libpod/pkg/spec" diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go index c5b7e2404..4381074ab 100644 --- a/cmd/podman/mount.go +++ b/cmd/podman/mount.go @@ -5,8 +5,8 @@ import ( "fmt" "os" + of "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - of "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go index e30a03005..a956882cf 100644 --- a/cmd/podman/pod_ps.go +++ b/cmd/podman/pod_ps.go @@ -8,8 +8,8 @@ import ( "strings" "time" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/adapter" diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go index 5c30e0595..701051938 100644 --- a/cmd/podman/pod_stats.go +++ b/cmd/podman/pod_stats.go @@ -11,8 +11,8 @@ import ( "encoding/json" tm "github.com/buger/goterm" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 6caac2406..de6966c3b 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -12,8 +12,8 @@ import ( "text/tabwriter" "time" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" diff --git a/cmd/podman/search.go b/cmd/podman/search.go index e508c2bcf..25f5a98b7 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -3,9 +3,9 @@ package main import ( "strings" + "github.com/containers/buildah/pkg/formats" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/libpod/image" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go index 3e2e114a9..d379dbad7 100644 --- a/cmd/podman/stats.go +++ b/cmd/podman/stats.go @@ -8,8 +8,8 @@ import ( "time" tm "github.com/buger/goterm" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" "github.com/docker/go-units" diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go index 5a70c21cc..d7a4ea6d6 100644 --- a/cmd/podman/trust_set_show.go +++ b/cmd/podman/trust_set_show.go @@ -7,9 +7,9 @@ import ( "sort" "strings" + "github.com/containers/buildah/pkg/formats" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/trust" diff --git a/cmd/podman/version.go b/cmd/podman/version.go index b3615ce23..336be892e 100644 --- a/cmd/podman/version.go +++ b/cmd/podman/version.go @@ -6,8 +6,8 @@ import ( "text/tabwriter" "time" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/libpod" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/cmd/podman/volume_ls.go b/cmd/podman/volume_ls.go index 5a36f4f7d..2f35462a3 100644 --- a/cmd/podman/volume_ls.go +++ b/cmd/podman/volume_ls.go @@ -4,8 +4,8 @@ import ( "reflect" "strings" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/vendor.conf b/vendor.conf index e7aec5e35..1fd60f701 100644 --- a/vendor.conf +++ b/vendor.conf @@ -93,7 +93,7 @@ k8s.io/apimachinery kubernetes-1.10.13-beta.0 https://github.com/kubernetes/apim k8s.io/client-go kubernetes-1.10.13-beta.0 https://github.com/kubernetes/client-go github.com/mrunalp/fileutils 7d4729fb36185a7c1719923406c9d40e54fb93c7 github.com/varlink/go 3ac79db6fd6aec70924193b090962f92985fe199 -github.com/containers/buildah 11dd2197dfffedb40687de1d667e6c9fb0708de9 +github.com/containers/buildah 345ffc2b29b4255a83cfa763db88799d8ec9c569 https://github.com/QiWang19/buildah # TODO: Gotty has not been updated since 2012. Can we find replacement? github.com/Nvveen/Gotty cd527374f1e5bff4938207604a14f2e38a9cf512 # do not go beyond the below commit as the next one requires a more recent diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go index d69eab52f..4f0ffac1c 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/build.go +++ b/vendor/github.com/containers/buildah/imagebuildah/build.go @@ -293,7 +293,7 @@ func (b *Executor) Preserve(path string) error { // Try and resolve the symlink (if one exists) // Set archivedPath and path based on whether a symlink is found or not - if symLink, err := ResolveSymLink(b.mountPoint, path); err == nil { + if symLink, err := resolveSymlink(b.mountPoint, path); err == nil { archivedPath = filepath.Join(b.mountPoint, symLink) path = symLink } else { diff --git a/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go b/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go index 6feedf6a5..86bf7653b 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go +++ b/vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go @@ -24,9 +24,7 @@ func init() { reexec.Register(symlinkModifiedTime, resolveSymlinkTimeModified) } -// main() for grandparent subprocess. Its main job is to shuttle stdio back -// and forth, managing a pseudo-terminal if we want one, for our child, the -// parent subprocess. +// main() for resolveSymlink()'s subprocess. func resolveChrootedSymlinks() { status := 0 flag.Parse() @@ -57,9 +55,9 @@ func resolveChrootedSymlinks() { os.Exit(status) } -// ResolveSymLink (in the grandparent process) resolves any symlink in filename +// resolveSymlink uses a child subprocess to resolve any symlinks in filename // in the context of rootdir. -func ResolveSymLink(rootdir, filename string) (string, error) { +func resolveSymlink(rootdir, filename string) (string, error) { // The child process expects a chroot and one path that // will be consulted relative to the chroot directory and evaluated // for any symbolic links present. @@ -253,7 +251,7 @@ func hasSymlink(path string) (bool, string, error) { } // if the symlink points to a relative path, prepend the path till now to the resolved path if !filepath.IsAbs(targetDir) { - targetDir = filepath.Join(path, targetDir) + targetDir = filepath.Join(filepath.Dir(path), targetDir) } // run filepath.Clean to remove the ".." from relative paths return true, filepath.Clean(targetDir), nil diff --git a/vendor/github.com/containers/buildah/pkg/formats/formats.go b/vendor/github.com/containers/buildah/pkg/formats/formats.go new file mode 100644 index 000000000..37f9b8a20 --- /dev/null +++ b/vendor/github.com/containers/buildah/pkg/formats/formats.go @@ -0,0 +1,171 @@ +package formats + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "strings" + "text/tabwriter" + "text/template" + + "github.com/ghodss/yaml" + "github.com/pkg/errors" + "golang.org/x/crypto/ssh/terminal" +) + +const ( + // JSONString const to save on duplicate variable names + JSONString = "json" + // IDString const to save on duplicates for Go templates + IDString = "{{.ID}}" + + parsingErrorStr = "Template parsing error" +) + +// Writer interface for outputs +type Writer interface { + Out() error +} + +// JSONStructArray for JSON output +type JSONStructArray struct { + Output []interface{} +} + +// StdoutTemplateArray for Go template output +type StdoutTemplateArray struct { + Output []interface{} + Template string + Fields map[string]string +} + +// JSONStruct for JSON output +type JSONStruct struct { + Output interface{} +} + +// StdoutTemplate for Go template output +type StdoutTemplate struct { + Output interface{} + Template string + Fields map[string]string +} + +// YAMLStruct for YAML output +type YAMLStruct struct { + Output interface{} +} + +func setJSONFormatEncoder(isTerminal bool, w io.Writer) *json.Encoder { + enc := json.NewEncoder(w) + enc.SetIndent("", " ") + if isTerminal { + enc.SetEscapeHTML(false) + } + return enc +} + +// Out method for JSON Arrays +func (j JSONStructArray) Out() error { + buf := bytes.NewBuffer(nil) + enc := setJSONFormatEncoder(terminal.IsTerminal(int(os.Stdout.Fd())), buf) + if err := enc.Encode(j.Output); err != nil { + return err + } + data := buf.Bytes() + + // JSON returns a byte array with a literal null [110 117 108 108] in it + // if it is passed empty data. We used bytes.Compare to see if that is + // the case. + if diff := bytes.Compare(data, []byte("null")); diff == 0 { + data = []byte("[]") + } + + // If the we did get NULL back, we should spit out {} which is + // at least valid JSON for the consumer. + fmt.Printf("%s", data) + humanNewLine() + return nil +} + +// Out method for Go templates +func (t StdoutTemplateArray) Out() error { + w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) + if strings.HasPrefix(t.Template, "table") { + // replace any spaces with tabs in template so that tabwriter can align it + t.Template = strings.Replace(strings.TrimSpace(t.Template[5:]), " ", "\t", -1) + headerTmpl, err := template.New("header").Funcs(headerFunctions).Parse(t.Template) + if err != nil { + return errors.Wrapf(err, parsingErrorStr) + } + err = headerTmpl.Execute(w, t.Fields) + if err != nil { + return err + } + fmt.Fprintln(w, "") + } + t.Template = strings.Replace(t.Template, " ", "\t", -1) + tmpl, err := template.New("image").Funcs(basicFunctions).Parse(t.Template) + if err != nil { + return errors.Wrapf(err, parsingErrorStr) + } + for i, raw := range t.Output { + basicTmpl := tmpl.Funcs(basicFunctions) + if err := basicTmpl.Execute(w, raw); err != nil { + return errors.Wrapf(err, parsingErrorStr) + } + if i != len(t.Output)-1 { + fmt.Fprintln(w, "") + continue + } + } + fmt.Fprintln(w, "") + return w.Flush() +} + +// Out method for JSON struct +func (j JSONStruct) Out() error { + data, err := json.MarshalIndent(j.Output, "", " ") + if err != nil { + return err + } + fmt.Printf("%s", data) + humanNewLine() + return nil +} + +//Out method for Go templates +func (t StdoutTemplate) Out() error { + tmpl, err := template.New("image").Parse(t.Template) + if err != nil { + return errors.Wrapf(err, "template parsing error") + } + err = tmpl.Execute(os.Stdout, t.Output) + if err != nil { + return err + } + humanNewLine() + return nil +} + +// Out method for YAML +func (y YAMLStruct) Out() error { + var buf []byte + var err error + buf, err = yaml.Marshal(y.Output) + if err != nil { + return err + } + fmt.Printf("%s", string(buf)) + humanNewLine() + return nil +} + +// humanNewLine prints a new line at the end of the output only if stdout is the terminal +func humanNewLine() { + if terminal.IsTerminal(int(os.Stdout.Fd())) { + fmt.Println() + } +} diff --git a/vendor/github.com/containers/buildah/pkg/formats/templates.go b/vendor/github.com/containers/buildah/pkg/formats/templates.go new file mode 100644 index 000000000..c2582552a --- /dev/null +++ b/vendor/github.com/containers/buildah/pkg/formats/templates.go @@ -0,0 +1,78 @@ +package formats + +import ( + "bytes" + "encoding/json" + "strings" + "text/template" +) + +// basicFunctions are the set of initial +// functions provided to every template. +var basicFunctions = template.FuncMap{ + "json": func(v interface{}) string { + buf := &bytes.Buffer{} + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(false) + _ = enc.Encode(v) + // Remove the trailing new line added by the encoder + return strings.TrimSpace(buf.String()) + }, + "split": strings.Split, + "join": strings.Join, + "title": strings.Title, + "lower": strings.ToLower, + "upper": strings.ToUpper, + "pad": padWithSpace, + "truncate": truncateWithLength, +} + +// HeaderFunctions are used to created headers of a table. +// This is a replacement of basicFunctions for header generation +// because we want the header to remain intact. +// Some functions like `split` are irrelevant so not added. +var headerFunctions = template.FuncMap{ + "json": func(v string) string { + return v + }, + "title": func(v string) string { + return v + }, + "lower": func(v string) string { + return v + }, + "upper": func(v string) string { + return v + }, + "truncate": func(v string, l int) string { + return v + }, +} + +// Parse creates a new anonymous template with the basic functions +// and parses the given format. +func Parse(format string) (*template.Template, error) { + return NewParse("", format) +} + +// NewParse creates a new tagged template with the basic functions +// and parses the given format. +func NewParse(tag, format string) (*template.Template, error) { + return template.New(tag).Funcs(basicFunctions).Parse(format) +} + +// padWithSpace adds whitespace to the input if the input is non-empty +func padWithSpace(source string, prefix, suffix int) string { + if source == "" { + return source + } + return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix) +} + +// truncateWithLength truncates the source string up to the length provided by the input +func truncateWithLength(source string, length int) string { + if len(source) < length { + return source + } + return source[:length] +} diff --git a/vendor/github.com/containers/buildah/run.go b/vendor/github.com/containers/buildah/run.go index 4d6d28380..f56ce30b1 100644 --- a/vendor/github.com/containers/buildah/run.go +++ b/vendor/github.com/containers/buildah/run.go @@ -1,7 +1,6 @@ package buildah import ( - "bufio" "bytes" "encoding/json" "fmt" @@ -272,36 +271,6 @@ func addRlimits(ulimit []string, g *generate.Generator) error { return nil } -func addHosts(hosts []string, w io.Writer) error { - buf := bufio.NewWriter(w) - for _, host := range hosts { - values := strings.SplitN(host, ":", 2) - if len(values) != 2 { - return errors.Errorf("unable to parse host entry %q: incorrect format", host) - } - if values[0] == "" { - return errors.Errorf("hostname in host entry %q is empty", host) - } - if values[1] == "" { - return errors.Errorf("IP address in host entry %q is empty", host) - } - fmt.Fprintf(buf, "%s\t%s\n", values[1], values[0]) - } - return buf.Flush() -} - -func addHostsToFile(hosts []string, filename string) error { - if len(hosts) == 0 { - return nil - } - file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, os.ModeAppend) - if err != nil { - return errors.Wrapf(err, "error creating hosts file %q", filename) - } - defer file.Close() - return addHosts(hosts, file) -} - func addCommonOptsToSpec(commonOpts *CommonBuildOptions, g *generate.Generator) error { // Resources - CPU if commonOpts.CPUPeriod != 0 { @@ -638,6 +607,59 @@ func (b *Builder) addNetworkConfig(rdir, hostPath string, chownOpts *idtools.IDP return cfile, nil } +// generateHosts creates a containers hosts file +func (b *Builder) generateHosts(rdir, hostname string, addHosts []string, chownOpts *idtools.IDPair) (string, error) { + hostPath := "/etc/hosts" + stat, err := os.Stat(hostPath) + if err != nil { + return "", errors.Wrapf(err, "error statting %q for container %q", hostPath, b.ContainerID) + } + + hosts := bytes.NewBufferString("# Generated by Buildah\n") + orig, err := ioutil.ReadFile(hostPath) + if err != nil { + return "", errors.Wrapf(err, "unable to read %s", hostPath) + } + hosts.Write(orig) + for _, host := range addHosts { + // verify the host format + values := strings.SplitN(host, ":", 2) + if len(values) != 2 { + return "", errors.Errorf("unable to parse host entry %q: incorrect format", host) + } + if values[0] == "" { + return "", errors.Errorf("hostname in host entry %q is empty", host) + } + if values[1] == "" { + return "", errors.Errorf("IP address in host entry %q is empty", host) + } + hosts.Write([]byte(fmt.Sprintf("%s\t%s\n", values[1], values[0]))) + } + + if hostname != "" { + hosts.Write([]byte(fmt.Sprintf("127.0.0.1 %s\n", hostname))) + hosts.Write([]byte(fmt.Sprintf("::1 %s\n", hostname))) + } + cfile := filepath.Join(rdir, filepath.Base(hostPath)) + if err = ioutils.AtomicWriteFile(cfile, hosts.Bytes(), stat.Mode().Perm()); err != nil { + return "", errors.Wrapf(err, "error writing /etc/hosts into the container") + } + uid := int(stat.Sys().(*syscall.Stat_t).Uid) + gid := int(stat.Sys().(*syscall.Stat_t).Gid) + if chownOpts != nil { + uid = chownOpts.UID + gid = chownOpts.GID + } + if err = os.Chown(cfile, uid, gid); err != nil { + return "", errors.Wrapf(err, "error chowning file %q for container %q", cfile, b.ContainerID) + } + if err := label.Relabel(cfile, b.MountLabel, false); err != nil { + return "", errors.Wrapf(err, "error relabeling %q in container %q", cfile, b.ContainerID) + } + + return cfile, nil +} + func setupMaskedPaths(g *generate.Generator) { for _, mp := range []string{ "/proc/acpi", @@ -1081,15 +1103,11 @@ func (b *Builder) Run(command []string, options RunOptions) error { volumes := b.Volumes() if !contains(volumes, "/etc/hosts") { - hostFile, err := b.addNetworkConfig(path, "/etc/hosts", rootIDPair) + hostFile, err := b.generateHosts(path, spec.Hostname, b.CommonBuildOpts.AddHost, rootIDPair) if err != nil { return err } bindFiles["/etc/hosts"] = hostFile - - if err := addHostsToFile(b.CommonBuildOpts.AddHost, hostFile); err != nil { - return err - } } if !contains(volumes, "/etc/resolv.conf") { -- cgit v1.2.3-54-g00ecf