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 ed908e3
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 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: %v", 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 @@ -288,10 +292,12 @@ func TestNodePublishVolume(t *testing.T) {
if err == nil {
assert.Equal(t, &csi.NodePublishVolumeResponse{}, resp)
assertMounted(t, targetPath, workloadAPISocketDir)
assertSELinuxLabelWritten(t, workloadAPISocketDir)
} else {
assert.Nil(t, resp)
assertNotMounted(t, targetPath)
}

})
}
}
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

0 comments on commit ed908e3

Please sign in to comment.