Added build script and fixed some bugs

This commit is contained in:
ndouba
2022-11-15 22:32:24 -05:00
parent 8f19249c51
commit 9cc4b28a49
9 changed files with 317 additions and 12 deletions

94
.dockerignore Normal file
View File

@@ -0,0 +1,94 @@
### Linux template
.idea
*.iml
device-volume-driver
plugin
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
### Windows template
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### macOS template
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
build.sh
config.json

2
.gitignore vendored
View File

@@ -3,7 +3,7 @@
.idea
*.iml
device-volume-driver
plugin
*~
# temporary files which can be created if a process still has a handle open of a deleted file

17
Dockerfile Normal file
View File

@@ -0,0 +1,17 @@
FROM debian
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /go/src/github.com/allfro/device-volume-driver
COPY . .
RUN apt update && \
apt install -y musl-dev musl-tools git curl && \
curl -L -o go.tgz https://go.dev/dl/go1.19.3.linux-amd64.tar.gz && \
tar -zxvf go.tgz && \
export PATH=$PATH:go/bin && \
go get && \
CC=/usr/bin/musl-gcc go build -ldflags "-linkmode external -extldflags -static" -o /dvd
FROM alpine
COPY --from=0 /dvd /dvd
ENTRYPOINT ["/dvd"]

20
build.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/sh
set -eux
ROOTFS=plugin/rootfs
CONFIG=plugin/config.json
tag=redcanari/device-volume-driver
docker build -t "$tag" -f Dockerfile .
id=$(docker create "$tag" true)
rm -Rf $ROOTFS
mkdir -p $ROOTFS
docker export "$id" | tar -x -C $ROOTFS
docker rm -vf "$id"
docker rmi "$tag"
cp config.json $CONFIG
docker plugin rm -f redcanari/device-volume-driver || echo
docker plugin create redcanari/device-volume-driver ./plugin
docker plugin enable redcanari/device-volume-driver

72
config.json Normal file
View File

@@ -0,0 +1,72 @@
{
"Args": {
"Description": "",
"Name": "",
"Settable": null,
"Value": null
},
"Description": "A device mapping plugin for swarm clusters",
"Documentation": "https://docs.docker.com/engine/extend/plugins/",
"Entrypoint": [
"/dvd"
],
"Env": [
{
"Description": "",
"Name": "DEBUG",
"Settable": [
"value"
],
"Value": "0"
}
],
"Interface": {
"Socket": "dvd.sock",
"Types": [
"docker.volumedriver/1.0"
]
},
"Linux": {
"Capabilities": [
"CAP_SYS_ADMIN"
],
"AllowAllDevices": true,
"Devices": null
},
"Mounts": [
{
"source": "/sys/fs/cgroup",
"destination": "/sys/fs/cgroup",
"options": [
"bind",
"rw"
],
"type": "cgroup"
},
{
"destination": "/dev",
"source": "/dev",
"options": [
"bind",
"rw"
],
"type": "bind"
},
{
"destination": "/var/run/docker.sock",
"source": "/var/run/docker.sock",
"options": [
"bind",
"ro",
"private"
],
"type": "bind"
}
],
"Network": {
"Type": ""
},
"PropagatedMount": "/dev",
"User": {},
"Workdir": "/"
}

15
docker-compose.yml Normal file
View File

@@ -0,0 +1,15 @@
version: "3.8"
volumes:
fuse:
driver: redcanari/device-volume-driver
driver_opts:
device: /dev/fuse
services:
rdesktop:
image: lscr.io/linuxserver/rdesktop:ubuntu-xfce
volumes:
- fuse:/dev/fuse
ports:
- 3390:3389

10
go.mod
View File

@@ -3,27 +3,33 @@ module device-volume-driver
go 1.19
require (
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774
github.com/docker/docker v20.10.21+incompatible
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651
github.com/opencontainers/runtime-spec v1.0.2
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
)
require (
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/cilium/ebpf v0.9.1 // indirect
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.7.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/time v0.2.0 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gotest.tools/v3 v3.4.0 // indirect
)

29
go.sum
View File

@@ -1,8 +1,14 @@
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/cilium/ebpf v0.9.1 h1:64sn2K3UKw8NbP/blsixRpF3nXuyhz/VjRlRzvlBRu4=
github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774 h1:Tej/o6wjJ3icV9qkPopNXJxk2oeVAmRc7JL0q5JeUq8=
github.com/containerd/cgroups/v3 v3.0.0-20221112182753-e8802a182774/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
@@ -15,12 +21,18 @@ github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651 h1:YcvzL
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651/go.mod h1:LFyLie6XcDbyKGeVK6bHe+9aJTYCxWLBg5IrJZOaXKA=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c h1:RC8WMpjonrBfyAh6VN/POIPtYD5tRAq0qMqCRjQNK+g=
github.com/moby/term v0.0.0-20221105221325-4eb28fa6025c/go.mod h1:9OcmHNQQUTbk4XCffrLgN1NEKc2mh5u++biHVrvHsSU=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
@@ -29,16 +41,20 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -76,6 +92,11 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=

70
main.go
View File

@@ -1,9 +1,14 @@
package main
import (
"context"
"errors"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
"github.com/docker/go-plugins-helpers/volume"
_ "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
"log"
"os"
@@ -12,7 +17,7 @@ import (
"time"
)
const pluginId = "device-volume-driver"
const pluginId = "dvd"
func main() {
driver := DeviceVolumeDriver()
@@ -20,7 +25,9 @@ func main() {
log.Println(handler.ServeUnix(pluginId, 0))
}
type deviceVolumeDriver struct{}
type deviceVolumeDriver struct {
*client.Client
}
type mountPoint struct {
name string
@@ -88,11 +95,27 @@ func (d deviceVolumeDriver) Mount(request *volume.MountRequest) (*volume.MountRe
go func() {
time.Sleep(time.Second * 1)
devicesAllowPath := path.Join("/sys/fs/cgroup/devices/docker", request.ID, "devices.allow")
filter := filters.NewArgs(filters.KeyValuePair{Key: "volume", Value: request.Name})
containers, err := d.ContainerList(
context.Background(),
types.ContainerListOptions{Filters: filter},
)
if err != nil {
log.Println(err)
return
} else if len(containers) == 0 {
log.Println("aborting: could not find container that uses volume " + mountPoint.name)
return
}
devicesAllowPath := path.Join("/sys/fs/cgroup/devices/docker", containers[0].ID, "devices.allow")
if _, err := os.Stat(devicesAllowPath); os.IsNotExist(err) {
//return nil, errors.New("could not find cgroup `devices.allow` file for specified container: " + devicesAllowPath)
log.Println(errors.New("could not find cgroup `devices.allow` file for specified container: " + devicesAllowPath))
return
}
var stat unix.Stat_t
@@ -100,14 +123,18 @@ func (d deviceVolumeDriver) Mount(request *volume.MountRequest) (*volume.MountRe
if err := unix.Stat(mountPoint.device, &stat); err != nil {
//return nil, err
log.Println(err)
return
}
dev := uint64(stat.Rdev)
input := fmt.Sprintf("c %i:%i rwm\n", unix.Major(dev), unix.Minor(dev))
input := fmt.Sprintf("c %d:%d rwm\n", unix.Major(dev), unix.Minor(dev))
log.Println("Whitelisting `" + mountPoint.device + "` in `" + devicesAllowPath + "`")
if err := os.WriteFile(devicesAllowPath, []byte(input), 0400); err != nil {
//return nil, err
log.Println(err)
return
}
}()
@@ -122,6 +149,39 @@ func (d deviceVolumeDriver) Capabilities() *volume.CapabilitiesResponse {
return &volume.CapabilitiesResponse{Capabilities: volume.Capability{Scope: "local"}}
}
type pointer64 *int64
func DeviceVolumeDriver() *deviceVolumeDriver {
return &deviceVolumeDriver{}
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
//m, err := cgroup2.LoadSystemd("/system.slice", "docker-9ac190cfc7040ffb1a56315b0c4aba9a554e72aa43164c4b94e84ee5ae3d07d9.scope")
//
//if err != nil {
// log.Fatal(err)
//}
//
//major := int64(10)
//minor := int64(229)
//err = m.Update(&cgroup2.Resources{
// Devices: []specs.LinuxDeviceCgroup{
// {
// Allow: true,
// Type: "c",
// Major: &major,
// Minor: &minor,
// Access: "rwm",
// },
// },
//})
//
//if err != nil {
// log.Fatal(err)
//}
//
//os.Exit(0)
return &deviceVolumeDriver{cli}
}