Skip to content

Commit

Permalink
Set container file label on workload API directory
Browse files Browse the repository at this point in the history
This allows the driver to be used within OpenShift without using an init
container to set the label.

Fixes #54.

Signed-off-by: Andrew Harding <[email protected]>
  • Loading branch information
azdagron committed May 14, 2023
1 parent 2aae3aa commit 6d03ceb
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/opencontainers/selinux v1.11.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
13 changes: 13 additions & 0 deletions pkg/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@ import (

"github.com/container-storage-interface/spec/lib/go/csi"
"github.com/go-logr/logr"
"github.com/opencontainers/selinux/go-selinux"
"github.com/spiffe/spiffe-csi/internal/version"
"github.com/spiffe/spiffe-csi/pkg/logkeys"
"github.com/spiffe/spiffe-csi/pkg/mount"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

const (
seLinuxContainerFileLabel = "container_file_t"
)

var (
// We replace these in tests since bind mounting generally requires root.
bindMountRW = mount.BindMountRW
unmount = mount.Unmount
isMountPoint = mount.IsMountPoint
chcon = selinux.Chcon
)

// Config is the configuration for the driver
Expand Down Expand Up @@ -49,6 +55,13 @@ func New(config Config) (*Driver, error) {
case config.WorkloadAPISocketDir == "":
return nil, errors.New("workload API socket directory is required")
}

// Set the SELinux label on the workload API directory. This allows the
// mount to be used within OpenShift, for example.
if err := chcon(config.WorkloadAPISocketDir, seLinuxContainerFileLabel, true); err != nil {
return nil, fmt.Errorf("failed to set the SELinux label: %w", err)
}

return &Driver{
log: config.Log,
nodeID: config.NodeID,
Expand Down
26 changes: 26 additions & 0 deletions pkg/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func init() {
unmount = func(dst string) error {
return os.Remove(metaPath(dst))
}
chcon = func(fpath, label string, recursive bool) error {
fmt.Println("CHCON", fpath, label, recursive)
return writeSELinuxLabel(fpath, label, recursive)
}
}

func TestNew(t *testing.T) {
Expand Down Expand Up @@ -283,6 +287,8 @@ func TestNodePublishVolume(t *testing.T) {

client, workloadAPISocketDir := startDriver(t)

assertSELinuxLabelWritten(t, workloadAPISocketDir)

resp, err := client.NodePublishVolume(context.Background(), req)
requireGRPCStatusPrefix(t, err, tt.expectCode, tt.expectMsgPrefix)
if err == nil {
Expand Down Expand Up @@ -469,6 +475,13 @@ func assertNotMounted(t *testing.T, targetPath string) {
assert.Error(t, err, "should not be mounted")
}

func assertSELinuxLabelWritten(t *testing.T, fpath string) {
label, err := readSELinuxLabel(fpath)
if assert.NoError(t, err, "failed to read selinux label file") {
assert.Equal(t, "container_file_t-recursive-true", label)
}
}

func readMeta(targetPath string) (string, error) {
data, err := os.ReadFile(metaPath(targetPath))
return string(data), err
Expand All @@ -478,10 +491,23 @@ func writeMeta(targetPath string, meta string) error {
return os.WriteFile(metaPath(targetPath), []byte(meta), 0600)
}

func readSELinuxLabel(fpath string) (string, error) {
data, err := os.ReadFile(seLinuxLabelPath(fpath))
return string(data), err
}

func writeSELinuxLabel(fpath string, label string, recursive bool) error {
return os.WriteFile(seLinuxLabelPath(fpath), []byte(fmt.Sprintf("%s-recursive-%t", label, recursive)), 0600)
}

func metaPath(targetPath string) string {
return filepath.Join(targetPath, "meta")
}

func seLinuxLabelPath(targetPath string) string {
return filepath.Join(targetPath, "selinux-label")
}

func dumpIt(t *testing.T, when, dir string) {
t.Logf(">>>>>>>>>> DUMPING %s %s", when, dir)
assert.NoError(t, filepath.Walk(dir, filepath.WalkFunc(
Expand Down
2 changes: 1 addition & 1 deletion test/config/spiffe-csi-driver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ spec:
# driver will mount this directory into containers.
- mountPath: /spire-agent-socket
name: spire-agent-socket-dir
readOnly: true
#readOnly: true
# The volume that will contain the CSI driver socket shared
# with the kubelet and the driver registrar.
- mountPath: /spiffe-csi
Expand Down
12 changes: 11 additions & 1 deletion test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ esac


cleanup() {
if [ -z "${SUCCESS}" ]; then
"${KUBECTL}" logs deployment/spire-server -nspire-system --all-containers=true || true
"${KUBECTL}" logs daemonset/spire-agent -nspire-system --all-containers=true || true
"${KUBECTL}" logs daemonset/spiffe-csi-driver -nspire-system --all-containers=true || true
"${KUBECTL}" logs deployment/test-workload-1 --all-containers=true || true
"${KUBECTL}" logs deployment/test-workload-2 --all-containers=true || true
fi

delete-cluster
rm -rf "${TMPDIR}"
}
Expand Down Expand Up @@ -104,6 +112,8 @@ apply-yaml() {
"${KUBECTL}" rollout status -w --timeout=1m -nspire-system deployment/spire-server
echo "Waiting for SPIRE agent rollout..."
"${KUBECTL}" rollout status -w --timeout=1m -nspire-system daemonset/spire-agent
echo "Waiting for SPIFFE CSI driver rollout..."
"${KUBECTL}" rollout status -w --timeout=1m -nspire-system daemonset/spiffe-csi-driver
echo "Waiting for test workload 1 rollout..."
"${KUBECTL}" rollout status -w --timeout=1m deployment/test-workload-1
echo "Waiting for test workload 2 rollout..."
Expand Down Expand Up @@ -159,5 +169,5 @@ apply-yaml
register-workload
check-workload-status "test-workload-1"
check-workload-status "test-workload-2"
"${KUBECTL}" logs -nspire-system daemonset/spiffe-csi-driver -c spiffe-csi-driver
SUCCESS=1
echo "Done."

0 comments on commit 6d03ceb

Please sign in to comment.