From 3991ecdc7c4ce201134cbf03179a767ca31e1ba8 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 11:38:06 +0000 Subject: [PATCH 01/14] Add initial support for podman Signed-off-by: Paulo Gomes --- internal/deps/deps.go | 8 +++---- internal/files/binaries.go | 23 +++++++++++++++++- internal/images/images.go | 4 ++-- internal/profiles/profiles.go | 24 +++++++++---------- internal/runners/docker/run.go | 35 ++++++++++++++-------------- internal/runners/firecracker/deps.go | 2 +- internal/runners/firecracker/run.go | 2 +- 7 files changed, 60 insertions(+), 38 deletions(-) diff --git a/internal/deps/deps.go b/internal/deps/deps.go index cfb917d..da2b222 100644 --- a/internal/deps/deps.go +++ b/internal/deps/deps.go @@ -14,16 +14,16 @@ var deps map[string][]string = map[string][]string{ files.ShBinary, }, "run": { - files.DockerBinary, + files.ContainerRunnerBinary, }, "xdg-open": { - files.DockerBinary, + files.ContainerRunnerBinary, }, "images": { - files.DockerBinary, + files.ContainerRunnerBinary, }, "profiles": { - files.DockerBinary, + files.ContainerRunnerBinary, files.ShBinary, files.XrandrBinary, }, diff --git a/internal/files/binaries.go b/internal/files/binaries.go index 8a7c16b..e4e091c 100644 --- a/internal/files/binaries.go +++ b/internal/files/binaries.go @@ -1,9 +1,30 @@ package files +import ( + "fmt" + "os/exec" +) + +func init() { + p, err := exec.LookPath("podman") + if err != nil { + p2, err := exec.LookPath("docker") + if err == nil { + fmt.Println("falling back to docker") + ContainerRunnerBinary = p2 + } + } + + ContainerRunnerBinary = p +} + +var ( + ContainerRunnerBinary = "/usr/bin/podman" +) + const ( ShBinary = "/bin/sh" XclipBinary = "/usr/bin/xclip" - DockerBinary = "/usr/bin/docker" FireCrackerBinary = "/usr/bin/firecracker" XrandrBinary = "/usr/bin/xrandr" DbusBinary = "/usr/bin/dbus-send" diff --git a/internal/images/images.go b/internal/images/images.go index 4ee2e3d..a7a466c 100644 --- a/internal/images/images.go +++ b/internal/images/images.go @@ -123,7 +123,7 @@ func PullAll(cfg *types.Config) error { func PullImage(image string) error { slog.Info("pulling container image", "image", image) - cmd := execabs.Command(files.DockerBinary, "pull", image) //nolint + cmd := execabs.Command(files.ContainerRunnerBinary, "pull", image) //nolint cmd.Stdout = os.Stdout return cmd.Run() @@ -131,7 +131,7 @@ func PullImage(image string) error { func PullImageIfNotPresent(image string) error { slog.Debug("checking if container image is present", "image", image) - cmd := execabs.Command(files.DockerBinary, "images", "-q", image) //nolint + cmd := execabs.Command(files.ContainerRunnerBinary, "images", "-q", image) //nolint out, err := cmd.Output() if len(out) > 0 && err == nil { diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index be75126..2aaf466 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -254,12 +254,12 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { return fmt.Errorf("failed to start profile: %s", msg) } - if !profile.Dbus { - err = startDbus(name) - if err != nil { - return err - } - } + // if !profile.Dbus { + // err = startDbus(name) + // if err != nil { + // return err + // } + // } err = startWindowManager(name, strconv.Itoa(int(profile.Display)), profile.WindowManager) if err != nil { @@ -273,7 +273,7 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { func containerRunning(name string) bool { args := fmt.Sprintf("ps -q -f name=%s", name) fmt.Println(args) - cmd := execabs.Command(files.DockerBinary, //nolint:gosec + cmd := execabs.Command(files.ContainerRunnerBinary, //nolint:gosec strings.Split(args, " ")...) out, err := cmd.Output() @@ -330,8 +330,8 @@ func createMagicCookie(profile *types.Profile) error { func startWindowManager(name, display, wm string) error { args := []string{"exec", name, files.ShBinary, "-c", fmt.Sprintf("DISPLAY=:%s %s", display, wm)} - slog.Debug(files.DockerBinary+" exec", "container-name", name, "args", args) - cmd := execabs.Command(files.DockerBinary, args...) //nolint + slog.Debug(files.ContainerRunnerBinary+" exec", "container-name", name, "args", args) + cmd := execabs.Command(files.ContainerRunnerBinary, args...) //nolint output, err := cmd.CombinedOutput() if err != nil { @@ -352,8 +352,8 @@ func startDbus(name string) error { "--address=unix:path=/run/user/1000/bus", } - slog.Debug(files.DockerBinary+" exec", "container-name", name, "args", args) - cmd := execabs.Command(files.DockerBinary, args...) //nolint + slog.Debug(files.ContainerRunnerBinary+" exec", "container-name", name, "args", args) + cmd := execabs.Command(files.ContainerRunnerBinary, args...) //nolint output, err := cmd.CombinedOutput() if err != nil { @@ -499,7 +499,7 @@ func createNewDisplay(profile *types.Profile, display string) error { dockerArgs = append(dockerArgs, cArgs...) slog.Debug("exec: docker", "args", dockerArgs) - cmd := execabs.Command(files.DockerBinary, dockerArgs...) //nolint + cmd := execabs.Command(files.ContainerRunnerBinary, dockerArgs...) //nolint output, err := cmd.CombinedOutput() if err != nil { diff --git a/internal/runners/docker/run.go b/internal/runners/docker/run.go index b81532d..9bb130b 100644 --- a/internal/runners/docker/run.go +++ b/internal/runners/docker/run.go @@ -52,7 +52,7 @@ x-scheme-handler/snap=snap-handle-link.desktop; func ContainerID(name string) (string, bool) { args := fmt.Sprintf("ps -a -q -f name=%s", name) - cmd := execabs.Command(files.DockerBinary, //nolint:gosec + cmd := execabs.Command(files.ContainerRunnerBinary, //nolint:gosec strings.Split(args, " ")...) out, err := cmd.Output() @@ -69,8 +69,8 @@ func exec(id string, ew types.EffectiveWorkload) error { args := []string{"exec", "--detach", id, ew.Workload.Command} args = append(args, ew.Workload.Args...) - slog.Debug(files.DockerBinary+" exec", "container-id", id, "cmd", ew.Workload.Command, "args", ew.Workload.Args) - cmd := execabs.Command(files.DockerBinary, args...) //nolint + slog.Debug(files.ContainerRunnerBinary+" exec", "container-id", id, "cmd", ew.Workload.Command, "args", ew.Workload.Args) + cmd := execabs.Command(files.ContainerRunnerBinary, args...) //nolint return cmd.Run() } @@ -116,7 +116,8 @@ func Run(ew types.EffectiveWorkload) error { "--rm", "-d", "--security-opt=seccomp=unconfined", - "--security-opt=no-new-privileges:true", + "--security-opt=no-new-privileges=true", + "--group-add=keep-groups", } if ew.Workload.User != nil { @@ -150,7 +151,7 @@ func Run(ew types.EffectiveWorkload) error { } if wl.HostAccess.Dbus || wl.HostAccess.Bluetooth || wl.HostAccess.VarRunUser { - args = append(args, "-v=/run/user/1000:/run/user/1000") + args = append(args, "-v=/run/user/1000:/run/user/1000:z") } userDir, err := files.IsolatedRunUserPath(ew.Profile.Name) @@ -161,7 +162,7 @@ func Run(ew types.EffectiveWorkload) error { if wl.HostAccess.Dbus || wl.HostAccess.Bluetooth || wl.HostAccess.VarRunUser { args = append(args, hostDbusParams()...) } else { - paths = append(paths, fmt.Sprintf("-v=%s:/run/user/1000", userDir)) + paths = append(paths, fmt.Sprintf("-v=%s:/run/user/1000:z", userDir)) machineIDPath := filepath.Join(files.ProfileDir(ew.Profile.Name), "machine-id") paths = append(paths, fmt.Sprintf("-v=%s:/etc/machine-id:ro", machineIDPath)) @@ -272,15 +273,15 @@ func Run(ew types.EffectiveWorkload) error { } dst := ps[1] - args = append(args, fmt.Sprintf("-v=%s:%s", src, dst)) + args = append(args, fmt.Sprintf("-v=%s:%s:z", src, dst)) } args = append(args, wl.Image) args = append(args, wl.Command) args = append(args, wl.Args...) - slog.Debug(fmt.Sprintf("exec: %s", files.DockerBinary), "args", args) - cmd := execabs.Command(files.DockerBinary, args...) //nolint + slog.Debug(fmt.Sprintf("exec: %s", files.ContainerRunnerBinary), "args", args) + cmd := execabs.Command(files.ContainerRunnerBinary, args...) //nolint cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin @@ -292,8 +293,8 @@ func Run(ew types.EffectiveWorkload) error { func getHomeDir(image string) (string, error) { args := []string{"run", "--rm", image, "ls", "/home"} - slog.Debug(files.DockerBinary + " " + strings.Join(args, " ")) - cmd := execabs.Command(files.DockerBinary, args...) //nolint + slog.Debug(files.ContainerRunnerBinary + " " + strings.Join(args, " ")) + cmd := execabs.Command(files.ContainerRunnerBinary, args...) //nolint out, err := cmd.Output() if err != nil { @@ -305,9 +306,9 @@ func getHomeDir(image string) (string, error) { func hostDbusParams() []string { return []string{ - "-v=/run/dbus/system_bus_socket:/run/dbus/system_bus_socket", - "-v=/var/lib/dbus:/var/lib/dbus", - "-v=/usr/share/dbus-1:/usr/share/dbus-1", + "-v=/run/dbus/system_bus_socket:/run/dbus/system_bus_socket:z", + "-v=/var/lib/dbus:/var/lib/dbus:z", + "-v=/usr/share/dbus-1:/usr/share/dbus-1:z", // At the moment we are mapping /run/user/1000 when // the host Dbus is being used. Therefore, there is no // point in mounting descending dirs. @@ -322,7 +323,7 @@ func hostDbusParams() []string { func cameraParams() []string { params := []string{ - "--group-add=video", + // "--group-add=video", } vds, _ := filepath.Glob("/dev/video*") @@ -336,8 +337,8 @@ func cameraParams() []string { func audioParams() []string { return []string{ // TODO: For Bluetooth (Apple AirPods) you may require /run/user/1000 shared via VarRunUser - "-v=/run/user/1000/pipewire-0:/run/user/1000/pipewire-0", + "-v=/run/user/1000/pipewire-0:/run/user/1000/pipewire-0:z", "--device=/dev/snd", - "--group-add=audio", + // "--group-add=audio", } } diff --git a/internal/runners/firecracker/deps.go b/internal/runners/firecracker/deps.go index e6486ac..0fef097 100644 --- a/internal/runners/firecracker/deps.go +++ b/internal/runners/firecracker/deps.go @@ -74,7 +74,7 @@ func ensureDependencies(img string) error { func setupTaps(img string) error { slog.Info("setting up taps") - cmd := execabs.Command(files.DockerBinary, //nolint + cmd := execabs.Command(files.ContainerRunnerBinary, //nolint "run", "--rm", "--privileged", "--network", "host", img, diff --git a/internal/runners/firecracker/run.go b/internal/runners/firecracker/run.go index b8caf44..f75653f 100644 --- a/internal/runners/firecracker/run.go +++ b/internal/runners/firecracker/run.go @@ -23,7 +23,7 @@ type configParams struct { func createRootFs(dir, img string) (string, error) { slog.Info("creating root fs") rootfs := filepath.Join(dir, "roofs.ext4") - cmd := execabs.Command(files.DockerBinary, //nolint + cmd := execabs.Command(files.ContainerRunnerBinary, //nolint "run", "--rm", "--privileged", "-v", "/tmp/:/tmp/", img, From 65d74e3f776a3499d2e0774fee7d1c6e5872730d Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 12:16:03 +0000 Subject: [PATCH 02/14] build: Move main.go for easier installation Signed-off-by: Paulo Gomes --- Makefile | 2 +- README.md | 4 ++-- main.go => cmd/qubesome/main.go | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename main.go => cmd/qubesome/main.go (100%) diff --git a/Makefile b/Makefile index 0e268e6..dfc5676 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ help: ## display Makefile's help. .PHONY: build build: ## build qubesome to the path set on TARGET_BIN. - go build -trimpath -tags 'netgo,osusergo,static_build' -ldflags '-extldflags -static -s -w' -o $(TARGET_BIN) main.go + go build -trimpath -tags 'netgo,osusergo,static_build' -ldflags '-extldflags -static -s -w' -o $(TARGET_BIN) cmd/qubesome/main.go .PHONY: test test: ## run golang tests. diff --git a/README.md b/README.md index 68b49e3..54b1cae 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ storage, etc). #### Install ##### Using Go ``` -go install github.com/qubesome/cli@latest +go install github.com/qubesome/cli/cmd/qubesome@latest ``` ##### For Tumbleweed users @@ -73,7 +73,7 @@ For more information on each command, run `qubesome --help`. #### Minimum -Qubesome requires `docker` and `xrandr` installed on a machine +Qubesome requires `docker` (or `podman`) and `xrandr` installed on a machine running Xorg. To install them using zypper: ``` sudo zypper install -y docker xrandr diff --git a/main.go b/cmd/qubesome/main.go similarity index 100% rename from main.go rename to cmd/qubesome/main.go From ba80be5b1b672b395bf0bd54285fd4fafbb3cde3 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 12:22:58 +0000 Subject: [PATCH 03/14] build: Bump dependencies Signed-off-by: Paulo Gomes --- go.mod | 20 ++++++++++---------- go.sum | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index e18d84c..8eeadeb 100644 --- a/go.mod +++ b/go.mod @@ -3,33 +3,33 @@ module github.com/qubesome/cli go 1.22.4 require ( - github.com/cyphar/filepath-securejoin v0.3.0 - github.com/go-git/go-git/v5 v5.12.0 + github.com/cyphar/filepath-securejoin v0.3.4 + github.com/go-git/go-git/v5 v5.12.1-0.20241115094014-70dd9f8347eb github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.9.0 - golang.org/x/sys v0.22.0 + golang.org/x/sys v0.27.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - dario.cat/mergo v1.0.0 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.0.0 // indirect - github.com/cloudflare/circl v1.3.9 // indirect + github.com/ProtonMail/go-crypto v1.1.2 // indirect + github.com/cloudflare/circl v1.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-billy/v5 v5.6.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/net v0.31.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index dd3fae0..0a32958 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,14 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.1.2 h1:A7JbD57ThNqh7XjmHE+PXpQ3Dqt3BrSAC0AL0Go3KS0= +github.com/ProtonMail/go-crypto v1.1.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -13,8 +17,12 @@ github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= +github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= +github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cyphar/filepath-securejoin v0.3.0 h1:tXpmbiaeBrS/K2US8nhgwdKYnfAOnVfkcLPKFgFHeA0= github.com/cyphar/filepath-securejoin v0.3.0/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= +github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8= +github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -28,10 +36,14 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66D github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-git/v5 v5.12.1-0.20241115094014-70dd9f8347eb h1:TEo1aHmTS/QU1IIYczLGhqUEp8m03a7bk3ZdRHoUonk= +github.com/go-git/go-git/v5 v5.12.1-0.20241115094014-70dd9f8347eb/go.mod h1:KECzDiPamjQz6lBAKQI+cIhdDfUcb64jyErZarVFKIE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -64,6 +76,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -81,6 +95,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -92,6 +108,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -110,6 +128,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= From 038151be1843a861ab6f7446ddad439b395785a0 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 12:25:40 +0000 Subject: [PATCH 04/14] build: Bump Go to v1.23 Signed-off-by: Paulo Gomes --- go.mod | 2 +- go.sum | 77 ++++++++-------------------------------------------------- 2 files changed, 11 insertions(+), 68 deletions(-) diff --git a/go.mod b/go.mod index 8eeadeb..7f6bb11 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/qubesome/cli -go 1.22.4 +go 1.23.3 require ( github.com/cyphar/filepath-securejoin v0.3.4 diff --git a/go.sum b/go.sum index 0a32958..b1ef886 100644 --- a/go.sum +++ b/go.sum @@ -1,47 +1,33 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v1.1.2 h1:A7JbD57ThNqh7XjmHE+PXpQ3Dqt3BrSAC0AL0Go3KS0= github.com/ProtonMail/go-crypto v1.1.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= -github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cyphar/filepath-securejoin v0.3.0 h1:tXpmbiaeBrS/K2US8nhgwdKYnfAOnVfkcLPKFgFHeA0= -github.com/cyphar/filepath-securejoin v0.3.0/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8= github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v0.0.0-20240618083138-03be62527ccb h1:2SoxRauy2IqekRMggrQk3yNI5X6omSnk6ugVbFywwXs= +github.com/elazarl/goproxy v0.0.0-20240618083138-03be62527ccb/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-git/go-git/v5 v5.12.1-0.20241115094014-70dd9f8347eb h1:TEo1aHmTS/QU1IIYczLGhqUEp8m03a7bk3ZdRHoUonk= github.com/go-git/go-git/v5 v5.12.1-0.20241115094014-70dd9f8347eb/go.mod h1:KECzDiPamjQz6lBAKQI+cIhdDfUcb64jyErZarVFKIE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -61,8 +47,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -74,8 +60,6 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -87,70 +71,29 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From 3a8018d5747c9071d46d28939d884506520b4e4c Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 12:32:12 +0000 Subject: [PATCH 05/14] build: Run make test and make verify on push Signed-off-by: Paulo Gomes --- .github/workflows/test.yml | 23 +++++++++++++++++++++++ Makefile | 6 +++--- cmd/console_test.go | 5 +++++ hack/base.mk | 2 +- internal/files/binaries.go | 2 +- 5 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..7da4a3e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: tests + +on: + push: + +permissions: + contents: read + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - run: make verify + - run: make test diff --git a/Makefile b/Makefile index dfc5676..fd2b349 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,9 @@ build: ## build qubesome to the path set on TARGET_BIN. .PHONY: test test: ## run golang tests. - go test -race ./... + go test -race -parallel 10 ./... -validate: validate-lint validate-dirty ## Run validation checks. +verify: verify-lint verify-dirty ## Run verification checks. -validate-lint: $(GOLANGCI) +verify-lint: $(GOLANGCI) $(GOLANGCI) run diff --git a/cmd/console_test.go b/cmd/console_test.go index bef9f08..ed88b55 100644 --- a/cmd/console_test.go +++ b/cmd/console_test.go @@ -2,6 +2,7 @@ package cmd import ( "embed" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -18,6 +19,10 @@ func TestCommandWiring(t *testing.T) { c := newConsole() for _, entry := range entries { + if strings.EqualFold(entry.Name(), "qubesome") { + continue + } + if !entry.IsDir() { continue } diff --git a/hack/base.mk b/hack/base.mk index df5561d..4fae492 100644 --- a/hack/base.mk +++ b/hack/base.mk @@ -16,7 +16,7 @@ GOBIN=$(TOOLS_BIN) go install $(2) ;\ } endef -validate-dirty: +verify-dirty: ifneq ($(shell git status --porcelain --untracked-files=no),) @echo worktree is dirty @git --no-pager status diff --git a/internal/files/binaries.go b/internal/files/binaries.go index e4e091c..b770f16 100644 --- a/internal/files/binaries.go +++ b/internal/files/binaries.go @@ -5,7 +5,7 @@ import ( "os/exec" ) -func init() { +func init() { //nolint p, err := exec.LookPath("podman") if err != nil { p2, err := exec.LookPath("docker") From f2622aab95b994ba3ae531c38f40cf58ab7dcf80 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 12:32:46 +0000 Subject: [PATCH 06/14] build: Bump golangci-lint to v1.62.0 Signed-off-by: Paulo Gomes --- hack/base.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/base.mk b/hack/base.mk index 4fae492..fb96e4a 100644 --- a/hack/base.mk +++ b/hack/base.mk @@ -1,4 +1,4 @@ -GOLANGCI_VERSION ?= v1.57.2 +GOLANGCI_VERSION ?= v1.62.0 TOOLS_BIN := $(shell mkdir -p build/tools && realpath build/tools) GOLANGCI = $(TOOLS_BIN)/golangci-lint-$(GOLANGCI_VERSION) From ec4cc1abb1ab47b424b292242ba5d9c08d5d362c Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Mon, 18 Nov 2024 12:34:51 +0000 Subject: [PATCH 07/14] profiles: Remove dbus code This feature was work in progress and can be removed until it is fully implemented. Signed-off-by: Paulo Gomes --- internal/profiles/profiles.go | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index 2aaf466..25681a5 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -254,13 +254,6 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { return fmt.Errorf("failed to start profile: %s", msg) } - // if !profile.Dbus { - // err = startDbus(name) - // if err != nil { - // return err - // } - // } - err = startWindowManager(name, strconv.Itoa(int(profile.Display)), profile.WindowManager) if err != nil { return err @@ -340,28 +333,6 @@ func startWindowManager(name, display, wm string) error { return nil } -func startDbus(name string) error { - args := []string{ - "exec", - "--detach", - name, - "/usr/bin/dbus-daemon", - "--session", - "--fork", - "--nopidfile", - "--address=unix:path=/run/user/1000/bus", - } - - slog.Debug(files.ContainerRunnerBinary+" exec", "container-name", name, "args", args) - cmd := execabs.Command(files.ContainerRunnerBinary, args...) //nolint - - output, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("%s: %w", output, err) - } - return nil -} - func createNewDisplay(profile *types.Profile, display string) error { command := "Xephyr" res, err := resolution.Primary() From 0b2c0a2210c7c4d801c9241b70ae79b77a44fcf4 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 11:51:20 +0000 Subject: [PATCH 08/14] build: Fix golangci-lint warnings Signed-off-by: Paulo Gomes --- .golangci.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index cf4cfd3..ad21c62 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -16,9 +16,7 @@ linters: - errchkjson - errname - errorlint - - execinquery - exhaustive - - exportloopref - forcetypeassert - ginkgolinter - gocheckcompilerdirectives From 50204351aa241b158202f35e460e573a8b4abe7c Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 12:05:44 +0000 Subject: [PATCH 09/14] wayland: Initial support for profiles Signed-off-by: Paulo Gomes --- internal/profiles/profiles.go | 41 ++++++++++++++++++++++++---------- internal/runners/docker/run.go | 4 ++++ internal/util/dbus/dbus.go | 5 +++++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index 25681a5..e58d22a 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -244,19 +244,24 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { return err } - name := fmt.Sprintf(ContainerNameFormat, profile.Name) - - // If xhost access control is enabled, it may block qubesome - // execution. A tail sign is the profile container dying early. - if !containerRunning(name) { - msg := os.ExpandEnv("run xhost +SI:localhost:${USER} and try again") - dbus.NotifyOrLog("qubesome start error", msg) - return fmt.Errorf("failed to start profile: %s", msg) - } + // In Wayland, Xephyr is replaced by xwayland-run, which can + // run the Window Manager directly, without the need of a exec + // into the container to trigger it. + if !strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { + name := fmt.Sprintf(ContainerNameFormat, profile.Name) + + // If xhost access control is enabled, it may block qubesome + // execution. A tail sign is the profile container dying early. + if !containerRunning(name) { + msg := os.ExpandEnv("run xhost +SI:localhost:${USER} and try again") + dbus.NotifyOrLog("qubesome start error", msg) + return fmt.Errorf("failed to start profile: %s", msg) + } - err = startWindowManager(name, strconv.Itoa(int(profile.Display)), profile.WindowManager) - if err != nil { - return err + err = startWindowManager(name, strconv.Itoa(int(profile.Display)), profile.WindowManager) + if err != nil { + return err + } } wg.Wait() @@ -354,6 +359,12 @@ func createNewDisplay(profile *types.Profile, display string) error { cArgs = append(cArgs, strings.Split(profile.XephyrArgs, " ")...) } + if strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { + command = "xwayland-run" + cArgs = []string{"-host-grab", "-geometry", res, "--", + strings.TrimPrefix(profile.WindowManager, "exec ")} + } + server, err := files.ServerCookiePath(profile.Name) if err != nil { return err @@ -414,9 +425,15 @@ func createNewDisplay(profile *types.Profile, display string) error { "-d", // rely on currently set DISPLAY. "-e", "DISPLAY", + "-e", "XDG_SESSION_TYPE=X11", + "--device", "/dev/dri", "--security-opt=no-new-privileges:true", "--cap-drop=ALL", } + + if strings.HasSuffix(files.ContainerRunnerBinary, "podman") { + dockerArgs = append(dockerArgs, "--userns=keep-id") + } if profile.HostAccess.Gpus != "" { dockerArgs = append(dockerArgs, "--gpus", profile.HostAccess.Gpus) } diff --git a/internal/runners/docker/run.go b/internal/runners/docker/run.go index 9bb130b..af2442b 100644 --- a/internal/runners/docker/run.go +++ b/internal/runners/docker/run.go @@ -120,6 +120,10 @@ func Run(ew types.EffectiveWorkload) error { "--group-add=keep-groups", } + if strings.HasSuffix(files.ContainerRunnerBinary, "podman") { + args = append(args, "--userns=keep-id") + } + if ew.Workload.User != nil { args = append(args, fmt.Sprintf("--user=%d", *ew.Workload.User)) } diff --git a/internal/util/dbus/dbus.go b/internal/util/dbus/dbus.go index 0f31e31..5f977f2 100644 --- a/internal/util/dbus/dbus.go +++ b/internal/util/dbus/dbus.go @@ -4,6 +4,7 @@ import ( "fmt" "log/slog" "os" + "strings" "github.com/qubesome/cli/internal/files" "golang.org/x/sys/execabs" @@ -57,6 +58,10 @@ func Notify(title, body string) error { } func NotifyOrLog(title, body string) { + if strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { + slog.Error("logging notification (sending not supported on wayland)", "title", title, "body", body) + } + err := Notify(title, body) if err != nil { slog.Error("cannot send notification", "error", err, "notification", body) From 5ba449609a7325a100a3ffff50729796a68b33c7 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 13:16:32 +0000 Subject: [PATCH 10/14] wayland: Pass XDG_RUNTIME_DIR to profile container Signed-off-by: Paulo Gomes --- internal/profiles/profiles.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index e58d22a..73416a4 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -434,6 +434,21 @@ func createNewDisplay(profile *types.Profile, display string) error { if strings.HasSuffix(files.ContainerRunnerBinary, "podman") { dockerArgs = append(dockerArgs, "--userns=keep-id") } + if strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { + fmt.Println("WARN: running qubesome in Wayland (experimental)") + xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR") + if xdgRuntimeDir == "" { + uid := os.Getuid() + if uid < 1000 { + return fmt.Errorf("qubesome does not support running under privileged users") + } + xdgRuntimeDir = "/run/user/" + strconv.Itoa(uid) + } + + // TODO: Investigate ways to avoid sharing /run/user/1000 on Wayland. + dockerArgs = append(dockerArgs, "-e XDG_RUNTIME_DIR") + dockerArgs = append(dockerArgs, "-v="+xdgRuntimeDir+":/run/user/1000") + } if profile.HostAccess.Gpus != "" { dockerArgs = append(dockerArgs, "--gpus", profile.HostAccess.Gpus) } From d6a1fbdc1496df990209b1865a761278ef8072be Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 14:39:00 +0000 Subject: [PATCH 11/14] Add QS_DEBUG=true to run on debug mode Signed-off-by: Paulo Gomes --- cmd/root.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/root.go b/cmd/root.go index 3e7efd9..83bbd37 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,6 +5,7 @@ import ( "log/slog" "os" "runtime" + "strings" "github.com/qubesome/cli/internal/command" "github.com/qubesome/cli/internal/log" @@ -17,6 +18,13 @@ var ( ConsoleApp command.App = newConsole() ) +func init() { //nolint + val := os.Getenv("QS_DEBUG") + if strings.EqualFold(val, "true") { + DefaultLogLevel = "DEBUG" + } +} + func Exec(args []string) { if runtime.GOOS != "linux" { fmt.Println("unsupported OS:", runtime.GOOS) From b8fbf3eb8ca9d487297677d9a4f17902209c91a6 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 15:34:37 +0000 Subject: [PATCH 12/14] wayland: Set additional params for xwayland-run Disable testing extensions and ensure the auth file is set. Signed-off-by: Paulo Gomes --- internal/profiles/profiles.go | 15 ++++++++-- internal/runners/docker/run.go | 50 ++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index 73416a4..99e2e4a 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -361,7 +361,16 @@ func createNewDisplay(profile *types.Profile, display string) error { if strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { command = "xwayland-run" - cArgs = []string{"-host-grab", "-geometry", res, "--", + cArgs = []string{ + "-host-grab", + "-geometry", res, + "-extension", "MIT-SHM", + "-extension", "XTEST", + "-nopn", + "-tst", + "-nolisten", "tcp", + "-auth", "/home/xorg-user/.Xserver", + "--", strings.TrimPrefix(profile.WindowManager, "exec ")} } @@ -411,8 +420,8 @@ func createNewDisplay(profile *types.Profile, display string) error { paths = append(paths, "-v=/etc/localtime:/etc/localtime:ro") paths = append(paths, "-v=/tmp/.X11-unix:/tmp/.X11-unix:rw") paths = append(paths, fmt.Sprintf("-v=%s:/tmp/qube.sock:ro", socket)) - paths = append(paths, fmt.Sprintf("-v=%s:/home/xorg-user/.Xserver:ro", server)) - paths = append(paths, fmt.Sprintf("-v=%s:/home/xorg-user/.Xauthority:ro", workload)) + paths = append(paths, fmt.Sprintf("-v=%s:/home/xorg-user/.Xserver", server)) + paths = append(paths, fmt.Sprintf("-v=%s:/home/xorg-user/.Xauthority", workload)) paths = append(paths, fmt.Sprintf("-v=%s:/usr/local/bin/qubesome:ro", binPath)) for _, p := range profile.Paths { diff --git a/internal/runners/docker/run.go b/internal/runners/docker/run.go index af2442b..f1a4fe5 100644 --- a/internal/runners/docker/run.go +++ b/internal/runners/docker/run.go @@ -6,6 +6,7 @@ import ( "log/slog" "os" "path/filepath" + "strconv" "strings" "github.com/qubesome/cli/internal/env" @@ -154,36 +155,55 @@ func Run(ew types.EffectiveWorkload) error { args = append(args, cameraParams()...) } - if wl.HostAccess.Dbus || wl.HostAccess.Bluetooth || wl.HostAccess.VarRunUser { - args = append(args, "-v=/run/user/1000:/run/user/1000:z") - } + display := ew.Profile.Display + if strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { //nolint + fmt.Println("WARN: running qubesome in Wayland (experimental)") + display = 0 + + xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR") + if xdgRuntimeDir == "" { + uid := os.Getuid() + if uid < 1000 { + return fmt.Errorf("qubesome does not support running under privileged users") + } + xdgRuntimeDir = "/run/user/" + strconv.Itoa(uid) + } - userDir, err := files.IsolatedRunUserPath(ew.Profile.Name) - if err != nil { - return fmt.Errorf("failed to get isolated /user path: %w", err) - } - paths = append(paths, fmt.Sprintf("-v=%s:/dev/shm", filepath.Join(userDir, "shm"))) - if wl.HostAccess.Dbus || wl.HostAccess.Bluetooth || wl.HostAccess.VarRunUser { - args = append(args, hostDbusParams()...) + // TODO: Investigate ways to avoid sharing /run/user/1000 on Wayland. + args = append(args, "-e XDG_RUNTIME_DIR") + args = append(args, "-v="+xdgRuntimeDir+":/run/user/1000") } else { - paths = append(paths, fmt.Sprintf("-v=%s:/run/user/1000:z", userDir)) + if wl.HostAccess.Dbus || wl.HostAccess.Bluetooth || wl.HostAccess.VarRunUser { + args = append(args, "-v=/run/user/1000:/run/user/1000:z") + } - machineIDPath := filepath.Join(files.ProfileDir(ew.Profile.Name), "machine-id") - paths = append(paths, fmt.Sprintf("-v=%s:/etc/machine-id:ro", machineIDPath)) + userDir, err := files.IsolatedRunUserPath(ew.Profile.Name) + if err != nil { + return fmt.Errorf("failed to get isolated /user path: %w", err) + } + paths = append(paths, fmt.Sprintf("-v=%s:/dev/shm", filepath.Join(userDir, "shm"))) + if wl.HostAccess.Dbus || wl.HostAccess.Bluetooth || wl.HostAccess.VarRunUser { + args = append(args, hostDbusParams()...) + } else { + paths = append(paths, fmt.Sprintf("-v=%s:/run/user/1000:z", userDir)) + + machineIDPath := filepath.Join(files.ProfileDir(ew.Profile.Name), "machine-id") + paths = append(paths, fmt.Sprintf("-v=%s:/etc/machine-id:ro", machineIDPath)) + } } args = append(args, paths...) args = append(args, "--device=/dev/dri") // Display is used for all qubesome applications. - args = append(args, fmt.Sprintf("-e=DISPLAY=:%d", ew.Profile.Display)) + args = append(args, fmt.Sprintf("-e=DISPLAY=:%d", display)) pp, err := files.ClientCookiePath(ew.Profile.Name) if err != nil { return err } args = append(args, fmt.Sprintf("-v=%s:/tmp/.Xauthority:ro", pp)) args = append(args, "-e=XAUTHORITY=/tmp/.Xauthority") - args = append(args, fmt.Sprintf("-v=/tmp/.X11-unix/X%[1]d:/tmp/.X11-unix/X%[1]d", ew.Profile.Display)) + args = append(args, fmt.Sprintf("-v=/tmp/.X11-unix/X%[1]d:/tmp/.X11-unix/X%[1]d", display)) args = append(args, fmt.Sprintf("-e=QUBESOME_PROFILE=%s", ew.Profile.Name)) if ew.Profile.Timezone != "" { From 8a35364c9fbdb76f4950ae0823bd909423098f14 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 15:56:35 +0000 Subject: [PATCH 13/14] profiles: Clean up CLI messages Signed-off-by: Paulo Gomes --- internal/profiles/profiles.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index 99e2e4a..676949e 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -270,7 +270,6 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { func containerRunning(name string) bool { args := fmt.Sprintf("ps -q -f name=%s", name) - fmt.Println(args) cmd := execabs.Command(files.ContainerRunnerBinary, //nolint:gosec strings.Split(args, " ")...) @@ -510,6 +509,10 @@ func createNewDisplay(profile *types.Profile, display string) error { dockerArgs = append(dockerArgs, command) dockerArgs = append(dockerArgs, cArgs...) + fmt.Println( + "INFO: For best experience use input grabber shortcuts:", + grabberShortcut()) + slog.Debug("exec: docker", "args", dockerArgs) cmd := execabs.Command(files.ContainerRunnerBinary, dockerArgs...) //nolint @@ -520,6 +523,14 @@ func createNewDisplay(profile *types.Profile, display string) error { return nil } +func grabberShortcut() string { + if strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { + return " + " + } + + return " + " +} + func setupRunUserDir(dir string) error { err := os.MkdirAll(dir, files.DirMode) if err != nil { From 2cff782627d9fc789835d2e1fdecfaa2368b8d55 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 19 Nov 2024 16:49:20 +0000 Subject: [PATCH 14/14] profiles: Preemptive pull workload images Signed-off-by: Paulo Gomes --- internal/images/images.go | 17 ++++++++++++++--- internal/profiles/profiles.go | 17 ++++++++++++++++- internal/types/config.go | 2 ++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/internal/images/images.go b/internal/images/images.go index a7a466c..e42bf15 100644 --- a/internal/images/images.go +++ b/internal/images/images.go @@ -1,9 +1,7 @@ package images import ( - "errors" "fmt" - "io/fs" "log/slog" "os" "sync" @@ -53,7 +51,7 @@ func pullExpired() (bool, error) { fn := files.ImagesLastCheckedPath() fi, err := os.Stat(fn) if err != nil { - if !errors.Is(err, fs.ErrNotExist) { + if !os.IsNotExist(err) { return false, fmt.Errorf("cannot stat %q: %w", fn, err) } if err := os.WriteFile(fn, []byte{}, files.FileMode); err != nil { @@ -76,6 +74,19 @@ func pullExpired() (bool, error) { return false, nil } +func PreemptWorkloadImages(cfg *types.Config) { + slog.Debug("Check need for the preemptive pull of workload images") + fn := files.ImagesLastCheckedPath() + + _, err := os.Stat(fn) + if err != nil && os.IsNotExist(err) { + fmt.Println("INFO: Preemptively pulling workload images. This only happens on first execution and aims to avoid delays opening apps.") + + _ = PullAll(cfg) + _ = os.WriteFile(fn, []byte{}, files.FileMode) + } +} + func PullAll(cfg *types.Config) error { wf, err := cfg.WorkloadFiles() if err != nil { diff --git a/internal/profiles/profiles.go b/internal/profiles/profiles.go index 676949e..5930960 100644 --- a/internal/profiles/profiles.go +++ b/internal/profiles/profiles.go @@ -74,8 +74,15 @@ func validGitDir(path string) bool { func StartFromGit(name, gitURL, path, local string) error { ln := files.ProfileConfig(name) + if _, err := os.Lstat(ln); err == nil { - return fmt.Errorf("profile %q is already started", name) + // Wayland is not cleaning up profile state after closure. + if !strings.EqualFold(os.Getenv("XDG_SESSION_TYPE"), "wayland") { + return fmt.Errorf("profile %q is already started", name) + } + if err = os.Remove(ln); err != nil { + return fmt.Errorf("failed to remove leftover profile symlink: %w", err) + } } dir, err := files.GitDirPath(gitURL) @@ -177,11 +184,18 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { return err } + fi, err := os.Lstat(files.ContainerRunnerBinary) + if err != nil || !fi.Mode().IsRegular() { + return fmt.Errorf("could not find docker or podman") + } + err = images.PullImageIfNotPresent(profile.Image) if err != nil { return fmt.Errorf("cannot pull profile image: %w", err) } + go images.PreemptWorkloadImages(cfg) + if profile.Gpus != "" { if !gpu.Supported() { profile.Gpus = "" @@ -225,6 +239,7 @@ func Start(profile *types.Profile, cfg *types.Config) (err error) { err = err1 } } + wg.Done() }() diff --git a/internal/types/config.go b/internal/types/config.go index f005c40..6e1f7fa 100644 --- a/internal/types/config.go +++ b/internal/types/config.go @@ -187,6 +187,8 @@ func LoadConfig(path string) (*Config, error) { return nil, fmt.Errorf("cannot unmarshal qubesome config %q: %w", path, err) } + cfg.RootDir = filepath.Dir(path) + // To avoid names being defined twice on the profiles, the name // is only defined when referring to a profile which results // on the .name field of Profiles not being populated.