Repository: nektos/act (language: go)

Issue:
new-action-cache: rootless containers cannot read actions due to access level
_This is behind a feature flag and doesn't cause problems unless explicit opt in_

Using rootful container avoids the problem


Discussion / hints:
ls shows this
```
total 0
-????????? ? ? ? ?            ? CODE_OF_CONDUCT.md
-????????? ? ? ? ?            ? CONTRIBUTING.md
-????????? ? ? ? ?            ? LICENSE
-????????? ? ? ? ?            ? README.md
d????????? ? ? ? ?            ? __tests__
-????????? ? ? ? ?            ? action.yml
d????????? ? ? ? ?            ? dist
d????????? ? ? ? ?            ? docs
-????????? ? ? ? ?            ? jest.config.js
-????????? ? ? ? ?            ? package-lock.json
-????????? ? ? ? ?            ? package.json
d????????? ? ? ? ?            ? src
-????????? ? ? ? ?            ? tsconfig.json
```
Permission bits of tar has failed badly.

Fix patch:
diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go
index c61301b5e18..fe377fdc95a 100644
--- a/pkg/container/docker_run.go
+++ b/pkg/container/docker_run.go
@@ -679,7 +679,7 @@ func (cr *containerReference) CopyTarStream(ctx context.Context, destPath string
 	tw := tar.NewWriter(buf)
 	_ = tw.WriteHeader(&tar.Header{
 		Name:     destPath,
-		Mode:     777,
+		Mode:     0o777,
 		Typeflag: tar.TypeDir,
 	})
 	tw.Close()


Test patch:
diff --git a/pkg/container/docker_run_test.go b/pkg/container/docker_run_test.go
index 96bda59214e..7205a26d650 100644
--- a/pkg/container/docker_run_test.go
+++ b/pkg/container/docker_run_test.go
@@ -2,7 +2,9 @@ package container
 
 import (
 	"bufio"
+	"bytes"
 	"context"
+	"fmt"
 	"io"
 	"net"
 	"strings"
@@ -75,6 +77,11 @@ func (m *mockDockerClient) ContainerExecInspect(ctx context.Context, execID stri
 	return args.Get(0).(types.ContainerExecInspect), args.Error(1)
 }
 
+func (m *mockDockerClient) CopyToContainer(ctx context.Context, id string, path string, content io.Reader, options types.CopyToContainerOptions) error {
+	args := m.Called(ctx, id, path, content, options)
+	return args.Error(0)
+}
+
 type endlessReader struct {
 	io.Reader
 }
@@ -165,5 +172,77 @@ func TestDockerExecFailure(t *testing.T) {
 	client.AssertExpectations(t)
 }
 
+func TestDockerCopyTarStream(t *testing.T) {
+	ctx := context.Background()
+
+	conn := &mockConn{}
+
+	client := &mockDockerClient{}
+	client.On("CopyToContainer", ctx, "123", "/", mock.Anything, mock.AnythingOfType("types.CopyToContainerOptions")).Return(nil)
+	client.On("CopyToContainer", ctx, "123", "/var/run/act", mock.Anything, mock.AnythingOfType("types.CopyToContainerOptions")).Return(nil)
+	cr := &containerReference{
+		id:  "123",
+		cli: client,
+		input: &NewContainerInput{
+			Image: "image",
+		},
+	}
+
+	_ = cr.CopyTarStream(ctx, "/var/run/act", &bytes.Buffer{})
+
+	conn.AssertExpectations(t)
+	client.AssertExpectations(t)
+}
+
+func TestDockerCopyTarStreamErrorInCopyFiles(t *testing.T) {
+	ctx := context.Background()
+
+	conn := &mockConn{}
+
+	merr := fmt.Errorf("Failure")
+
+	client := &mockDockerClient{}
+	client.On("CopyToContainer", ctx, "123", "/", mock.Anything, mock.AnythingOfType("types.CopyToContainerOptions")).Return(merr)
+	client.On("CopyToContainer", ctx, "123", "/", mock.Anything, mock.AnythingOfType("types.CopyToContainerOptions")).Return(merr)
+	cr := &containerReference{
+		id:  "123",
+		cli: client,
+		input: &NewContainerInput{
+			Image: "image",
+		},
+	}
+
+	err := cr.CopyTarStream(ctx, "/var/run/act", &bytes.Buffer{})
+	assert.ErrorIs(t, err, merr)
+
+	conn.AssertExpectations(t)
+	client.AssertExpectations(t)
+}
+
+func TestDockerCopyTarStreamErrorInMkdir(t *testing.T) {
+	ctx := context.Background()
+
+	conn := &mockConn{}
+
+	merr := fmt.Errorf("Failure")
+
+	client := &mockDockerClient{}
+	client.On("CopyToContainer", ctx, "123", "/", mock.Anything, mock.AnythingOfType("types.CopyToContainerOptions")).Return(nil)
+	client.On("CopyToContainer", ctx, "123", "/var/run/act", mock.Anything, mock.AnythingOfType("types.CopyToContainerOptions")).Return(merr)
+	cr := &containerReference{
+		id:  "123",
+		cli: client,
+		input: &NewContainerInput{
+			Image: "image",
+		},
+	}
+
+	err := cr.CopyTarStream(ctx, "/var/run/act", &bytes.Buffer{})
+	assert.ErrorIs(t, err, merr)
+
+	conn.AssertExpectations(t)
+	client.AssertExpectations(t)
+}
+
 // Type assert containerReference implements ExecutionsEnvironment
 var _ ExecutionsEnvironment = &containerReference{}