@agentshouse/kit 0.1.0-alpha.24 → 0.1.0-alpha.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,13 +6,33 @@ this repository contains only the package source and its operator documentation.
6
6
 
7
7
  ## Connect a Linux computer
8
8
 
9
- On Linux `amd64` or `arm64` with a working Docker Engine, run the published,
10
- versioned bootstrap once:
9
+ On Linux `amd64` or `arm64`, run the published, versioned bootstrap once:
11
10
 
12
11
  ```sh
13
- bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.24/connect-linux.sh)
12
+ bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.25/connect-linux.sh)
14
13
  ```
15
14
 
15
+ The bootstrap first establishes Docker Engine from what it observes on the
16
+ computer. A Docker Engine that already answers is used as it is, on any
17
+ distribution. On Ubuntu 22.04, 24.04 or 26.04 LTS it follows Docker's
18
+ [apt repository recipe](https://docs.docker.com/engine/install/ubuntu/) for
19
+ whatever is missing: it installs `docker-ce`, `docker-ce-cli`,
20
+ `containerd.io`, `docker-buildx-plugin` and `docker-compose-plugin` from
21
+ `download.docker.com`, starts the `docker` service when it is stopped and adds
22
+ the account to the `docker` group. Every such step runs through `sudo`, which
23
+ asks for the password as it ordinarily does. A new group membership applies
24
+ from the account's next sign-in, so the invocation that grants it reaches
25
+ Docker Engine through `sudo` for the rest of its own run; a later invocation
26
+ from a session older than the membership is refused until the account signs
27
+ out and back in. The bootstrap refuses an Ubuntu computer whose installed
28
+ `docker.io`, `docker-compose`, `docker-compose-v2`, `docker-doc`,
29
+ `docker-buildx`, `podman-docker`, `containerd` or `runc` package conflicts with
30
+ that recipe rather than removing it. Any other distribution needs a working
31
+ Docker Engine supplied by its owner, and without one the bootstrap stops with
32
+ that missing prerequisite. A step that fails names its cause and changes
33
+ nothing further; running the same bootstrap again continues from the state it
34
+ left, including after a restart.
35
+
16
36
  The release asset pins one immutable multi-architecture image digest. It creates
17
37
  owner-protected `~/.house-kit` and `~/AgentsHouse`, mounts those as the complete
18
38
  Kit home and `/agents/house`, enrolls through House Login in the host browser,
@@ -11,6 +11,10 @@ HOUSE_SELECTED=0
11
11
  FORWARDING=0
12
12
  FORWARDED=kit
13
13
  FORWARD=()
14
+ UBUNTU_RELEASES=(jammy noble resolute)
15
+ DOCKER_PACKAGES=(docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin)
16
+ CONFLICTING_PACKAGES=(docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc)
17
+ DOCKER_GROUP=0
14
18
 
15
19
  refuse() {
16
20
  printf 'kit_bootstrap_refused: %s\n' "$1" >&2
@@ -42,6 +46,94 @@ start_resident() {
42
46
  docker run -d --name "$NAME" --restart unless-stopped --user "$(id -u):$(id -g)" --mount "$KIT_HOME_MOUNT" --mount "$WORKSPACE_MOUNT" --label "agentshouse.house=$HOUSE" --env HOME=/kit-home --env HOUSE_KIT_HOME=/kit-home --env HOUSE_KIT_CONTAINER=1 "$IMAGE" resident >/dev/null
43
47
  }
44
48
 
49
+ docker() {
50
+ if ((DOCKER_GROUP)); then
51
+ sudo -u "$(id -un)" docker "$@"
52
+ else
53
+ command docker "$@"
54
+ fi
55
+ }
56
+
57
+ elevated() {
58
+ if ((EUID == 0)); then
59
+ "$@"
60
+ else
61
+ sudo "$@"
62
+ fi
63
+ }
64
+
65
+ docker_member() {
66
+ [[ " $(id -nG "$@") " == *' docker '* ]]
67
+ }
68
+
69
+ docker_answers() {
70
+ DOCKER_PLATFORM=$(docker info --format '{{.OSType}}/{{.Architecture}}' 2>/dev/null)
71
+ }
72
+
73
+ docker_cause() {
74
+ docker info 2>&1 >/dev/null | tail -n 1
75
+ }
76
+
77
+ unanswered() {
78
+ type -P docker >/dev/null || return 0
79
+ printf '; Docker Engine does not answer: %s' "$(docker_cause)"
80
+ }
81
+
82
+ installed_packages() {
83
+ { dpkg-query -W -f='${db:Status-Status} ${Package}\n' "$@" 2>/dev/null || true; } | awk '$1 == "installed" { print $2 }'
84
+ }
85
+
86
+ install_docker_engine() {
87
+ printf 'Installing Docker Engine from Docker'\''s apt repository for %s; sudo may ask for your password.\n' "$1"
88
+ elevated apt-get update -qq >/dev/null || refuse 'apt could not refresh its package lists'
89
+ elevated apt-get install -y -qq ca-certificates curl >/dev/null || refuse 'apt could not install ca-certificates and curl'
90
+ elevated install -m 0755 -d /etc/apt/keyrings || refuse '/etc/apt/keyrings could not be created'
91
+ elevated curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc || refuse 'the Docker apt repository key could not be downloaded'
92
+ elevated chmod a+r /etc/apt/keyrings/docker.asc || refuse 'the Docker apt repository key could not be made readable'
93
+ printf 'Types: deb\nURIs: https://download.docker.com/linux/ubuntu\nSuites: %s\nComponents: stable\nArchitectures: %s\nSigned-By: /etc/apt/keyrings/docker.asc\n' "$2" "$(dpkg --print-architecture)" \
94
+ | elevated tee /etc/apt/sources.list.d/docker.sources >/dev/null || refuse 'the Docker apt repository could not be configured'
95
+ elevated apt-get update -qq >/dev/null || refuse 'apt could not read the Docker apt repository'
96
+ elevated apt-get install -y -qq "${DOCKER_PACKAGES[@]}" >/dev/null || refuse 'apt could not install Docker Engine'
97
+ }
98
+
99
+ establish_docker_engine() {
100
+ docker_answers && return
101
+ if ((EUID != 0)) && ! docker_member && docker_member "$(id -un)"; then
102
+ refuse "$(id -un) joined the docker group after this session began; sign out and back in, then rerun this bootstrap"
103
+ fi
104
+ local distribution='' release='' described='this Linux distribution' conflicting present
105
+ if [[ -r /etc/os-release ]]; then
106
+ distribution=$(. /etc/os-release && printf '%s' "${ID:-}")
107
+ release=$(. /etc/os-release && printf '%s' "${UBUNTU_CODENAME:-${VERSION_CODENAME:-}}")
108
+ described=$(. /etc/os-release && printf '%s' "${PRETTY_NAME:-$described}")
109
+ fi
110
+ if ((FORWARDING)); then
111
+ type -P docker >/dev/null || refuse 'House Kit is not installed; run this bootstrap without arguments first'
112
+ refuse "Docker Engine does not answer: $(docker_cause)"
113
+ fi
114
+ if [[ "$distribution" != ubuntu ]]; then
115
+ type -P docker >/dev/null || refuse "Docker Engine is not installed on $described; install a working Docker Engine, then rerun this bootstrap"
116
+ refuse "Docker Engine does not answer on $described: $(docker_cause)"
117
+ fi
118
+ [[ " ${UBUNTU_RELEASES[*]} " == *" $release "* ]] || refuse "this bootstrap installs Docker Engine only on Ubuntu 22.04, 24.04 and 26.04 LTS, not $described; install a working Docker Engine, then rerun this bootstrap$(unanswered)"
119
+ conflicting=$(installed_packages "${CONFLICTING_PACKAGES[@]}" | paste -sd ' ' -)
120
+ [[ -z "$conflicting" ]] || refuse "the installed packages $conflicting conflict with Docker Engine; remove them or make their Docker Engine work, then rerun this bootstrap$(unanswered)"
121
+ present=$(installed_packages "${DOCKER_PACKAGES[@]}" | wc -l)
122
+ ((present == ${#DOCKER_PACKAGES[@]})) || install_docker_engine "$described" "$release"
123
+ if ! systemctl is-active --quiet docker.service; then
124
+ printf 'Starting Docker Engine; sudo may ask for your password.\n'
125
+ elevated systemctl start docker.service || refuse 'Docker Engine could not be started'
126
+ fi
127
+ if ((EUID != 0)); then
128
+ if ! docker_member "$(id -un)"; then
129
+ printf 'Adding %s to the docker group; it applies from your next sign-in, so this run reaches Docker Engine through sudo.\n' "$(id -un)"
130
+ elevated usermod -aG docker "$(id -un)" || refuse "$(id -un) could not be added to the docker group"
131
+ fi
132
+ docker_member || DOCKER_GROUP=1
133
+ fi
134
+ docker_answers || refuse "Docker Engine does not answer: $(docker_cause)"
135
+ }
136
+
45
137
  if [[ "${1:-}" == kit || "${1:-}" == house ]]; then
46
138
  FORWARDING=1
47
139
  FORWARDED="$1"
@@ -80,8 +172,7 @@ case "$(uname -m)" in
80
172
  *) refuse "unsupported Linux architecture $(uname -m)" ;;
81
173
  esac
82
174
  [[ "$WORKSPACE" == /* ]] || refuse 'workspace root must be an absolute path'
83
- command -v docker >/dev/null || refuse 'Docker Engine client is unavailable'
84
- DOCKER_PLATFORM=$(docker info --format '{{.OSType}}/{{.Architecture}}' 2>/dev/null) || refuse 'Docker Engine is unavailable'
175
+ establish_docker_engine
85
176
  case "$DOCKER_PLATFORM" in
86
177
  linux/x86_64|linux/amd64) DOCKER_ARCH=amd64 ;;
87
178
  linux/aarch64|linux/arm64) DOCKER_ARCH=arm64 ;;
package/bootstrap.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.1.0-alpha.24",
3
+ "version": "0.1.0-alpha.25",
4
4
  "hosts": {
5
5
  "linux": {
6
- "command": "bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.24/connect-linux.sh)",
6
+ "command": "bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.25/connect-linux.sh)",
7
7
  "asset": {
8
8
  "name": "connect-linux.sh",
9
- "url": "https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.24/connect-linux.sh"
9
+ "url": "https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.25/connect-linux.sh"
10
10
  },
11
11
  "workspace": {
12
12
  "argument": "--workspace",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/kit",
3
- "version": "0.1.0-alpha.24",
3
+ "version": "0.1.0-alpha.25",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",