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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ All notable changes to this project are documented here. The format follows

## [Unreleased]

### Added

- `update` and `cleanup` subcommands for one-command lifecycle management, mirroring
apple/container's `update-container.sh` / `uninstall-container.sh`. `update` downloads the
latest release (or `--version vX.Y.Z`), verifies its checksum, replaces the binary in place,
and re-runs `setup`; `--all` also updates OpenShell (brew) and apple/container, `--no-setup`
replaces the binary only. `cleanup` layers like the apple/container uninstaller: the bare
command removes only the driver's service and gateway wiring, `-d`/`--delete-data` also removes
the driver's state, vmnet network and pulled images (`-k`/`--keep-data` is the default), and
`--all` also removes OpenShell and apple/container. `uninstall` is now an alias for `cleanup`.

### Fixed

- The `install.sh` one-line installer no longer aborts when the OpenShell installer it invokes
Expand Down
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,33 @@ openshell sandbox delete demo

Both services start at login and restart on failure — nothing to launch by hand, ever.
`setup` is **idempotent**: re-run it any time (after an upgrade, after changing flags, or just
to repair the installation). `openshell-driver-applecontainer uninstall` removes everything
setup installed.
to repair the installation). To upgrade or remove the stack later, see
[Update and remove](#update-and-remove).

The installer is non-interactive with `-y`, and takes `--no-setup`, `--version vX.Y.Z`, and
`--prefix <dir>` (or the `OSHL_AC_YES`, `OSHL_AC_VERSION`, `OSHL_AC_PREFIX` env vars).

### Update and remove

Two commands manage the stack's lifecycle, mirroring apple/container's own
`update-container.sh` / `uninstall-container.sh`:

```sh
openshell-driver-applecontainer update # update the driver to the latest release, then re-setup
openshell-driver-applecontainer update --all # also update OpenShell (brew) and apple/container
openshell-driver-applecontainer update --version vX.Y.Z # pin a specific driver release

openshell-driver-applecontainer cleanup # remove the driver service + gateway wiring (data kept)
openshell-driver-applecontainer cleanup -d # also remove driver state, vmnet network and pulled images
openshell-driver-applecontainer cleanup --all -d # full teardown: also remove OpenShell and apple/container
```

`update` downloads the release, verifies its checksum, replaces the binary in place, and re-runs
`setup` so the service restarts on it (`--no-setup` skips that). `cleanup` layers like the
apple/container uninstaller: the bare command touches only the driver; `-d`/`--delete-data` also
removes its data (`-k`/`--keep-data` is the default); `--all` also removes the prerequisites
(apple/container's uninstaller needs `sudo`). `uninstall` remains as an alias for `cleanup`.

### Manual install

Prerequisites: an Apple-silicon Mac (macOS 26+), [apple/container](https://github.com/apple/container)
Expand Down
56 changes: 56 additions & 0 deletions cmd/openshell-driver-applecontainer/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"flag"
"log/slog"

"github.com/vyncint/openshell-driver-applecontainer/internal/backend"
"github.com/vyncint/openshell-driver-applecontainer/internal/config"
"github.com/vyncint/openshell-driver-applecontainer/internal/hostsetup"
)

// runCleanup implements `openshell-driver-applecontainer cleanup`: reverse
// setup with apple/container-style layering. Bare command removes only the
// driver's service and gateway wiring; -d/--delete-data also removes the
// driver's data; --all also removes the OpenShell and apple/container
// prerequisites.
func runCleanup(args []string) int {
fs := flag.NewFlagSet("cleanup", flag.ContinueOnError)
keep := fs.Bool("keep-data", false, "keep the driver's data — state, network, images (the default)")
fs.BoolVar(keep, "k", false, "shorthand for --keep-data")
del := fs.Bool("delete-data", false, "also remove the driver's data: state, socket, vmnet network, pulled images")
fs.BoolVar(del, "d", false, "shorthand for --delete-data")
all := fs.Bool("all", false, "also remove the prerequisites: OpenShell (brew) and apple/container (its uninstaller)")
if err := fs.Parse(args); err != nil {
return 2
}
if *keep && *del {
slog.Error("cleanup: pass at most one of -k/--keep-data and -d/--delete-data")
return 2
}

defaults, err := config.Parse(nil)
if err != nil {
slog.Error("resolve defaults", "err", err)
return 1
}
log := newLogger("info")
s, err := hostsetup.New(backend.NewCLI(log), log)
if err != nil {
log.Error("cleanup failed", "err", err)
return 1
}
if err := s.Cleanup(hostsetup.CleanupOptions{
DeleteData: *del,
All: *all,
Network: defaults.Network,
Socket: defaults.Socket,
StateDir: defaults.StateDir,
DefaultImage: defaults.DefaultImage,
SupervisorImage: defaults.SupervisorImage,
}); err != nil {
log.Error("cleanup failed", "err", err)
return 1
}
return 0
}
19 changes: 17 additions & 2 deletions cmd/openshell-driver-applecontainer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func main() {
return
case "setup":
os.Exit(runSetup(args[1:]))
case "update":
os.Exit(runUpdate(args[1:]))
case "cleanup":
os.Exit(runCleanup(args[1:]))
case "uninstall":
os.Exit(runUninstall(args[1:]))
case "help", "--help", "-h":
Expand All @@ -64,8 +68,19 @@ Usage:
vmnet network and gateway certificate, and pre-pulls images.
Idempotent — re-run any time to repair the installation.

openshell-driver-applecontainer uninstall
Removes the services and configuration that setup installed.
openshell-driver-applecontainer update [--version vX.Y.Z] [--all] [--no-setup]
Updates the driver to the latest release (verifying its checksum)
and re-runs setup so the service restarts on the new binary. --all
also updates the prerequisites (OpenShell via brew, apple/container
via its own updater). --no-setup replaces the binary only.

openshell-driver-applecontainer cleanup [-d | -k] [--all]
Reverses setup. By default removes only the driver's service and
gateway wiring (data kept). -d/--delete-data also removes the
driver's state, vmnet network and pulled images; -k/--keep-data is
the default. --all also removes the prerequisites (OpenShell via
brew, apple/container via its own uninstaller, which needs sudo).
The "uninstall" subcommand is a backward-compatible alias.

openshell-driver-applecontainer [flags]
Runs the driver in the foreground (development). See -h of the
Expand Down
18 changes: 5 additions & 13 deletions cmd/openshell-driver-applecontainer/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,9 @@ func runSetup(args []string) int {
return 0
}

// runUninstall implements `openshell-driver-applecontainer uninstall`.
func runUninstall(_ []string) int {
log := newLogger("info")
s, err := hostsetup.New(backend.NewCLI(log), log)
if err != nil {
log.Error("uninstall failed", "err", err)
return 1
}
if err := s.Uninstall(); err != nil {
log.Error("uninstall failed", "err", err)
return 1
}
return 0
// runUninstall implements `openshell-driver-applecontainer uninstall`, a
// backward-compatible alias for `cleanup` (driver only, data kept). Any
// cleanup flags (-d/--delete-data, --all) still work through it.
func runUninstall(args []string) int {
return runCleanup(args)
}
Loading