Move get{Bind,Tmpfs,Secret,SSH}Mount to run_common.go
Signed-off-by: Doug Rabson <dfr@rabson.org>
This commit is contained in:
parent
0832ea2f35
commit
57a73847e4
265
run_common.go
265
run_common.go
|
|
@ -26,6 +26,8 @@ import (
|
|||
"github.com/containers/buildah/bind"
|
||||
"github.com/containers/buildah/copier"
|
||||
"github.com/containers/buildah/define"
|
||||
"github.com/containers/buildah/internal"
|
||||
internalParse "github.com/containers/buildah/internal/parse"
|
||||
"github.com/containers/buildah/pkg/sshagent"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/common/libnetwork/etchosts"
|
||||
|
|
@ -34,6 +36,7 @@ import (
|
|||
nettypes "github.com/containers/common/libnetwork/types"
|
||||
"github.com/containers/common/pkg/config"
|
||||
"github.com/containers/common/pkg/subscriptions"
|
||||
imagetypes "github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
|
|
@ -1523,3 +1526,265 @@ func (b *Builder) runSetupRunMounts(mounts []string, sources runMountInfo, idMap
|
|||
}
|
||||
return finalMounts, artifacts, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getBindMount(tokens []string, context *imagetypes.SystemContext, contextDir string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps) (*spec.Mount, string, error) {
|
||||
if contextDir == "" {
|
||||
return nil, "", errors.New("Context Directory for current run invocation is not configured")
|
||||
}
|
||||
var optionMounts []specs.Mount
|
||||
mount, image, err := internalParse.GetBindMount(context, tokens, contextDir, b.store, b.MountLabel, stageMountPoints)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
}
|
||||
return &volumes[0], image, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps) (*spec.Mount, error) {
|
||||
var optionMounts []specs.Mount
|
||||
mount, err := internalParse.GetTmpfsMount(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &volumes[0], nil
|
||||
}
|
||||
|
||||
func (b *Builder) getSecretMount(tokens []string, secrets map[string]define.Secret, idMaps IDMaps) (*spec.Mount, string, error) {
|
||||
errInvalidSyntax := errors.New("secret should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint")
|
||||
if len(tokens) == 0 {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
var err error
|
||||
var id, target string
|
||||
var required bool
|
||||
var uid, gid uint32
|
||||
var mode uint32 = 0400
|
||||
for _, val := range tokens {
|
||||
kv := strings.SplitN(val, "=", 2)
|
||||
switch kv[0] {
|
||||
case "id":
|
||||
id = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
target = kv[1]
|
||||
case "required":
|
||||
required, err = strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
case "mode":
|
||||
mode64, err := strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
mode = uint32(mode64)
|
||||
case "uid":
|
||||
uid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
uid = uint32(uid64)
|
||||
case "gid":
|
||||
gid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
default:
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
// Default location for secretis is /run/secrets/id
|
||||
if target == "" {
|
||||
target = "/run/secrets/" + id
|
||||
}
|
||||
|
||||
secr, ok := secrets[id]
|
||||
if !ok {
|
||||
if required {
|
||||
return nil, "", fmt.Errorf("secret required but no secret with id %s found", id)
|
||||
}
|
||||
return nil, "", nil
|
||||
}
|
||||
var data []byte
|
||||
var envFile string
|
||||
var ctrFileOnHost string
|
||||
|
||||
switch secr.SourceType {
|
||||
case "env":
|
||||
data = []byte(os.Getenv(secr.Source))
|
||||
tmpFile, err := ioutil.TempFile("/dev/shm", "buildah*")
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
envFile = tmpFile.Name()
|
||||
ctrFileOnHost = tmpFile.Name()
|
||||
case "file":
|
||||
containerWorkingDir, err := b.store.ContainerDirectory(b.ContainerID)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
data, err = ioutil.ReadFile(secr.Source)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
ctrFileOnHost = filepath.Join(containerWorkingDir, "secrets", id)
|
||||
default:
|
||||
return nil, "", errors.New("invalid source secret type")
|
||||
}
|
||||
|
||||
// Copy secrets to container working dir (or tmp dir if it's an env), since we need to chmod,
|
||||
// chown and relabel it for the container user and we don't want to mess with the original file
|
||||
if err := os.MkdirAll(filepath.Dir(ctrFileOnHost), 0755); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := ioutil.WriteFile(ctrFileOnHost, data, 0644); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if err := label.Relabel(ctrFileOnHost, b.MountLabel, false); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
hostUID, hostGID, err := util.GetHostIDs(idMaps.uidmap, idMaps.gidmap, uid, gid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := os.Lchown(ctrFileOnHost, int(hostUID), int(hostGID)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := os.Chmod(ctrFileOnHost, os.FileMode(mode)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
newMount := specs.Mount{
|
||||
Destination: target,
|
||||
Type: "bind",
|
||||
Source: ctrFileOnHost,
|
||||
Options: []string{"bind", "rprivate", "ro"},
|
||||
}
|
||||
return &newMount, envFile, nil
|
||||
}
|
||||
|
||||
// getSSHMount parses the --mount type=ssh flag in the Containerfile, checks if there's an ssh source provided, and creates and starts an ssh-agent to be forwarded into the container
|
||||
func (b *Builder) getSSHMount(tokens []string, count int, sshsources map[string]*sshagent.Source, idMaps IDMaps) (*spec.Mount, *sshagent.AgentServer, error) {
|
||||
errInvalidSyntax := errors.New("ssh should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint")
|
||||
|
||||
var err error
|
||||
var id, target string
|
||||
var required bool
|
||||
var uid, gid uint32
|
||||
var mode uint32 = 400
|
||||
for _, val := range tokens {
|
||||
kv := strings.SplitN(val, "=", 2)
|
||||
if len(kv) < 2 {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
switch kv[0] {
|
||||
case "id":
|
||||
id = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
target = kv[1]
|
||||
case "required":
|
||||
required, err = strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
case "mode":
|
||||
mode64, err := strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
mode = uint32(mode64)
|
||||
case "uid":
|
||||
uid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
uid = uint32(uid64)
|
||||
case "gid":
|
||||
gid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
default:
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
id = "default"
|
||||
}
|
||||
// Default location for secretis is /run/buildkit/ssh_agent.{i}
|
||||
if target == "" {
|
||||
target = fmt.Sprintf("/run/buildkit/ssh_agent.%d", count)
|
||||
}
|
||||
|
||||
sshsource, ok := sshsources[id]
|
||||
if !ok {
|
||||
if required {
|
||||
return nil, nil, fmt.Errorf("ssh required but no ssh with id %s found", id)
|
||||
}
|
||||
return nil, nil, nil
|
||||
}
|
||||
// Create new agent from keys or socket
|
||||
fwdAgent, err := sshagent.NewAgentServer(sshsource)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Start ssh server, and get the host sock we're mounting in the container
|
||||
hostSock, err := fwdAgent.Serve(b.ProcessLabel)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := label.Relabel(filepath.Dir(hostSock), b.MountLabel, false); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := label.Relabel(hostSock, b.MountLabel, false); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
hostUID, hostGID, err := util.GetHostIDs(idMaps.uidmap, idMaps.gidmap, uid, gid)
|
||||
if err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := os.Lchown(hostSock, int(hostUID), int(hostGID)); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := os.Chmod(hostSock, os.FileMode(mode)); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
newMount := specs.Mount{
|
||||
Destination: target,
|
||||
Type: "bind",
|
||||
Source: hostSock,
|
||||
Options: []string{"bind", "rprivate", "ro"},
|
||||
}
|
||||
return &newMount, fwdAgent, nil
|
||||
}
|
||||
|
|
|
|||
267
run_freebsd.go
267
run_freebsd.go
|
|
@ -9,7 +9,6 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
|
@ -19,11 +18,9 @@ import (
|
|||
"github.com/containers/buildah/copier"
|
||||
"github.com/containers/buildah/define"
|
||||
"github.com/containers/buildah/internal"
|
||||
internalParse "github.com/containers/buildah/internal/parse"
|
||||
internalUtil "github.com/containers/buildah/internal/util"
|
||||
"github.com/containers/buildah/pkg/jail"
|
||||
"github.com/containers/buildah/pkg/overlay"
|
||||
"github.com/containers/buildah/pkg/sshagent"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/common/libnetwork/resolvconf"
|
||||
nettypes "github.com/containers/common/libnetwork/types"
|
||||
|
|
@ -37,7 +34,6 @@ import (
|
|||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
|
|
@ -320,269 +316,6 @@ func (b *Builder) getCacheMount(tokens []string, stageMountPoints map[string]int
|
|||
return nil, nil, errors.New("cache mounts not supported on freebsd")
|
||||
}
|
||||
|
||||
func (b *Builder) getSecretMount(tokens []string, secrets map[string]define.Secret, idMaps IDMaps) (*spec.Mount, string, error) {
|
||||
errInvalidSyntax := errors.New("secret should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint")
|
||||
if len(tokens) == 0 {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
var err error
|
||||
var id, target string
|
||||
var required bool
|
||||
var uid, gid uint32
|
||||
var mode uint32 = 0400
|
||||
for _, val := range tokens {
|
||||
kv := strings.SplitN(val, "=", 2)
|
||||
switch kv[0] {
|
||||
case "id":
|
||||
id = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
target = kv[1]
|
||||
case "required":
|
||||
required, err = strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
case "mode":
|
||||
mode64, err := strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
mode = uint32(mode64)
|
||||
case "uid":
|
||||
uid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
uid = uint32(uid64)
|
||||
case "gid":
|
||||
gid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
default:
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
// Default location for secretis is /run/secrets/id
|
||||
if target == "" {
|
||||
target = "/run/secrets/" + id
|
||||
}
|
||||
|
||||
secr, ok := secrets[id]
|
||||
if !ok {
|
||||
if required {
|
||||
return nil, "", errors.Errorf("secret required but no secret with id %s found", id)
|
||||
}
|
||||
return nil, "", nil
|
||||
}
|
||||
var data []byte
|
||||
var envFile string
|
||||
var ctrFileOnHost string
|
||||
|
||||
switch secr.SourceType {
|
||||
case "env":
|
||||
data = []byte(os.Getenv(secr.Source))
|
||||
tmpFile, err := ioutil.TempFile("/var/tmp", "buildah*")
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
envFile = tmpFile.Name()
|
||||
ctrFileOnHost = tmpFile.Name()
|
||||
case "file":
|
||||
containerWorkingDir, err := b.store.ContainerDirectory(b.ContainerID)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
data, err = ioutil.ReadFile(secr.Source)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
ctrFileOnHost = filepath.Join(containerWorkingDir, "secrets", id)
|
||||
default:
|
||||
return nil, "", errors.New("invalid source secret type")
|
||||
}
|
||||
|
||||
// Copy secrets to container working dir (or tmp dir if it's an env), since we need to chmod,
|
||||
// chown and relabel it for the container user and we don't want to mess with the original file
|
||||
if err := os.MkdirAll(filepath.Dir(ctrFileOnHost), 0755); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := ioutil.WriteFile(ctrFileOnHost, data, 0644); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if err := label.Relabel(ctrFileOnHost, b.MountLabel, false); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
hostUID, hostGID, err := util.GetHostIDs(nil, nil, uid, gid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := os.Lchown(ctrFileOnHost, int(hostUID), int(hostGID)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := os.Chmod(ctrFileOnHost, os.FileMode(mode)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
newMount := specs.Mount{
|
||||
Destination: target,
|
||||
Type: "nullfs",
|
||||
Source: ctrFileOnHost,
|
||||
Options: []string{"ro"},
|
||||
}
|
||||
return &newMount, envFile, nil
|
||||
}
|
||||
|
||||
// getSSHMount parses the --mount type=ssh flag in the Containerfile, checks if there's an ssh source provided, and creates and starts an ssh-agent to be forwarded into the container
|
||||
func (b *Builder) getSSHMount(tokens []string, count int, sshsources map[string]*sshagent.Source, idMaps IDMaps) (*spec.Mount, *sshagent.AgentServer, error) {
|
||||
errInvalidSyntax := errors.New("ssh should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint")
|
||||
|
||||
var err error
|
||||
var id, target string
|
||||
var required bool
|
||||
var uid, gid uint32
|
||||
var mode uint32 = 400
|
||||
for _, val := range tokens {
|
||||
kv := strings.SplitN(val, "=", 2)
|
||||
if len(kv) < 2 {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
switch kv[0] {
|
||||
case "id":
|
||||
id = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
target = kv[1]
|
||||
case "required":
|
||||
required, err = strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
case "mode":
|
||||
mode64, err := strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
mode = uint32(mode64)
|
||||
case "uid":
|
||||
uid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
uid = uint32(uid64)
|
||||
case "gid":
|
||||
gid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
default:
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
id = "default"
|
||||
}
|
||||
// Default location for secretis is /run/buildkit/ssh_agent.{i}
|
||||
if target == "" {
|
||||
target = fmt.Sprintf("/run/buildkit/ssh_agent.%d", count)
|
||||
}
|
||||
|
||||
sshsource, ok := sshsources[id]
|
||||
if !ok {
|
||||
if required {
|
||||
return nil, nil, errors.Errorf("ssh required but no ssh with id %s found", id)
|
||||
}
|
||||
return nil, nil, nil
|
||||
}
|
||||
// Create new agent from keys or socket
|
||||
fwdAgent, err := sshagent.NewAgentServer(sshsource)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Start ssh server, and get the host sock we're mounting in the container
|
||||
hostSock, err := fwdAgent.Serve(b.ProcessLabel)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := label.Relabel(filepath.Dir(hostSock), b.MountLabel, false); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := label.Relabel(hostSock, b.MountLabel, false); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
hostUID, hostGID, err := util.GetHostIDs(nil, nil, uid, gid)
|
||||
if err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := os.Lchown(hostSock, int(hostUID), int(hostGID)); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := os.Chmod(hostSock, os.FileMode(mode)); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
newMount := specs.Mount{
|
||||
Destination: target,
|
||||
Type: "nullfs",
|
||||
Source: hostSock,
|
||||
Options: []string{"ro"},
|
||||
}
|
||||
return &newMount, fwdAgent, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getBindMount(tokens []string, context *imagetypes.SystemContext, contextDir string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps) (*spec.Mount, string, error) {
|
||||
if contextDir == "" {
|
||||
return nil, "", errors.New("Context Directory for current run invocation is not configured")
|
||||
}
|
||||
var optionMounts []specs.Mount
|
||||
mount, image, err := internalParse.GetBindMount(context, tokens, contextDir, b.store, b.MountLabel, stageMountPoints)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
}
|
||||
return &volumes[0], image, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps) (*spec.Mount, error) {
|
||||
var optionMounts []specs.Mount
|
||||
mount, err := internalParse.GetTmpfsMount(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &volumes[0], nil
|
||||
}
|
||||
|
||||
func (b *Builder) cleanupTempVolumes() {
|
||||
for tempVolume, val := range b.TempVolumes {
|
||||
if val {
|
||||
|
|
|
|||
263
run_linux.go
263
run_linux.go
|
|
@ -25,7 +25,6 @@ import (
|
|||
internalUtil "github.com/containers/buildah/internal/util"
|
||||
"github.com/containers/buildah/pkg/overlay"
|
||||
"github.com/containers/buildah/pkg/parse"
|
||||
"github.com/containers/buildah/pkg/sshagent"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/common/libnetwork/resolvconf"
|
||||
nettypes "github.com/containers/common/libnetwork/types"
|
||||
|
|
@ -1176,37 +1175,6 @@ func checkIdsGreaterThan5(ids []spec.LinuxIDMapping) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (b *Builder) getBindMount(tokens []string, context *imagetypes.SystemContext, contextDir string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps) (*spec.Mount, string, error) {
|
||||
if contextDir == "" {
|
||||
return nil, "", errors.New("Context Directory for current run invocation is not configured")
|
||||
}
|
||||
var optionMounts []specs.Mount
|
||||
mount, image, err := internalParse.GetBindMount(context, tokens, contextDir, b.store, b.MountLabel, stageMountPoints)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, image, err
|
||||
}
|
||||
return &volumes[0], image, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps) (*spec.Mount, error) {
|
||||
var optionMounts []specs.Mount
|
||||
mount, err := internalParse.GetTmpfsMount(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
optionMounts = append(optionMounts, mount)
|
||||
volumes, err := b.runSetupVolumeMounts(b.MountLabel, nil, optionMounts, idMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &volumes[0], nil
|
||||
}
|
||||
|
||||
func (b *Builder) getCacheMount(tokens []string, stageMountPoints map[string]internal.StageMountDetails, idMaps IDMaps) (*spec.Mount, []string, error) {
|
||||
var optionMounts []specs.Mount
|
||||
mount, lockedTargets, err := internalParse.GetCacheMount(tokens, b.store, b.MountLabel, stageMountPoints)
|
||||
|
|
@ -1221,237 +1189,6 @@ func (b *Builder) getCacheMount(tokens []string, stageMountPoints map[string]int
|
|||
return &volumes[0], lockedTargets, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getSecretMount(tokens []string, secrets map[string]define.Secret, idMaps IDMaps) (*spec.Mount, string, error) {
|
||||
errInvalidSyntax := errors.New("secret should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint")
|
||||
if len(tokens) == 0 {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
var err error
|
||||
var id, target string
|
||||
var required bool
|
||||
var uid, gid uint32
|
||||
var mode uint32 = 0400
|
||||
for _, val := range tokens {
|
||||
kv := strings.SplitN(val, "=", 2)
|
||||
switch kv[0] {
|
||||
case "id":
|
||||
id = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
target = kv[1]
|
||||
case "required":
|
||||
required, err = strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
case "mode":
|
||||
mode64, err := strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
mode = uint32(mode64)
|
||||
case "uid":
|
||||
uid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
uid = uint32(uid64)
|
||||
case "gid":
|
||||
gid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
default:
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
return nil, "", errInvalidSyntax
|
||||
}
|
||||
// Default location for secretis is /run/secrets/id
|
||||
if target == "" {
|
||||
target = "/run/secrets/" + id
|
||||
}
|
||||
|
||||
secr, ok := secrets[id]
|
||||
if !ok {
|
||||
if required {
|
||||
return nil, "", fmt.Errorf("secret required but no secret with id %s found", id)
|
||||
}
|
||||
return nil, "", nil
|
||||
}
|
||||
var data []byte
|
||||
var envFile string
|
||||
var ctrFileOnHost string
|
||||
|
||||
switch secr.SourceType {
|
||||
case "env":
|
||||
data = []byte(os.Getenv(secr.Source))
|
||||
tmpFile, err := ioutil.TempFile("/dev/shm", "buildah*")
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
envFile = tmpFile.Name()
|
||||
ctrFileOnHost = tmpFile.Name()
|
||||
case "file":
|
||||
containerWorkingDir, err := b.store.ContainerDirectory(b.ContainerID)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
data, err = ioutil.ReadFile(secr.Source)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
ctrFileOnHost = filepath.Join(containerWorkingDir, "secrets", id)
|
||||
default:
|
||||
return nil, "", errors.New("invalid source secret type")
|
||||
}
|
||||
|
||||
// Copy secrets to container working dir (or tmp dir if it's an env), since we need to chmod,
|
||||
// chown and relabel it for the container user and we don't want to mess with the original file
|
||||
if err := os.MkdirAll(filepath.Dir(ctrFileOnHost), 0755); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := ioutil.WriteFile(ctrFileOnHost, data, 0644); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if err := label.Relabel(ctrFileOnHost, b.MountLabel, false); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
hostUID, hostGID, err := util.GetHostIDs(idMaps.uidmap, idMaps.gidmap, uid, gid)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := os.Lchown(ctrFileOnHost, int(hostUID), int(hostGID)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := os.Chmod(ctrFileOnHost, os.FileMode(mode)); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
newMount := specs.Mount{
|
||||
Destination: target,
|
||||
Type: "bind",
|
||||
Source: ctrFileOnHost,
|
||||
Options: []string{"bind", "rprivate", "ro"},
|
||||
}
|
||||
return &newMount, envFile, nil
|
||||
}
|
||||
|
||||
// getSSHMount parses the --mount type=ssh flag in the Containerfile, checks if there's an ssh source provided, and creates and starts an ssh-agent to be forwarded into the container
|
||||
func (b *Builder) getSSHMount(tokens []string, count int, sshsources map[string]*sshagent.Source, idMaps IDMaps) (*spec.Mount, *sshagent.AgentServer, error) {
|
||||
errInvalidSyntax := errors.New("ssh should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint")
|
||||
|
||||
var err error
|
||||
var id, target string
|
||||
var required bool
|
||||
var uid, gid uint32
|
||||
var mode uint32 = 400
|
||||
for _, val := range tokens {
|
||||
kv := strings.SplitN(val, "=", 2)
|
||||
if len(kv) < 2 {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
switch kv[0] {
|
||||
case "id":
|
||||
id = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
target = kv[1]
|
||||
case "required":
|
||||
required, err = strconv.ParseBool(kv[1])
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
case "mode":
|
||||
mode64, err := strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
mode = uint32(mode64)
|
||||
case "uid":
|
||||
uid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
uid = uint32(uid64)
|
||||
case "gid":
|
||||
gid64, err := strconv.ParseUint(kv[1], 10, 32)
|
||||
if err != nil {
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
default:
|
||||
return nil, nil, errInvalidSyntax
|
||||
}
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
id = "default"
|
||||
}
|
||||
// Default location for secretis is /run/buildkit/ssh_agent.{i}
|
||||
if target == "" {
|
||||
target = fmt.Sprintf("/run/buildkit/ssh_agent.%d", count)
|
||||
}
|
||||
|
||||
sshsource, ok := sshsources[id]
|
||||
if !ok {
|
||||
if required {
|
||||
return nil, nil, fmt.Errorf("ssh required but no ssh with id %s found", id)
|
||||
}
|
||||
return nil, nil, nil
|
||||
}
|
||||
// Create new agent from keys or socket
|
||||
fwdAgent, err := sshagent.NewAgentServer(sshsource)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Start ssh server, and get the host sock we're mounting in the container
|
||||
hostSock, err := fwdAgent.Serve(b.ProcessLabel)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := label.Relabel(filepath.Dir(hostSock), b.MountLabel, false); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := label.Relabel(hostSock, b.MountLabel, false); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
hostUID, hostGID, err := util.GetHostIDs(idMaps.uidmap, idMaps.gidmap, uid, gid)
|
||||
if err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := os.Lchown(hostSock, int(hostUID), int(hostGID)); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := os.Chmod(hostSock, os.FileMode(mode)); err != nil {
|
||||
if shutdownErr := fwdAgent.Shutdown(); shutdownErr != nil {
|
||||
b.Logger.Errorf("error shutting down agent: %v", shutdownErr)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
newMount := specs.Mount{
|
||||
Destination: target,
|
||||
Type: "bind",
|
||||
Source: hostSock,
|
||||
Options: []string{"bind", "rprivate", "ro"},
|
||||
}
|
||||
return &newMount, fwdAgent, nil
|
||||
}
|
||||
|
||||
// cleanupRunMounts cleans up run mounts so they only appear in this run.
|
||||
func (b *Builder) cleanupRunMounts(context *imagetypes.SystemContext, mountpoint string, artifacts *runMountArtifacts) error {
|
||||
for _, agent := range artifacts.Agents {
|
||||
|
|
|
|||
Loading…
Reference in New Issue