mirror of
https://github.com/containers/podman.git
synced 2025-12-01 02:27:13 +08:00
build, rootless: specify IsolationOCIRootless
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> Closes: #1269 Approved by: rhatdan
This commit is contained in:
committed by
Atomic Bot
parent
e2b96e96f9
commit
883aea51a3
@@ -7,10 +7,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectatomic/buildah"
|
||||
"github.com/projectatomic/buildah/imagebuildah"
|
||||
buildahcli "github.com/projectatomic/buildah/pkg/cli"
|
||||
"github.com/projectatomic/buildah/pkg/parse"
|
||||
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/projectatomic/libpod/pkg/rootless"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -229,5 +231,9 @@ func buildCmd(c *cli.Context) error {
|
||||
options.ReportWriter = ioutil.Discard
|
||||
}
|
||||
|
||||
if rootless.IsRootless() {
|
||||
options.Isolation = buildah.IsolationOCIRootless
|
||||
}
|
||||
|
||||
return runtime.Build(getContext(), options, dockerfiles...)
|
||||
}
|
||||
|
||||
369
vendor/github.com/containers/image/pkg/sysregistriesv2/system_registries_v2.go
generated
vendored
Normal file
369
vendor/github.com/containers/image/pkg/sysregistriesv2/system_registries_v2.go
generated
vendored
Normal file
@@ -0,0 +1,369 @@
|
||||
package sysregistriesv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/containers/image/types"
|
||||
)
|
||||
|
||||
// systemRegistriesConfPath is the path to the system-wide registry
|
||||
// configuration file and is used to add/subtract potential registries for
|
||||
// obtaining images. You can override this at build time with
|
||||
// -ldflags '-X github.com/containers/image/sysregistries.systemRegistriesConfPath=$your_path'
|
||||
var systemRegistriesConfPath = builtinRegistriesConfPath
|
||||
|
||||
// builtinRegistriesConfPath is the path to the registry configuration file.
|
||||
// DO NOT change this, instead see systemRegistriesConfPath above.
|
||||
const builtinRegistriesConfPath = "/etc/containers/registries.conf"
|
||||
|
||||
// Mirror represents a mirror. Mirrors can be used as pull-through caches for
|
||||
// registries.
|
||||
type Mirror struct {
|
||||
// The mirror's URL.
|
||||
URL string `toml:"url"`
|
||||
// If true, certs verification will be skipped and HTTP (non-TLS)
|
||||
// connections will be allowed.
|
||||
Insecure bool `toml:"insecure"`
|
||||
}
|
||||
|
||||
// Registry represents a registry.
|
||||
type Registry struct {
|
||||
// Serializable registry URL.
|
||||
URL string `toml:"url"`
|
||||
// The registry's mirrors.
|
||||
Mirrors []Mirror `toml:"mirror"`
|
||||
// If true, pulling from the registry will be blocked.
|
||||
Blocked bool `toml:"blocked"`
|
||||
// If true, certs verification will be skipped and HTTP (non-TLS)
|
||||
// connections will be allowed.
|
||||
Insecure bool `toml:"insecure"`
|
||||
// If true, the registry can be used when pulling an unqualified image.
|
||||
Search bool `toml:"unqualified-search"`
|
||||
// Prefix is used for matching images, and to translate one namespace to
|
||||
// another. If `Prefix="example.com/bar"`, `URL="example.com/foo/bar"`
|
||||
// and we pull from "example.com/bar/myimage:latest", the image will
|
||||
// effectively be pulled from "example.com/foo/bar/myimage:latest".
|
||||
// If no Prefix is specified, it defaults to the specified URL.
|
||||
Prefix string `toml:"prefix"`
|
||||
}
|
||||
|
||||
// backwards compatability to sysregistries v1
|
||||
type v1TOMLregistries struct {
|
||||
Registries []string `toml:"registries"`
|
||||
}
|
||||
|
||||
// tomlConfig is the data type used to unmarshal the toml config.
|
||||
type tomlConfig struct {
|
||||
Registries []Registry `toml:"registry"`
|
||||
// backwards compatability to sysregistries v1
|
||||
V1Registries struct {
|
||||
Search v1TOMLregistries `toml:"search"`
|
||||
Insecure v1TOMLregistries `toml:"insecure"`
|
||||
Block v1TOMLregistries `toml:"block"`
|
||||
} `toml:"registries"`
|
||||
}
|
||||
|
||||
// InvalidRegistries represents an invalid registry configurations. An example
|
||||
// is when "registry.com" is defined multiple times in the configuration but
|
||||
// with conflicting security settings.
|
||||
type InvalidRegistries struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// Error returns the error string.
|
||||
func (e *InvalidRegistries) Error() string {
|
||||
return e.s
|
||||
}
|
||||
|
||||
// parseURL parses the input string, performs some sanity checks and returns
|
||||
// the sanitized input string. An error is returned in case parsing fails or
|
||||
// or if URI scheme or user is set.
|
||||
func parseURL(input string) (string, error) {
|
||||
trimmed := strings.TrimRight(input, "/")
|
||||
|
||||
if trimmed == "" {
|
||||
return "", &InvalidRegistries{s: "invalid URL: cannot be empty"}
|
||||
}
|
||||
|
||||
// Ultimately, we expect input of the form example.com[/namespace/…], a prefix
|
||||
// of a fully-expended reference (containers/image/docker/Reference.String()).
|
||||
// c/image/docker/Reference does not currently provide such a parser.
|
||||
// So, we use url.Parse("http://"+trimmed) below to ~verify the format, possibly
|
||||
// letting some invalid input in, trading that off for a simpler parser.
|
||||
//
|
||||
// url.Parse("http://"+trimmed) is, sadly, too permissive, notably for
|
||||
// trimmed == "http://example.com/…", url.Parse("http://http://example.com/…")
|
||||
// is accepted and parsed as
|
||||
// {Scheme: "http", Host: "http:", Path: "//example.com/…"}.
|
||||
//
|
||||
// So, first we do an explicit check for an unwanted scheme prefix:
|
||||
|
||||
// This will parse trimmed=="http://example.com/…" with Scheme: "http". Perhaps surprisingly,
|
||||
// it also succeeds for the input we want to accept, in different ways:
|
||||
// "example.com" -> {Scheme:"", Opaque:"", Path:"example.com"}
|
||||
// "example.com/repo" -> {Scheme:"", Opaque:"", Path:"example.com/repo"}
|
||||
// "example.com:5000" -> {Scheme:"example.com", Opaque:"5000"}
|
||||
// "example.com:5000/repo" -> {Scheme:"example.com", Opaque:"5000/repo"}
|
||||
uri, err := url.Parse(trimmed)
|
||||
if err != nil {
|
||||
return "", &InvalidRegistries{s: fmt.Sprintf("invalid URL '%s': %v", input, err)}
|
||||
}
|
||||
|
||||
// Check if a URI Scheme is set.
|
||||
// Note that URLs that do not start with a slash after the scheme are
|
||||
// interpreted as `scheme:opaque[?query][#fragment]`; see above for examples.
|
||||
if uri.Scheme != "" && uri.Opaque == "" {
|
||||
msg := fmt.Sprintf("invalid URL '%s': URI schemes are not supported", input)
|
||||
return "", &InvalidRegistries{s: msg}
|
||||
}
|
||||
|
||||
uri, err = url.Parse("http://" + trimmed)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("invalid URL '%s': sanitized URL did not parse: %v", input, err)
|
||||
return "", &InvalidRegistries{s: msg}
|
||||
}
|
||||
|
||||
if uri.User != nil {
|
||||
msg := fmt.Sprintf("invalid URL '%s': user/password are not supported", trimmed)
|
||||
return "", &InvalidRegistries{s: msg}
|
||||
}
|
||||
|
||||
return trimmed, nil
|
||||
}
|
||||
|
||||
// getV1Registries transforms v1 registries in the config into an array of v2
|
||||
// registries of type Registry.
|
||||
func getV1Registries(config *tomlConfig) ([]Registry, error) {
|
||||
regMap := make(map[string]*Registry)
|
||||
|
||||
getRegistry := func(url string) (*Registry, error) { // Note: _pointer_ to a long-lived object
|
||||
var err error
|
||||
url, err = parseURL(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reg, exists := regMap[url]
|
||||
if !exists {
|
||||
reg = &Registry{
|
||||
URL: url,
|
||||
Mirrors: []Mirror{},
|
||||
Prefix: url,
|
||||
}
|
||||
regMap[url] = reg
|
||||
}
|
||||
return reg, nil
|
||||
}
|
||||
|
||||
for _, search := range config.V1Registries.Search.Registries {
|
||||
reg, err := getRegistry(search)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reg.Search = true
|
||||
}
|
||||
for _, blocked := range config.V1Registries.Block.Registries {
|
||||
reg, err := getRegistry(blocked)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reg.Blocked = true
|
||||
}
|
||||
for _, insecure := range config.V1Registries.Insecure.Registries {
|
||||
reg, err := getRegistry(insecure)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reg.Insecure = true
|
||||
}
|
||||
|
||||
registries := []Registry{}
|
||||
for _, reg := range regMap {
|
||||
registries = append(registries, *reg)
|
||||
}
|
||||
return registries, nil
|
||||
}
|
||||
|
||||
// postProcessRegistries checks the consistency of all registries (e.g., set
|
||||
// the Prefix to URL if not set) and applies conflict checks. It returns an
|
||||
// array of cleaned registries and error in case of conflicts.
|
||||
func postProcessRegistries(regs []Registry) ([]Registry, error) {
|
||||
var registries []Registry
|
||||
regMap := make(map[string][]Registry)
|
||||
|
||||
for _, reg := range regs {
|
||||
var err error
|
||||
|
||||
// make sure URL and Prefix are valid
|
||||
reg.URL, err = parseURL(reg.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if reg.Prefix == "" {
|
||||
reg.Prefix = reg.URL
|
||||
} else {
|
||||
reg.Prefix, err = parseURL(reg.Prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// make sure mirrors are valid
|
||||
for _, mir := range reg.Mirrors {
|
||||
mir.URL, err = parseURL(mir.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
registries = append(registries, reg)
|
||||
regMap[reg.URL] = append(regMap[reg.URL], reg)
|
||||
}
|
||||
|
||||
// Given a registry can be mentioned multiple times (e.g., to have
|
||||
// multiple prefixes backed by different mirrors), we need to make sure
|
||||
// there are no conflicts among them.
|
||||
//
|
||||
// Note: we need to iterate over the registries array to ensure a
|
||||
// deterministic behavior which is not guaranteed by maps.
|
||||
for _, reg := range registries {
|
||||
others, _ := regMap[reg.URL]
|
||||
for _, other := range others {
|
||||
if reg.Insecure != other.Insecure {
|
||||
msg := fmt.Sprintf("registry '%s' is defined multiple times with conflicting 'insecure' setting", reg.URL)
|
||||
|
||||
return nil, &InvalidRegistries{s: msg}
|
||||
}
|
||||
if reg.Blocked != other.Blocked {
|
||||
msg := fmt.Sprintf("registry '%s' is defined multiple times with conflicting 'blocked' setting", reg.URL)
|
||||
return nil, &InvalidRegistries{s: msg}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return registries, nil
|
||||
}
|
||||
|
||||
// getConfigPath returns the system-registries config path if specified.
|
||||
// Otherwise, systemRegistriesConfPath is returned.
|
||||
func getConfigPath(ctx *types.SystemContext) string {
|
||||
confPath := systemRegistriesConfPath
|
||||
if ctx != nil {
|
||||
if ctx.SystemRegistriesConfPath != "" {
|
||||
confPath = ctx.SystemRegistriesConfPath
|
||||
} else if ctx.RootForImplicitAbsolutePaths != "" {
|
||||
confPath = filepath.Join(ctx.RootForImplicitAbsolutePaths, systemRegistriesConfPath)
|
||||
}
|
||||
}
|
||||
return confPath
|
||||
}
|
||||
|
||||
// configMutex is used to synchronize concurrent accesses to configCache.
|
||||
var configMutex = sync.Mutex{}
|
||||
|
||||
// configCache caches already loaded configs with config paths as keys and is
|
||||
// used to avoid redudantly parsing configs. Concurrent accesses to the cache
|
||||
// are synchronized via configMutex.
|
||||
var configCache = make(map[string][]Registry)
|
||||
|
||||
// GetRegistries loads and returns the registries specified in the config.
|
||||
func GetRegistries(ctx *types.SystemContext) ([]Registry, error) {
|
||||
configPath := getConfigPath(ctx)
|
||||
|
||||
configMutex.Lock()
|
||||
defer configMutex.Unlock()
|
||||
// if the config has already been loaded, return the cached registries
|
||||
if registries, inCache := configCache[configPath]; inCache {
|
||||
return registries, nil
|
||||
}
|
||||
|
||||
// load the config
|
||||
config, err := loadRegistryConf(configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
registries := config.Registries
|
||||
|
||||
// backwards compatibility for v1 configs
|
||||
v1Registries, err := getV1Registries(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(v1Registries) > 0 {
|
||||
if len(registries) > 0 {
|
||||
return nil, &InvalidRegistries{s: "mixing sysregistry v1/v2 is not supported"}
|
||||
}
|
||||
registries = v1Registries
|
||||
}
|
||||
|
||||
registries, err = postProcessRegistries(registries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// populate the cache
|
||||
configCache[configPath] = registries
|
||||
|
||||
return registries, err
|
||||
}
|
||||
|
||||
// FindUnqualifiedSearchRegistries returns all registries that are configured
|
||||
// for unqualified image search (i.e., with Registry.Search == true).
|
||||
func FindUnqualifiedSearchRegistries(registries []Registry) []Registry {
|
||||
unqualified := []Registry{}
|
||||
for _, reg := range registries {
|
||||
if reg.Search {
|
||||
unqualified = append(unqualified, reg)
|
||||
}
|
||||
}
|
||||
return unqualified
|
||||
}
|
||||
|
||||
// FindRegistry returns the Registry with the longest prefix for ref. If no
|
||||
// Registry prefixes the image, nil is returned.
|
||||
func FindRegistry(ref string, registries []Registry) *Registry {
|
||||
reg := Registry{}
|
||||
prefixLen := 0
|
||||
for _, r := range registries {
|
||||
if strings.HasPrefix(ref, r.Prefix) {
|
||||
length := len(r.Prefix)
|
||||
if length > prefixLen {
|
||||
reg = r
|
||||
prefixLen = length
|
||||
}
|
||||
}
|
||||
}
|
||||
if prefixLen != 0 {
|
||||
return ®
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reads the global registry file from the filesystem. Returns a byte array.
|
||||
func readRegistryConf(configPath string) ([]byte, error) {
|
||||
configBytes, err := ioutil.ReadFile(configPath)
|
||||
return configBytes, err
|
||||
}
|
||||
|
||||
// Used in unittests to parse custom configs without a types.SystemContext.
|
||||
var readConf = readRegistryConf
|
||||
|
||||
// Loads the registry configuration file from the filesystem and then unmarshals
|
||||
// it. Returns the unmarshalled object.
|
||||
func loadRegistryConf(configPath string) (*tomlConfig, error) {
|
||||
config := &tomlConfig{}
|
||||
|
||||
configBytes, err := readConf(configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = toml.Unmarshal(configBytes, &config)
|
||||
return config, err
|
||||
}
|
||||
Reference in New Issue
Block a user