Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add functionality to copy file permissions from host to container #1182

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions environment/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ type ContainerEngine interface {
// InspectImage gets Inspect output for a container
InspectImage(image string) (dockertypes.ImageInspect, error)
// TODO: Change paths from map to array
CopyDirsIntoImage(image, newImageName string, paths map[string]string) (err error)
CopyDirsIntoContainer(containerID string, paths map[string]string) (err error)
CopyDirsIntoImage(image, newImageName string, paths map[string]string, copyUIDGID bool) (err error)
CopyDirsIntoContainer(containerID string, paths map[string]string, copyUIDGID bool) (err error) // See here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comments

Suggested change
CopyDirsIntoContainer(containerID string, paths map[string]string, copyUIDGID bool) (err error) // See here
CopyDirsIntoContainer(containerID string, paths map[string]string, copyUIDGID bool) (err error)

CopyDirsFromContainer(containerID string, paths map[string]string) (err error)
BuildImage(image, context, dockerfile string) (err error)
RemoveImage(image string) (err error)
CreateContainer(container environmenttypes.Container) (containerid string, err error)
StopAndRemoveContainer(containerID string) (err error)
// RunContainer runs a container from an image
RunContainer(image string, cmd environmenttypes.Command, volsrc string, voldest string) (output string, containerStarted bool, err error)
RunContainer(image string, cmd environmenttypes.Command, volsrc string, voldest string, copyUIDGID bool) (output string, containerStarted bool, err error)
Stat(containerID, name string) (fs.FileInfo, error)
}

Expand Down
14 changes: 7 additions & 7 deletions environment/container/dockerengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func newDockerEngine() (*dockerEngine, error) {
if err := engine.updateAvailableImages(); err != nil {
return engine, fmt.Errorf("failed to update the list of available images. Error: %w", err)
}
if _, _, err := engine.RunContainer(testimage, environmenttypes.Command{}, "", ""); err != nil {
if _, _, err := engine.RunContainer(testimage, environmenttypes.Command{}, "", "", false); err != nil {
return engine, fmt.Errorf("failed to run the test image '%s' as a container. Error: %w", testimage, err)
}
return engine, nil
Expand Down Expand Up @@ -206,7 +206,7 @@ func (e *dockerEngine) StopAndRemoveContainer(containerID string) error {
}

// CopyDirsIntoImage copies some directories into a container
func (e *dockerEngine) CopyDirsIntoImage(image, newImageName string, paths map[string]string) (err error) {
func (e *dockerEngine) CopyDirsIntoImage(image, newImageName string, paths map[string]string, copyUIDGID bool) (err error) {
logrus.Trace("CopyDirsIntoImage start")
defer logrus.Trace("CopyDirsIntoImage end")
if err := e.pullImage(image); err != nil {
Expand All @@ -217,7 +217,7 @@ func (e *dockerEngine) CopyDirsIntoImage(image, newImageName string, paths map[s
return fmt.Errorf("failed to create container with base image '%s' . Error: %w", image, err)
}
for sp, dp := range paths {
if err := copyDirToContainer(e.ctx, e.cli, cid, sp, dp); err != nil {
if err := copyDirToContainer(e.ctx, e.cli, cid, sp, dp, copyUIDGID); err != nil {
return fmt.Errorf("container data copy failed for image '%s' with volume %s:%s . Error: %w", image, sp, dp, err)
}
}
Expand All @@ -232,9 +232,9 @@ func (e *dockerEngine) CopyDirsIntoImage(image, newImageName string, paths map[s
}

// CopyDirsIntoContainer copies some directories into a container
func (e *dockerEngine) CopyDirsIntoContainer(containerID string, paths map[string]string) (err error) {
func (e *dockerEngine) CopyDirsIntoContainer(containerID string, paths map[string]string, copyUIDGID bool) (err error) {
for sp, dp := range paths {
err = copyDirToContainer(e.ctx, e.cli, containerID, sp, dp)
err = copyDirToContainer(e.ctx, e.cli, containerID, sp, dp, copyUIDGID)
if err != nil {
return fmt.Errorf("container data copy failed for image '%s' with volume %s:%s . Error: %w", containerID, sp, dp, err)
}
Expand Down Expand Up @@ -295,7 +295,7 @@ func (e *dockerEngine) RemoveImage(image string) (err error) {
}

// RunContainer executes a container
func (e *dockerEngine) RunContainer(image string, cmd environmenttypes.Command, volsrc string, voldest string) (output string, containerStarted bool, err error) {
func (e *dockerEngine) RunContainer(image string, cmd environmenttypes.Command, volsrc string, voldest string, copyUIDGID bool) (output string, containerStarted bool, err error) {
if err := e.pullImage(image); err != nil {
return "", false, fmt.Errorf("failed to pull the image '%s'. Error: %w", image, err)
}
Expand Down Expand Up @@ -329,7 +329,7 @@ func (e *dockerEngine) RunContainer(image string, cmd environmenttypes.Command,
logrus.Debugf("Container %s created with image %s with no volumes", resp.ID, image)
defer cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
if volsrc != "" && voldest != "" {
err = copyDir(ctx, cli, resp.ID, volsrc, voldest)
err = copyDir(ctx, cli, resp.ID, volsrc, voldest, copyUIDGID)
if err != nil {
return "", false, fmt.Errorf("container data copy failed for image '%s' with volume (%s:%s). Error: %w", image, volsrc, voldest, err)
}
Expand Down
8 changes: 4 additions & 4 deletions environment/container/dockerengine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func TestIsBuilderAvailable(t *testing.T) {
paths[absDir1] = "/dir1"
paths[absDir2] = "/dir2"

err = provider.CopyDirsIntoImage(image, newimage, paths)
err = provider.CopyDirsIntoImage(image, newimage, paths, true)
if err != nil {
t.Fatalf("failed to copy dirs into iamge '%s' . Error: %q", image, err)
}
Expand Down Expand Up @@ -296,7 +296,7 @@ func TestIsBuilderAvailable(t *testing.T) {
paths[absDir1] = "/dir1"
paths[absDir2] = "/dir2"

err = provider.CopyDirsIntoContainer(containerID, paths)
err = provider.CopyDirsIntoContainer(containerID, paths, true)
if err != nil {
t.Fatalf("failed to copy dirs into iamge '%s' . Error: %q", image, err)
}
Expand Down Expand Up @@ -365,7 +365,7 @@ func TestIsBuilderAvailable(t *testing.T) {
paths[absDir1] = "/dir1"
paths[absDir2] = "/dir2"

err = provider.CopyDirsIntoContainer(containerID, paths)
err = provider.CopyDirsIntoContainer(containerID, paths, true)
if err != nil {
t.Fatalf("failed to copy dirs into iamge '%s' . Error: %q", image, err)
}
Expand Down Expand Up @@ -504,7 +504,7 @@ func TestIsBuilderAvailable(t *testing.T) {
t.Run("check for Running a Container ", func(t *testing.T) {
provider, _ := newDockerEngine()
image := "docker.io/somerandomimage"
output, containerStarted, err := provider.RunContainer(image, environmenttypes.Command{"pwd"}, "", "")
output, containerStarted, err := provider.RunContainer(image, environmenttypes.Command{"pwd"}, "", "", true)
if err == nil {
t.Fatalf("Test passed: failed to run the image due to incorrect name '%s' as a container. Error: %q", image, err)
}
Expand Down
2 changes: 1 addition & 1 deletion environment/container/podmanengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (e *podmanEngine) pullImage(image string) bool {
}

// RunContainer executes a container using podman
func (e *podmanEngine) RunContainer(image string, cmd string, volsrc string, voldest string) (output string, containerStarted bool, err error) {
func (e *podmanEngine) RunContainer(image string, cmd string, volsrc string, voldest string, copyUIDGID bool) (output string, containerStarted bool, err error) {
if !e.pullImage(image) {
logrus.Debugf("Unable to pull image using podman : %s", image)
return "", false, fmt.Errorf("unable to pull image")
Expand Down
2 changes: 1 addition & 1 deletion environment/container/podmanengine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestPodman(t *testing.T) {
t.Fatalf("Failed to find the image '%s' locally and/or pull it. Error: %v", image, err)
}

output, containerStarted, err := provider.RunContainer(image, "", "", "")
output, containerStarted, err := provider.RunContainer(image, "", "", "", false)
if err != nil {
t.Fatalf("Failed to run the container '%s' locally. Output: %v , containerStarted: %v Error: %v", image, output, containerStarted, err)
}
Expand Down
8 changes: 4 additions & 4 deletions environment/container/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"github.com/sirupsen/logrus"
)

func copyDirToContainer(ctx context.Context, cli *client.Client, containerID, src, dst string) error {
func copyDirToContainer(ctx context.Context, cli *client.Client, containerID, src, dst string, copyUIDGID bool) error {
reader := common.ReadFilesAsTar(src, dst, common.NoCompression)
if reader == nil {
err := fmt.Errorf("error during create tar archive from '%s'", src)
Expand All @@ -40,7 +40,7 @@ func copyDirToContainer(ctx context.Context, cli *client.Client, containerID, sr
doneChan := make(chan interface{})
pr, pw := io.Pipe()
go func() {
clientErr = cli.CopyToContainer(ctx, containerID, "/", pr, types.CopyToContainerOptions{})
clientErr = cli.CopyToContainer(ctx, containerID, "/", pr, types.CopyToContainerOptions{CopyUIDGID: copyUIDGID})
close(doneChan)
}()
func() {
Expand Down Expand Up @@ -73,7 +73,7 @@ func copyFromContainer(ctx context.Context, cli *client.Client, containerID stri
return archive.CopyTo(preArchive, copyInfo, destPath)
}

func copyDir(ctx context.Context, cli *client.Client, containerID, src, dst string) error {
func copyDir(ctx context.Context, cli *client.Client, containerID, src, dst string, copyUIDGID bool) error {
reader := common.ReadFilesAsTar(src, dst, common.NoCompression)
if reader == nil {
err := fmt.Errorf("error during create tar archive from '%s'", src)
Expand All @@ -85,7 +85,7 @@ func copyDir(ctx context.Context, cli *client.Client, containerID, src, dst stri
doneChan := make(chan interface{})
pr, pw := io.Pipe()
go func() {
clientErr = cli.CopyToContainer(ctx, containerID, "/", pr, types.CopyToContainerOptions{})
clientErr = cli.CopyToContainer(ctx, containerID, "/", pr, types.CopyToContainerOptions{CopyUIDGID: copyUIDGID})
close(doneChan)
}()
func() {
Expand Down
6 changes: 3 additions & 3 deletions environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type EnvironmentInstance interface {
Reset() error
Stat(name string) (fs.FileInfo, error)
Download(envpath string) (outpath string, err error)
Upload(outpath string) (envpath string, err error)
Upload(outpath string, copyUIDGID bool) (envpath string, err error)
Exec(cmd environmenttypes.Command, envList []string) (stdout string, stderr string, exitcode int, err error)
Destroy() error

Expand Down Expand Up @@ -196,7 +196,7 @@ func (e *Environment) Encode(obj interface{}) interface{} {
if !filepath.IsAbs(path) {
var err error
if e.CurrEnvOutputBasePath == "" {
e.CurrEnvOutputBasePath, err = e.Env.Upload(e.Output)
e.CurrEnvOutputBasePath, err = e.Env.Upload(e.Output, e.EnvInfo.CopyUIDGID)
}
return filepath.Join(e.CurrEnvOutputBasePath, path), err
}
Expand All @@ -221,7 +221,7 @@ func (e *Environment) Encode(obj interface{}) interface{} {
logrus.Error(err)
return "", err
}
return e.Env.Upload(path)
return e.Env.Upload(path, e.EnvInfo.CopyUIDGID)
}
if objS, ok := obj.(string); ok {
val, err := processPath(objS)
Expand Down
2 changes: 1 addition & 1 deletion environment/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func (e *Local) Download(sourcePath string) (string, error) {
}

// Upload uploads the path from outside the environment into it
func (e *Local) Upload(sourcePath string) (string, error) {
func (e *Local) Upload(sourcePath string, copyUIDGID bool) (string, error) {
destPath, err := os.MkdirTemp(e.TempPath, "*")
if err != nil {
return destPath, fmt.Errorf("failed to create the temp dir at path '%s' with pattern '*' . Error: %w", e.TempPath, err)
Expand Down
6 changes: 4 additions & 2 deletions environment/peercontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func NewPeerContainer(envInfo EnvInfo, grpcQAReceiver net.Addr, containerInfo en
peerContainer.OriginalImage,
peerContainer.ContainerInfo.Image,
map[string]string{envInfo.Source: peerContainer.WorkspaceSource},
envInfo.CopyUIDGID,
); err != nil {
err := fmt.Errorf("failed to create a new container image with the input data copied into the container. Error: %w", err)
if peerContainer.ContainerInfo.ImageBuild.Context == "" {
Expand All @@ -115,6 +116,7 @@ func NewPeerContainer(envInfo EnvInfo, grpcQAReceiver net.Addr, containerInfo en
peerContainer.OriginalImage,
peerContainer.ContainerInfo.Image,
map[string]string{envInfo.Source: peerContainer.WorkspaceSource},
envInfo.CopyUIDGID,
); err != nil {
return nil, fmt.Errorf("failed to copy paths to new container image. Error: %w", err)
}
Expand Down Expand Up @@ -208,7 +210,7 @@ func (e *PeerContainer) Download(path string) (string, error) {
}

// Upload uploads the path from outside the environment into it
func (e *PeerContainer) Upload(outpath string) (string, error) {
func (e *PeerContainer) Upload(outpath string, copyUIDGID bool) (string, error) {
envpath := "/var/tmp/" + uniuri.NewLen(5) + "/" + filepath.Base(outpath)
fileInfo, err := os.Stat(outpath)
if err != nil {
Expand All @@ -221,7 +223,7 @@ func (e *PeerContainer) Upload(outpath string) (string, error) {
if err != nil {
return envpath, fmt.Errorf("failed to get the container engine. Error: %w", err)
}
if err := cengine.CopyDirsIntoContainer(e.ContainerInfo.ID, map[string]string{outpath: envpath}); err != nil {
if err := cengine.CopyDirsIntoContainer(e.ContainerInfo.ID, map[string]string{outpath: envpath}, copyUIDGID); err != nil {
return envpath, fmt.Errorf("failed to copy data into the container with ID '%s' . Error: %w", e.ContainerInfo.ID, err)
}
return envpath, nil
Expand Down
2 changes: 1 addition & 1 deletion environment/peercontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func TestPeerContainer(t *testing.T) {

filename := "container/testdata/buildimage"

envPath, err := container.Upload(filename)
envPath, err := container.Upload(filename, false)
if err != nil {
t.Fatalf("Failed to upload file %s to environment: %s", filename, err)
}
Expand Down
1 change: 1 addition & 0 deletions environment/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ type EnvInfo struct {
TempPath string
EnvPlatformConfig environmenttypes.EnvPlatformConfig
SpawnContainers bool
CopyUIDGID bool
}
5 changes: 4 additions & 1 deletion transformer/external/executabletransformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type ExecutableYamlConfig struct {
DirectoryDetectCMD environmenttypes.Command `yaml:"directoryDetectCMD"`
TransformCMD environmenttypes.Command `yaml:"transformCMD"`
Container environmenttypes.Container `yaml:"container,omitempty"`
CopyUIDGID bool `default:"true" yaml:"copyUIDGID"`
}

var (
Expand Down Expand Up @@ -97,6 +98,8 @@ func (t *Executable) Init(tc transformertypes.Transformer, env *environment.Envi
Container: t.ExecConfig.Container,
Platforms: t.ExecConfig.Platforms,
}
env.EnvInfo.CopyUIDGID = t.ExecConfig.CopyUIDGID

t.Env, err = environment.NewEnvironment(env.EnvInfo, qaRPCReceiverAddr)
if err != nil {
return fmt.Errorf("failed to create the environment for the executable transformer. Error: %w", err)
Expand Down Expand Up @@ -247,7 +250,7 @@ func (t *Executable) uploadInput(data interface{}, inputFile string) (string, er
if err := common.WriteJSON(inputFilePath, data); err != nil {
return "", fmt.Errorf("failed to create the input json. Error: %w", err)
}
containerInputDir, err := t.Env.Env.Upload(inputDirPath)
containerInputDir, err := t.Env.Env.Upload(inputDirPath, t.ExecConfig.CopyUIDGID)
if err != nil {
return "", fmt.Errorf("failed to copy input dir to new container image. Error: %w", err)
}
Expand Down
Loading