mirror of
https://github.com/containers/podman.git
synced 2025-12-03 03:39:44 +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"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/projectatomic/buildah"
|
||||||
"github.com/projectatomic/buildah/imagebuildah"
|
"github.com/projectatomic/buildah/imagebuildah"
|
||||||
buildahcli "github.com/projectatomic/buildah/pkg/cli"
|
buildahcli "github.com/projectatomic/buildah/pkg/cli"
|
||||||
"github.com/projectatomic/buildah/pkg/parse"
|
"github.com/projectatomic/buildah/pkg/parse"
|
||||||
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
|
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
|
||||||
|
"github.com/projectatomic/libpod/pkg/rootless"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@@ -229,5 +231,9 @@ func buildCmd(c *cli.Context) error {
|
|||||||
options.ReportWriter = ioutil.Discard
|
options.ReportWriter = ioutil.Discard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rootless.IsRootless() {
|
||||||
|
options.Isolation = buildah.IsolationOCIRootless
|
||||||
|
}
|
||||||
|
|
||||||
return runtime.Build(getContext(), options, dockerfiles...)
|
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