summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/build.go2
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go10
-rw-r--r--vendor/github.com/containers/buildah/pkg/formats/formats.go171
-rw-r--r--vendor/github.com/containers/buildah/pkg/formats/templates.go78
-rw-r--r--vendor/github.com/containers/buildah/run.go90
5 files changed, 308 insertions, 43 deletions
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") {