Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
22 changes: 15 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ on:
tags:
- "v*"

permissions:
contents: write # create GH releases
id-token: write # ephemeral keys (a.k.a. "keyless") signing
permissions: {}

jobs:
goreleaser:
runs-on: ubuntu-latest

permissions:
contents: write # create GH releases
id-token: write # ephemeral keys (a.k.a. "keyless") signing
attestations: write # write GH attestations

steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -24,14 +27,19 @@ jobs:
with:
go-version: stable

- uses: anchore/sbom-action/download-syft@v0.15.0
- uses: sigstore/cosign-installer@v3.4.0
- uses: anchore/sbom-action/download-syft@v0.17.7
- uses: sigstore/cosign-installer@v3.7.0

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: latest
version: '~> v2'
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Attest release artefacts
uses: actions/attest-build-provenance@v1
with:
subject-path: "dist/qubesome*"
6 changes: 4 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ name: tests
on:
push:

permissions:
contents: read
permissions: {}

jobs:
tests:
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version: 2
project_name: qubesome
builds:
- id: qubesome
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ go install github.com/qubesome/cli/cmd/qubesome@latest

##### For Tumbleweed users
```
zypper install qubesome
zypper install -y qubesome
```

#### Start Profile
Expand All @@ -45,7 +45,7 @@ To transfer clipboards between profiles use `qubesome clipboard`.

Check whether dependency requirements are met:
```
qubesome deps show
qubesome deps
```

Use a local copy, and if not found fallback to a fresh clone:
Expand Down Expand Up @@ -129,8 +129,8 @@ Ability to control network/internet access for each workload, and run the window
manager without internet access. Auditing access violations, for visibility of when
workloads are trying to access things they should not.

#### Is Rootless docker support?
Not at this point, potentially this could be introduced in the future.
#### Is rootless supported?
Yes, but only with podman.

### Why do I need to run xhost +SI:localuser:${USER}?
Some Linux distros (e.g. Tumbleweed) have X11 access controls enabled
Expand Down
23 changes: 23 additions & 0 deletions cmd/cli/autocomplete/zsh_autocomplete
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#compdef qubesome
compdef _qubesome qubesome

_qubesome() {
local -a opts
local cur
cur=${words[-1]}
if [[ "$cur" == "-"* ]]; then
opts=("${(@f)$(${words[@]:0:#words[@]-1} ${cur} --generate-shell-completion)}")
else
opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}")
fi

if [[ "${opts[1]}" != "" ]]; then
_describe 'values' opts
else
_files
fi
}

if [ "$funcstack[1]" = "_qubesome" ]; then
_qubesome
fi
25 changes: 25 additions & 0 deletions cmd/cli/completion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cli

import (
"context"
_ "embed"
"fmt"

"github.com/urfave/cli/v3"
)

//go:embed autocomplete/zsh_autocomplete
var autocompleteZSH string

func completionCommand() *cli.Command {
cmd := &cli.Command{
Name: "autocomplete",
Usage: "Generate autocomplete",
UsageText: "source <(qubesome autocomplete)",
Action: func(ctx context.Context, cmd *cli.Command) error {
fmt.Println(autocompleteZSH)
return nil
},
}
return cmd
}
9 changes: 8 additions & 1 deletion cmd/cli/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ func imagesCommand() *cli.Command {
Name: "profile",
Destination: &targetProfile,
},
&cli.StringFlag{
Name: "runner",
Destination: &runner,
},
},
Action: func(ctx context.Context, cmd *cli.Command) error {
cfg := profileConfigOrDefault(targetProfile)

return images.Run(images.WithConfig(cfg))
return images.Run(
images.WithConfig(cfg),
images.WithRunner(runner),
)
},
},
},
Expand Down
2 changes: 2 additions & 0 deletions cmd/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var (
workload string
path string
local string
runner string
debug bool
)

Expand All @@ -31,6 +32,7 @@ func RootCommand() *cli.Command {
xdgCommand(),
depsCommand(),
versionCommand(),
completionCommand(),
},
}

Expand Down
5 changes: 5 additions & 0 deletions cmd/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func runCommand() *cli.Command {
Name: "profile",
Destination: &targetProfile,
},
&cli.StringFlag{
Name: "runner",
Destination: &runner,
},
},
Usage: "execute workloads",
Action: func(ctx context.Context, cmd *cli.Command) error {
Expand All @@ -33,6 +37,7 @@ func runCommand() *cli.Command {
qubesome.WithWorkload(workload),
qubesome.WithProfile(targetProfile),
qubesome.WithConfig(cfg),
qubesome.WithRunner(runner),
qubesome.WithExtraArgs(cmd.Args().Slice()),
)
},
Expand Down
5 changes: 5 additions & 0 deletions cmd/cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ func startCommand() *cli.Command {
Usage: "local is the local path for a git repository. This is to be used in combination with --git.",
Destination: &local,
},
&cli.StringFlag{
Name: "runner",
Destination: &runner,
},
},
Arguments: []cli.Argument{
&cli.StringArg{
Expand All @@ -46,6 +50,7 @@ func startCommand() *cli.Command {
profiles.WithGitURL(gitURL),
profiles.WithPath(path),
profiles.WithLocal(local),
profiles.WithRunner(runner),
)
},
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/cli/xdg.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ func xdgCommand() *cli.Command {
Name: "profile",
Destination: &targetProfile,
},
&cli.StringFlag{
Name: "runner",
Destination: &runner,
},
},
Action: func(ctx context.Context, cmd *cli.Command) error {
cfg := profileConfigOrDefault(targetProfile)

return qubesome.XdgRun(
qubesome.WithConfig(cfg),
qubesome.WithExtraArgs(cmd.Args().Slice()),
qubesome.WithRunner(runner),
)
},
}
Expand Down
58 changes: 34 additions & 24 deletions internal/deps/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,42 @@ package deps

import (
"fmt"
"os"
"os/exec"

"text/tabwriter"

"github.com/qubesome/cli/internal/command"
"github.com/qubesome/cli/internal/files"
)

var (
red = "\033[31m"
green = "\033[32m"
amber = "\033[33m"
reset = "\033[0m"
)

var deps map[string][]string = map[string][]string{
"clipboard": {
"clip": {
files.XclipBinary,
files.ShBinary,
},
"run": {
files.ContainerRunnerBinary,
files.PodmanBinary,
files.DockerBinary,
},
"xdg-open": {
files.ContainerRunnerBinary,
files.PodmanBinary,
files.DockerBinary,
},
"images": {
files.ContainerRunnerBinary,
files.PodmanBinary,
files.DockerBinary,
},
"profiles": {
files.ContainerRunnerBinary,
"start": {
files.PodmanBinary,
files.DockerBinary,
files.ShBinary,
files.XrandrBinary,
},
Expand All @@ -40,46 +54,42 @@ var optionalDeps map[string][]string = map[string][]string{
"images": {
files.FireCrackerBinary,
},
"profiles": {
"start": {
files.FireCrackerBinary,
files.DbusBinary,
},
}

func Run(_ ...command.Option[interface{}]) error {
for name, d := range deps {
fmt.Printf("%s: ", name)

if len(d) == 0 {
fmt.Println("OK")
continue
} else {
fmt.Println()
}
writer := tabwriter.NewWriter(os.Stdout, 0, 0, 5, ' ', 0)
fmt.Fprintln(writer, "Command\tDependency\tStatus")
fmt.Fprintln(writer, "-------\t----------\t------")

for name, d := range deps {
for _, dn := range d {
_, err := exec.LookPath(dn)
status := "OK"
status := green + "OK" + reset
if err != nil {
status = "NOT FOUND"
status = red + "NOT FOUND" + reset
}

fmt.Printf("- %s: %s\n", dn, status)
fmt.Fprintf(writer, "%s\t%s\t%s\n", name, dn, status)
}

if opt, ok := optionalDeps[name]; ok {
for _, dn := range opt {
_, err := exec.LookPath(dn)
status := "OK"
status := green + "OK" + reset
if err != nil {
status = "NOT FOUND (Optional)"
status = amber + "NOT FOUND (Optional)" + reset
}

fmt.Printf("- %s: %s\n", dn, status)
fmt.Fprintf(writer, "%s\t%s\t%s\n", name, dn, status)
}
}

fmt.Println()
}

writer.Flush()

return nil
}
Loading