mirror of
https://github.com/containers/podman.git
synced 2025-12-02 11:08:36 +08:00
move formats pkg to and vendor from buildah
Signed-off-by: Qi Wang <qiwan@redhat.com>
This commit is contained in:
2
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
2
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
@@ -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 {
|
||||
|
||||
10
vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
generated
vendored
10
vendor/github.com/containers/buildah/imagebuildah/chroot_symlink.go
generated
vendored
@@ -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
|
||||
|
||||
171
vendor/github.com/containers/buildah/pkg/formats/formats.go
generated
vendored
Normal file
171
vendor/github.com/containers/buildah/pkg/formats/formats.go
generated
vendored
Normal file
@@ -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()
|
||||
}
|
||||
}
|
||||
78
vendor/github.com/containers/buildah/pkg/formats/templates.go
generated
vendored
Normal file
78
vendor/github.com/containers/buildah/pkg/formats/templates.go
generated
vendored
Normal file
@@ -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]
|
||||
}
|
||||
90
vendor/github.com/containers/buildah/run.go
generated
vendored
90
vendor/github.com/containers/buildah/run.go
generated
vendored
@@ -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") {
|
||||
|
||||
Reference in New Issue
Block a user