empeira 0.1.0.pre.alpha.1 → 0.1.0.pre.alpha.3
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.
- checksums.yaml +4 -4
- data/README.md +20 -16
- data/docs/addons.md +12 -0
- data/docs/development.md +104 -17
- data/docs/installation.md +59 -28
- data/lib/empeira/build.json +3 -3
- data/lib/empeira/compatibility/data.rb +61 -0
- data/lib/empeira/network/peer/backend.rb +2 -2
- data/lib/empeira/network/peer/linux_podman.rb +2 -2
- data/lib/empeira/network/peer/podman_machine.rb +5 -5
- data/lib/empeira/node/definition.rb +2 -2
- data/lib/empeira/updates/images.rb +2 -2
- data/lib/empeira.rb +1 -0
- data/resources/modules/Containerfile +1 -1
- data/resources/modules/Gemfile +6 -0
- data/resources/modules/Gemfile.lock +7 -7
- data/resources/nodes/management/guest_agent.py +5 -2
- data/resources/proxy/Containerfile +3 -6
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c856b6d473f798e1882b261f6dec67a20ebaa89142a073ba9b977265cd24cd6f
|
|
4
|
+
data.tar.gz: ac23a47ef8ecf4abfdd8d48557cee762f5954e69c40c335b12e7d6428e376709
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30b50d1c33a73512fdd2067064e0f17b63dda84204045b90994137ec79ee8374c466501b232119ea2fff3b81f9dda39c62edd8fed47b5ee50a528f75f063dbf6
|
|
7
|
+
data.tar.gz: 8daa8af9f4f9bb5ffcc1751cf3c8714e6853142dd59878ba6791150b79511549b626cc3edd9eafc95e36adfed3b00f793e8f97d78a607ac6d29dd70865e91dc4
|
data/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://github.com/c8m6/empeira/actions/workflows/ci.yml)
|
|
6
6
|
[](https://github.com/c8m6/empeira/actions/workflows/openvox.yml)
|
|
7
7
|
[](https://github.com/c8m6/empeira/releases)
|
|
8
|
-
[](docs/installation.md)
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
|
|
11
11
|
**ἐμπειρία (empeiría)** — experience gained through practice. The name reflects
|
|
@@ -46,35 +46,37 @@ signed repositories or verified package artifacts are selected separately.
|
|
|
46
46
|
- An internal Chromium desktop and small additional infrastructure services.
|
|
47
47
|
- Explicit Puppetfile module and image updates.
|
|
48
48
|
|
|
49
|
-
Hosts: Linux, macOS and Windows through WSL2/Linux. Ruby 3.
|
|
50
|
-
|
|
49
|
+
Hosts: Linux, macOS and Windows through WSL2/Linux. Ruby 3.1 is the minimum; Ruby 3.1, 3.2, 3.3, 3.4 and 4.0 are supported;
|
|
50
|
+
CI runs deterministic tests and official addon/Core acceptance on all five versions
|
|
51
|
+
on Linux and macOS, plus the existing Linux Docker/OpenVox smoke on every Ruby.
|
|
51
52
|
Podman with Netavark is the default; Docker requires a Linux engine 28+ with
|
|
52
53
|
isolated bridge support. VMs require usable KVM or HVF. Platform setup and
|
|
53
54
|
validation limits are in [installation](docs/installation.md).
|
|
54
55
|
|
|
55
56
|
## Installation
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
The [Empeira gem on RubyGems.org](https://rubygems.org/gems/empeira) is the
|
|
59
|
+
recommended installation. With Ruby 3.1, 3.2, 3.3, 3.4 or 4.0 already installed:
|
|
58
60
|
|
|
59
61
|
```bash
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
bundle install
|
|
63
|
-
export EMPEIRA_SOURCE="$PWD"
|
|
64
|
-
empeira() { BUNDLE_GEMFILE="$EMPEIRA_SOURCE/Gemfile" bundle exec ruby "$EMPEIRA_SOURCE/bin/empeira" "$@"; }
|
|
62
|
+
gem install --user-install empeira --pre
|
|
63
|
+
export PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
|
|
65
64
|
empeira --version
|
|
66
65
|
```
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
[
|
|
70
|
-
|
|
67
|
+
`--pre` enables prerelease installation, including the first alpha
|
|
68
|
+
[`v0.1.0-alpha.1`](https://github.com/c8m6/empeira/releases/tag/v0.1.0-alpha.1).
|
|
69
|
+
No source checkout or Bundler is needed for a gem installation. Install Git,
|
|
70
|
+
a supported container runtime and any optional VM tools separately; see
|
|
71
|
+
[installation](docs/installation.md) for host prerequisites, exact-version
|
|
72
|
+
installation and Bash completion. Developers can also
|
|
73
|
+
[run from source](docs/installation.md#source-installation-and-project-opt-in).
|
|
71
74
|
|
|
72
75
|
## Quickstart
|
|
73
76
|
|
|
74
77
|
Use a dedicated Git control repository and an empty configuration marker:
|
|
75
78
|
|
|
76
79
|
```bash
|
|
77
|
-
cd ..
|
|
78
80
|
mkdir control-repo
|
|
79
81
|
cd control-repo
|
|
80
82
|
git init
|
|
@@ -126,8 +128,10 @@ See [diagnostic access and recovery](docs/nodes.md#root-diagnostic-commands-and-
|
|
|
126
128
|
|
|
127
129
|
## Alpha status
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
The first public alpha, [`v0.1.0-alpha.1`](https://github.com/c8m6/empeira/releases/tag/v0.1.0-alpha.1),
|
|
132
|
+
is available on [RubyGems.org](https://rubygems.org/gems/empeira). Interfaces
|
|
133
|
+
and inventory schemas may change; unsupported inventory fails closed without
|
|
134
|
+
automatic migration.
|
|
131
135
|
Use synthetic control code and disposable credentials. The shared network is a
|
|
132
136
|
cooperative lab, and its internal PuppetDB API is unauthenticated.
|
|
133
137
|
|
|
@@ -135,7 +139,7 @@ Container process mode does not provide a full booted OS. Systemd requires Podma
|
|
|
135
139
|
and cgroup v2. VM and shared-network support require actual host capabilities;
|
|
136
140
|
macOS/HVF and arm64 runtime validation are manual gates. Native Windows, automatic
|
|
137
141
|
self-update, aggregate `update all` and standalone platform binaries are unavailable.
|
|
138
|
-
|
|
142
|
+
Distribution is through RubyGems.org and the matching GitHub Release gem asset.
|
|
139
143
|
|
|
140
144
|
## Community and license
|
|
141
145
|
|
data/docs/addons.md
CHANGED
|
@@ -329,3 +329,15 @@ is incomplete, stop users of that source and remove only its affected source
|
|
|
329
329
|
namespace before synchronizing again; never delete a live lock as recovery.
|
|
330
330
|
For missing command completion, inspect `addons info NAME` and source the current
|
|
331
331
|
Bash completion again after an Empeira upgrade.
|
|
332
|
+
|
|
333
|
+
## Ruby support and addon development
|
|
334
|
+
|
|
335
|
+
Core and the official Convert, Pre-Commit and Sync addons support Ruby 3.1, 3.2,
|
|
336
|
+
3.3, 3.4 and 4.0 on Linux, macOS and WSL2. Ruby 3.1 is the minimum. Keep API 1
|
|
337
|
+
entrypoints runnable directly, preserve argv, terminal streams, environment and
|
|
338
|
+
exit status, and explicitly require libraries that newer Rubies no longer ship.
|
|
339
|
+
Do not install gems implicitly. Convert's XML support needs user-installed REXML.
|
|
340
|
+
Test complete standalone behavior and actual execution through Core on all five
|
|
341
|
+
Rubies; syntax checks alone are insufficient. See the [development gate](development.md#ruby-compatibility)
|
|
342
|
+
for the required Linux/macOS matrix, pinned source checkouts and local commands.
|
|
343
|
+
Real container/VM and WSL2 capabilities require their own integration gates.
|
data/docs/development.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Environment and quality checks
|
|
4
4
|
|
|
5
|
-
Install Git, Ruby 3.
|
|
6
|
-
[installation](installation.md). The gem requires Ruby 3.
|
|
7
|
-
|
|
8
|
-
RuboCop and both dependency audits only on Ruby 3.4. Release builds use Ruby 3.4.
|
|
5
|
+
Install Git, Ruby 3.1+, Bundler and the platform prerequisites in
|
|
6
|
+
[installation](installation.md). The gem requires Ruby 3.1+; normal Ubuntu and macOS CI
|
|
7
|
+
runs deterministic RSpec on Ruby 3.1, 3.2, 3.3, 3.4 and 4.0, with
|
|
8
|
+
RuboCop and both dependency audits only on Ubuntu with Ruby 3.4. Release builds use Ruby 3.4.
|
|
9
9
|
Use synthetic control repositories and disposable credentials.
|
|
10
10
|
|
|
11
11
|
```console
|
|
@@ -20,7 +20,7 @@ bundle exec bundler-audit check --gemfile-lock resources/modules/Gemfile.lock
|
|
|
20
20
|
local child processes and loopback fixtures. Explicit integration gates are pending
|
|
21
21
|
unless enabled; a pending test is not a successful runtime check. Security auditing
|
|
22
22
|
covers known Ruby advisories in both resolutions, not all container OS packages.
|
|
23
|
-
To reproduce
|
|
23
|
+
To reproduce a CI test job, activate the corresponding Ruby, install the locked
|
|
24
24
|
bundle and run `bundle exec rspec --exclude-pattern 'spec/integration/**/*_spec.rb'`.
|
|
25
25
|
Runtime and VM compatibility remain separate manual gates.
|
|
26
26
|
|
|
@@ -93,18 +93,73 @@ For workflow changes, parse `.github/workflows/*.yml` and run `actionlint` when
|
|
|
93
93
|
available. Review action pins, triggers and permissions as well as YAML syntax.
|
|
94
94
|
See [contributing](../CONTRIBUTING.md) for review, commit and label conventions.
|
|
95
95
|
|
|
96
|
-
### Ruby
|
|
96
|
+
### Ruby compatibility
|
|
97
97
|
|
|
98
|
-
Ruby 3.
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
Ruby 3.1 is the minimum. Ruby 3.1, 3.2, 3.3, 3.4 and 4.0 run the complete
|
|
99
|
+
deterministic suite on Ubuntu 24.04 and native macOS 15 in regular CI. Every
|
|
100
|
+
combination is required, including Ruby 4.0. The suite covers the CLI, Bash
|
|
101
|
+
completion, providers, networking, bootstrap, updates, addon contracts and gem
|
|
102
|
+
build/install/start. The existing Docker/OpenVox node smoke also runs on all five
|
|
103
|
+
Rubies on Ubuntu, with at most two concurrent jobs. Broader manual runtime
|
|
104
|
+
integrations and release builds remain on Ruby 3.4;
|
|
105
|
+
a unit test does not establish Docker, rootless Podman, KVM/HVF or WSL2 results.
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
Both committed lockfiles use Bundler 2.6.9, compatible with Ruby 3.1. Ruby 4.0
|
|
108
|
+
requires the explicit Bundler 4.0.22 selection to avoid RubyGems platform-constant
|
|
109
|
+
warnings. Frozen installation keeps the same dependencies and lockfiles on every
|
|
110
|
+
Ruby. To reproduce Ruby 4 CI without editing either lockfile:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
gem install bundler -v 4.0.22 --no-document
|
|
114
|
+
export BUNDLER_VERSION=4.0.22 BUNDLE_FROZEN=true
|
|
115
|
+
bundle install
|
|
116
|
+
bundle exec rspec --exclude-pattern 'spec/integration/**/*_spec.rb'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
For Ruby 3.x, use `BUNDLER_VERSION=2.6.9` instead. The module-helper image uses
|
|
120
|
+
Bundler 2.6.9 on its separately pinned Ruby base. r10k's transitive dependencies
|
|
121
|
+
`fast_gettext` and `multi_json` remain on 3.1.x and 1.18.0 respectively because
|
|
122
|
+
newer versions require Ruby 3.2. Other locked gem versions are retained. Ruby 3.1's
|
|
123
|
+
internal Data compatibility implementation preserves positional and keyword
|
|
124
|
+
constructors (including `[]` and custom initializers), frozen copies and empty
|
|
125
|
+
record value semantics. Newer Rubies retain their native Data implementation. Both
|
|
126
|
+
locks contain registry SHA-256 checksums generated by Bundler, not hand-entered:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
bundle _2.6.9_ lock --add-checksums
|
|
130
|
+
BUNDLE_GEMFILE=resources/modules/Gemfile bundle _2.6.9_ lock --add-checksums
|
|
131
|
+
git diff -- Gemfile.lock resources/modules/Gemfile.lock
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The real official addon acceptance gate is also required in every Linux/macOS
|
|
135
|
+
matrix job. CI checks out reviewed addon commits, then installs them through
|
|
136
|
+
Core's actual local Git acquisition, cache, manifest, configuration and execution
|
|
137
|
+
paths. Synthetic control/Hiera repositories, a real PTY and a local rsync stub
|
|
138
|
+
cover revision updates, failed-update retention, argv, inherited environment,
|
|
139
|
+
configuration exports, native errors and signal-derived status. No real data or
|
|
140
|
+
external synchronization endpoints are used. With the three addon checkouts
|
|
141
|
+
under a common directory, run:
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
EMPEIRA_OFFICIAL_ADDON_ROOT=/path/to/checkouts \
|
|
145
|
+
bundle exec rspec spec/acceptance/official_addons.rb
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Each checkout must be named `empeira-addon-convert`, `empeira-addon-pre-commit`
|
|
149
|
+
or `empeira-addon-sync`. Set `EMPEIRA_OFFICIAL_ADDONS=sync` (or a comma-separated
|
|
150
|
+
subset) to select checkouts; absent sources fail the gate. Addon CI uses the
|
|
151
|
+
same gate against a pinned Core revision. Update the reviewed commit pins in
|
|
152
|
+
CI when changing either side of API 1. Standalone addon unit tests remain in
|
|
153
|
+
each addon's matrix. macOS installs GNU coreutils and GNU tar for fixtures that
|
|
154
|
+
execute Linux guest package-manager commands against synthetic roots; these are
|
|
155
|
+
test dependencies, not macOS product prerequisites. Fixtures canonicalize temporary
|
|
156
|
+
paths, keep Unix socket names short and declare synthetic CPU architectures.
|
|
157
|
+
The single Python Linux-guest adapter probe requires Linux `epoll` and `waitid`;
|
|
158
|
+
it is explicitly unavailable on Darwin and remains required on every Ubuntu
|
|
159
|
+
Ruby job. All other deterministic examples and official addon acceptance run
|
|
160
|
+
natively on macOS. Pre-commit's real container integration remains required on
|
|
161
|
+
Linux; hosted macOS has no configured Docker/Podman engine. No native Windows
|
|
162
|
+
jobs are used, and WSL2 runtime validation remains a separate real-host gate.
|
|
108
163
|
|
|
109
164
|
The test checkout must be writable: the QEMU monitor-directory cleanup fixture
|
|
110
165
|
uses the checkout as a synthetic home. A read-only container bind mount caused one
|
|
@@ -390,8 +445,35 @@ Title and release-note edits do not repair incorrect immutable assets.
|
|
|
390
445
|
|
|
391
446
|
Release notes use merged PR labels from `.github/release.yml`, independently of
|
|
392
447
|
Conventional Commit types. See [label conventions](../CONTRIBUTING.md#release-note-labels).
|
|
393
|
-
The first
|
|
394
|
-
|
|
448
|
+
The first alpha is distributed as a verified GitHub Release gem and published
|
|
449
|
+
unchanged to [RubyGems.org](https://rubygems.org/gems/empeira) via OIDC Trusted
|
|
450
|
+
Publishing. Standalone Linux/macOS binaries and automatic self-update are not
|
|
451
|
+
implemented.
|
|
452
|
+
|
|
453
|
+
### RubyGems.org distribution (manual)
|
|
454
|
+
|
|
455
|
+
After a verified GitHub Release exists, use
|
|
456
|
+
`.github/workflows/publish-rubygems.yml` via **Actions → Publish existing release to RubyGems.org → Run workflow**.
|
|
457
|
+
Run it from `main`, entering the existing release tag (for example `v0.1.0-alpha.1`).
|
|
458
|
+
The default `dry_run: true` checks the existing GitHub release, tag ancestry,
|
|
459
|
+
uploaded gem SHA-256 and embedded build metadata; it never creates a tag,
|
|
460
|
+
rebuilds a gem or contacts RubyGems with publishing credentials.
|
|
461
|
+
|
|
462
|
+
For a new gem that has not yet been published, the owner must first configure a
|
|
463
|
+
[Pending Trusted Publisher](https://rubygems.org/profile/oidc/pending_trusted_publishers)
|
|
464
|
+
on RubyGems.org. Empeira's publisher is already configured for gem `empeira`,
|
|
465
|
+
repository owner `c8m6`, repository `empeira`, workflow filename
|
|
466
|
+
`publish-rubygems.yml` and no GitHub Environment. After a successful dry-run,
|
|
467
|
+
run the same workflow with `dry_run: false`. Only its upload step receives
|
|
468
|
+
short-lived RubyGems credentials via GitHub OIDC; no persistent API key is required.
|
|
469
|
+
|
|
470
|
+
Publishing uploads the exact previously verified GitHub Release asset, not a
|
|
471
|
+
second build, and does not modify GitHub Releases or source. It fails closed
|
|
472
|
+
if the asset differs, the tag is not on `main`, or RubyGems rejects the upload.
|
|
473
|
+
RubyGems does not allow uploading the same gem name/version twice; inspect
|
|
474
|
+
the existing published version before rerunning a failed push. After success,
|
|
475
|
+
install the alpha with `gem install empeira --pre`. GitHub Releases remain
|
|
476
|
+
the authoritative archive of release artifacts.
|
|
395
477
|
|
|
396
478
|
## Dependency and image provenance
|
|
397
479
|
|
|
@@ -470,3 +552,8 @@ The DNS gate checks UDP/TCP, internal/external names, NXDOMAIN, large-answer fal
|
|
|
470
552
|
unavailable/recreated CoreDNS, a second workspace with a different subnet and
|
|
471
553
|
CoreDNS address, rule removal and idempotent reconciliation. Node identity also
|
|
472
554
|
checks both virtual DNS transports before and after node stop/start.
|
|
555
|
+
|
|
556
|
+
The VirtIO upload regression deliberately delays staged-file unlinking. Successful
|
|
557
|
+
completion must follow both atomic installation and temporary-file cleanup; a
|
|
558
|
+
cleanup failure cannot acknowledge success. The unchanged binary-upload/empty-stage
|
|
559
|
+
assertions cover this ordering on Linux, independently from the real KVM gate.
|
data/docs/installation.md
CHANGED
|
@@ -1,36 +1,63 @@
|
|
|
1
1
|
# Installation
|
|
2
2
|
|
|
3
3
|
Empeira runs natively on Linux and macOS. Windows uses **WSL2 → Linux → Empeira**;
|
|
4
|
-
native Windows Ruby is unsupported. The gemspec requires **Ruby >= 3.
|
|
5
|
-
|
|
6
|
-
release gems are built with Ruby 3.4.
|
|
7
|
-
|
|
4
|
+
native Windows Ruby is unsupported. The gemspec requires **Ruby >= 3.1**; supported Ruby versions are **3.1, 3.2,
|
|
5
|
+
3.3, 3.4 and 4.0**. Normal CI tests all five on Ubuntu and native macOS;
|
|
6
|
+
release gems are built with Ruby 3.4. The first public alpha is
|
|
7
|
+
[`v0.1.0-alpha.1`](https://github.com/c8m6/empeira/releases/tag/v0.1.0-alpha.1)
|
|
8
|
+
and is available on [RubyGems.org](https://rubygems.org/gems/empeira).
|
|
9
|
+
|
|
10
|
+
## Install from RubyGems.org (recommended)
|
|
11
|
+
|
|
12
|
+
After installing Ruby 3.1+ and the appropriate host tools/container runtime
|
|
13
|
+
described below, install Empeira from RubyGems.org:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gem install --user-install empeira --pre
|
|
17
|
+
export PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
|
|
18
|
+
empeira --version
|
|
19
|
+
empeira help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The `--pre` flag is needed while Empeira is available as a prerelease. For an
|
|
23
|
+
exact installation of the first alpha, use:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
gem install --user-install empeira --version 0.1.0.pre.alpha.1
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
A gem installation needs neither Bundler nor a Git checkout of Empeira. It
|
|
30
|
+
installs the `thor` runtime dependency automatically; it does **not** install
|
|
31
|
+
Git, Podman/Docker, QEMU, or Puppet/OpenVox node images. Do not use `sudo gem install` for a normal user installation. Keep the gem user's `bin` directory
|
|
32
|
+
in your shell `PATH` to retain the command across new terminal sessions.
|
|
33
|
+
|
|
34
|
+
If you previously used the source-installation `empeira()` shell function,
|
|
35
|
+
remove that function from your shell configuration and start a new shell before
|
|
36
|
+
testing the installed executable. The source function otherwise takes precedence.
|
|
8
37
|
|
|
9
38
|
## Linux and WSL2
|
|
10
39
|
|
|
11
|
-
These commands target **Ubuntu 24.04 LTS** and **Debian 13 trixie**.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
default `ruby` package does not satisfy the gemspec on these hosts.
|
|
40
|
+
These commands target **Ubuntu 24.04 LTS** and **Debian 13 trixie**. Use Ruby 3.1+ from the distribution or your established Ruby version manager.
|
|
41
|
+
Check `ruby --version` before installing the gem. The distribution's default
|
|
42
|
+
`ruby` package is suitable only when it meets the minimum; otherwise activate
|
|
43
|
+
a compatible Ruby before proceeding.
|
|
16
44
|
|
|
17
|
-
|
|
45
|
+
Host utilities and SSH access:
|
|
18
46
|
|
|
19
47
|
```bash
|
|
20
48
|
sudo apt-get update
|
|
21
|
-
sudo apt-get install -y git
|
|
22
|
-
# Activate Ruby 3.
|
|
23
|
-
gem install bundler
|
|
49
|
+
sudo apt-get install -y git openssh-client iproute2
|
|
50
|
+
# Activate Ruby 3.1+ when the distribution's Ruby is too old.
|
|
24
51
|
ruby --version
|
|
25
52
|
gem --version
|
|
26
|
-
bundle --version
|
|
27
53
|
git --version
|
|
28
54
|
ssh -V
|
|
29
55
|
```
|
|
30
56
|
|
|
31
|
-
The selected Ruby installation must supply `gem
|
|
32
|
-
|
|
33
|
-
|
|
57
|
+
The selected Ruby installation must supply `gem`. Bundler, a source checkout and
|
|
58
|
+
a C/C++ build toolchain are not required to install the published Empeira gem.
|
|
59
|
+
They may be needed for source development or for setting up your Ruby environment;
|
|
60
|
+
see [source installation](#source-installation-and-project-opt-in).
|
|
34
61
|
`openssh-client` supplies `ssh` and `ssh-keygen` for regular node SSH. VM management
|
|
35
62
|
uses private VirtIO-Serial and Python 3 already present in the selected cloud image.
|
|
36
63
|
`iproute2` supplies host route inspection for automatic workspace subnet allocation. Coreutils supplies
|
|
@@ -131,11 +158,8 @@ Install Homebrew using its [official instructions](https://brew.sh/), then core:
|
|
|
131
158
|
```bash
|
|
132
159
|
brew install git ruby@3.4 openssh
|
|
133
160
|
export PATH="$(brew --prefix ruby@3.4)/bin:$PATH"
|
|
134
|
-
gem install --user-install bundler
|
|
135
|
-
export PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
|
|
136
161
|
ruby --version
|
|
137
162
|
gem --version
|
|
138
|
-
bundle --version
|
|
139
163
|
git --version
|
|
140
164
|
ssh -V
|
|
141
165
|
```
|
|
@@ -189,7 +213,13 @@ not establish those results. See the [VM validation gates](development.md#vm-and
|
|
|
189
213
|
|
|
190
214
|
## Source installation and project opt-in
|
|
191
215
|
|
|
216
|
+
For development or unreleased changes, run Empeira directly from a Git checkout.
|
|
217
|
+
This alternative requires Bundler and the development dependencies (including a
|
|
218
|
+
build toolchain where native gems need it). Set up Bundler first, then:
|
|
219
|
+
|
|
192
220
|
```bash
|
|
221
|
+
gem install --user-install bundler
|
|
222
|
+
export PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
|
|
193
223
|
git clone https://github.com/c8m6/empeira.git
|
|
194
224
|
cd empeira
|
|
195
225
|
bundle config set --local path vendor/bundle
|
|
@@ -213,21 +243,22 @@ invocation and paths with spaces work. No Puppet-file heuristic or `--project`
|
|
|
213
243
|
selector exists. The source shell function preserves the current directory.
|
|
214
244
|
Version/help/self-update work outside Git (self-update currently reports unavailable).
|
|
215
245
|
|
|
216
|
-
## Release gem
|
|
246
|
+
## Install the GitHub Release gem (alternative)
|
|
217
247
|
|
|
218
|
-
|
|
219
|
-
|
|
248
|
+
The [GitHub Releases](https://github.com/c8m6/empeira/releases) page also
|
|
249
|
+
provides the exact `.gem` asset built and verified by the release pipeline.
|
|
250
|
+
For example, after downloading the first alpha:
|
|
220
251
|
|
|
221
252
|
```bash
|
|
222
|
-
gem install --user-install ./empeira-
|
|
253
|
+
gem install --user-install ./empeira-0.1.0.pre.alpha.1.gem
|
|
223
254
|
export PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
|
|
224
255
|
empeira --version
|
|
225
256
|
```
|
|
226
257
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
258
|
+
Both distribution paths use the same verified gem for the corresponding release.
|
|
259
|
+
The release version is embedded in BuildInfo. No third-party agents, images or
|
|
260
|
+
binaries are bundled. Standalone platform binaries and automatic self-update
|
|
261
|
+
remain unavailable.
|
|
231
262
|
|
|
232
263
|
For other Linux distributions, install equivalent Ruby/Git/runtime packages through
|
|
233
264
|
your established host setup. Guest OS support does not imply a tested host recipe.
|
data/lib/empeira/build.json
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ruby 3.2 introduced immutable Data value objects. Keep Ruby 3.1 support
|
|
4
|
+
# without replacing the native Data implementation on newer Rubies.
|
|
5
|
+
module Empeira
|
|
6
|
+
module Compatibility
|
|
7
|
+
module DataFactory
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength -- Ruby 3.1 must emulate Data initializer semantics.
|
|
11
|
+
def define(*members, &definition)
|
|
12
|
+
# The explicit nil class name also permits zero members and preserves
|
|
13
|
+
# Struct's value equality, hashing and pattern matching for empty records.
|
|
14
|
+
base_class = Struct.new(nil, *members, keyword_init: true)
|
|
15
|
+
base_class.class_eval do
|
|
16
|
+
def initialize(*positional, **keywords)
|
|
17
|
+
fields = self.class.members
|
|
18
|
+
raise ArgumentError, 'too many positional arguments' if positional.size > fields.size
|
|
19
|
+
|
|
20
|
+
supplied = fields.take(positional.size).zip(positional).to_h.merge(keywords)
|
|
21
|
+
missing = fields - supplied.keys
|
|
22
|
+
unexpected = supplied.keys - fields
|
|
23
|
+
raise ArgumentError, "missing keywords: #{missing.join(', ')}" unless missing.empty?
|
|
24
|
+
raise ArgumentError, "unknown keywords: #{unexpected.join(', ')}" unless unexpected.empty?
|
|
25
|
+
|
|
26
|
+
super(**supplied)
|
|
27
|
+
freeze
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def with(**changes)
|
|
31
|
+
self.class.new(**to_h, **changes)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize_copy(other)
|
|
35
|
+
super
|
|
36
|
+
freeze
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
value_class = Class.new(base_class)
|
|
40
|
+
define_constructors(value_class)
|
|
41
|
+
value_class.include(self)
|
|
42
|
+
value_class.class_eval(&definition) if definition
|
|
43
|
+
value_class
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# rubocop:disable-next Metrics/AbcSize -- Normalize native Data constructors before custom initialization.
|
|
47
|
+
def define_constructors(value_class)
|
|
48
|
+
value_class.define_singleton_method(:new) do |*positional, **keywords|
|
|
49
|
+
raise ArgumentError, 'cannot mix positional and keyword arguments' unless positional.empty? || keywords.empty?
|
|
50
|
+
raise ArgumentError, 'too many positional arguments' if positional.size > members.size
|
|
51
|
+
|
|
52
|
+
keywords = members.take(positional.size).zip(positional).to_h unless positional.empty?
|
|
53
|
+
super(**keywords).freeze
|
|
54
|
+
end
|
|
55
|
+
value_class.define_singleton_method(:[]) { |*positional, **keywords| new(*positional, **keywords) }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Data = Empeira::Compatibility::DataFactory unless defined?(Data)
|
|
@@ -6,7 +6,7 @@ module Empeira
|
|
|
6
6
|
class Backend
|
|
7
7
|
attr_reader :context, :runtime, :runner, :store
|
|
8
8
|
|
|
9
|
-
def self.build(context:, **)
|
|
9
|
+
def self.build(context:, **options)
|
|
10
10
|
klass = if context.container_engine == 'docker'
|
|
11
11
|
DockerAdapter
|
|
12
12
|
elsif context.platform.os == :macos
|
|
@@ -14,7 +14,7 @@ module Empeira
|
|
|
14
14
|
else
|
|
15
15
|
LinuxPodman
|
|
16
16
|
end
|
|
17
|
-
klass.new(context: context, **)
|
|
17
|
+
klass.new(context: context, **options)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def initialize(context:, runtime:, runner:, store:)
|
|
@@ -92,8 +92,8 @@ module Empeira
|
|
|
92
92
|
raise Providers::OwnershipError, 'VM TAP already exists; inspect its owning process'
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
def namespace(
|
|
96
|
-
command('podman', '--remote=false', 'unshare', '--rootless-netns',
|
|
95
|
+
def namespace(*arguments, **options)
|
|
96
|
+
command('podman', '--remote=false', 'unshare', '--rootless-netns', *arguments, **options)
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def attached?(record, links)
|
|
@@ -98,13 +98,13 @@ module Empeira
|
|
|
98
98
|
raise Error, 'Podman Machine cannot verify the peer helper at its host path; configure its shared mount'
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
def namespace(*)
|
|
102
|
-
executable, *
|
|
103
|
-
command(executable, *
|
|
101
|
+
def namespace(*arguments)
|
|
102
|
+
executable, *command_arguments = namespace_command(@machine, *arguments)
|
|
103
|
+
command(executable, *command_arguments)
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
def namespace_command(machine, *)
|
|
107
|
-
['podman', 'machine', 'ssh', machine, Shellwords.join(['podman', 'unshare', '--rootless-netns', *])]
|
|
106
|
+
def namespace_command(machine, *arguments)
|
|
107
|
+
['podman', 'machine', 'ssh', machine, Shellwords.join(['podman', 'unshare', '--rootless-netns', *arguments])]
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
end
|
|
@@ -5,10 +5,10 @@ module Empeira
|
|
|
5
5
|
class Definition < Services::Definition
|
|
6
6
|
attr_reader :hostname
|
|
7
7
|
|
|
8
|
-
def initialize(hostname:, workspace:, **)
|
|
8
|
+
def initialize(hostname:, workspace:, **options)
|
|
9
9
|
@hostname = hostname
|
|
10
10
|
super(key: "node-#{Digest::SHA256.hexdigest(hostname)[0, 24]}", workspace: workspace,
|
|
11
|
-
hostname: hostname, **)
|
|
11
|
+
hostname: hostname, **options)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def ownership_labels
|
|
@@ -73,9 +73,9 @@ module Empeira
|
|
|
73
73
|
{ label: 'VM network helper', image: adapter.image, recipe: adapter.recipe, files: adapter.files }]
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
def utility_artifact(key, label, **)
|
|
76
|
+
def utility_artifact(key, label, **options)
|
|
77
77
|
Empeira::Images::Configuration.artifact(
|
|
78
|
-
@config.dig('images', key), registry: @config.dig('images', 'registry'), **
|
|
78
|
+
@config.dig('images', key), registry: @config.dig('images', 'registry'), **options
|
|
79
79
|
).merge(label: label)
|
|
80
80
|
end
|
|
81
81
|
|
data/lib/empeira.rb
CHANGED
|
@@ -5,7 +5,7 @@ RUN apk add --no-cache git ca-certificates
|
|
|
5
5
|
WORKDIR /opt/empeira-modules
|
|
6
6
|
COPY Gemfile Gemfile.lock ./
|
|
7
7
|
RUN apk add --no-cache --virtual .build-deps build-base libffi-dev \
|
|
8
|
-
&& gem install bundler -v
|
|
8
|
+
&& gem install bundler -v 2.6.9 --no-document \
|
|
9
9
|
&& bundle config set deployment true && bundle install --jobs 2 \
|
|
10
10
|
&& apk del .build-deps
|
|
11
11
|
COPY worker.rb ./
|
data/resources/modules/Gemfile
CHANGED
|
@@ -3,3 +3,9 @@
|
|
|
3
3
|
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
gem 'r10k', '5.0.3'
|
|
6
|
+
|
|
7
|
+
# r10k's newer fast_gettext 4.x dependency requires Ruby >= 3.2.
|
|
8
|
+
# Keep the module helper usable with the oldest supported Ruby (3.1).
|
|
9
|
+
gem 'fast_gettext', '~> 3.1.0'
|
|
10
|
+
# Newer multi_json requires Ruby >= 3.2.
|
|
11
|
+
gem 'multi_json', '1.18.0'
|
|
@@ -13,9 +13,8 @@ GEM
|
|
|
13
13
|
faraday (>= 1, < 3)
|
|
14
14
|
faraday-net_http (3.4.4)
|
|
15
15
|
net-http (~> 0.5)
|
|
16
|
-
fast_gettext (
|
|
16
|
+
fast_gettext (3.1.0)
|
|
17
17
|
prime
|
|
18
|
-
racc
|
|
19
18
|
fiddle (1.1.8)
|
|
20
19
|
forwardable (1.4.0)
|
|
21
20
|
gettext (3.5.2)
|
|
@@ -36,7 +35,7 @@ GEM
|
|
|
36
35
|
log4r (1.1.10)
|
|
37
36
|
logger (1.7.0)
|
|
38
37
|
minitar (1.1.0)
|
|
39
|
-
multi_json (1.
|
|
38
|
+
multi_json (1.18.0)
|
|
40
39
|
net-http (0.9.1)
|
|
41
40
|
uri (>= 0.11.1)
|
|
42
41
|
prime (0.1.4)
|
|
@@ -68,18 +67,19 @@ PLATFORMS
|
|
|
68
67
|
x86_64-linux
|
|
69
68
|
|
|
70
69
|
DEPENDENCIES
|
|
70
|
+
fast_gettext (~> 3.1.0)
|
|
71
|
+
multi_json (= 1.18.0)
|
|
71
72
|
r10k (= 5.0.3)
|
|
72
73
|
|
|
73
74
|
CHECKSUMS
|
|
74
75
|
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
75
|
-
bundler (4.0.22) sha256=d8d5ec84c8555e0af71db63ed7aee4d1a8fb839ec46d84212d61979242a5d75a
|
|
76
76
|
colored2 (4.0.3) sha256=63e1038183976287efc43034f5cca17fb180b4deef207da8ba78d051cbce2b37
|
|
77
77
|
cri (2.15.12) sha256=8abfe924ef53e772a8e4ee907e791d3bfcfca78bc62a5859e3b9899ba29956e5
|
|
78
78
|
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
|
|
79
79
|
faraday (2.14.4) sha256=9bb4408c44621b0dbaaaa39e5dbfc4dbe58cc6751b6eb94d16ae9e1f2f2fab6e
|
|
80
80
|
faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad
|
|
81
81
|
faraday-net_http (3.4.4) sha256=0e78af151747ed1b00f33e25973b4bc220d7f16c00c39676817c8b12331eb588
|
|
82
|
-
fast_gettext (
|
|
82
|
+
fast_gettext (3.1.0) sha256=9c4c84c33a875cc9edc062179229f9d373179a624d3c961eed747cddbab72ac5
|
|
83
83
|
fiddle (1.1.8) sha256=7fa8ee3627271497f3add5503acdbc3f40b32f610fc1cf49634f083ef3f32eee
|
|
84
84
|
forwardable (1.4.0) sha256=f1cd40cc9812937980e1c76f1aa053660990a7c9b6a98fc37d945468afcce838
|
|
85
85
|
gettext (3.5.2) sha256=ada02c59aa7e9f56bd2522faedaed16421dd2f3ddb5fe28628c0be5abcbf3c74
|
|
@@ -90,7 +90,7 @@ CHECKSUMS
|
|
|
90
90
|
log4r (1.1.10) sha256=9b452928c964b7c54c09aeb25ff045b5a722b387b16c9ce37cb1baec00062966
|
|
91
91
|
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
92
92
|
minitar (1.1.0) sha256=38db0cfb6f3801017946cdcd8dc53f2cf3fd41ff752892312bf9a1639c9ea23e
|
|
93
|
-
multi_json (1.
|
|
93
|
+
multi_json (1.18.0) sha256=23f70cf73e2895a33e6d10f0ec955b28ef5627ca4bbad0f292e7d16f4675596f
|
|
94
94
|
net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996
|
|
95
95
|
prime (0.1.4) sha256=4d755ebf7c2994a6f3a3fee0d072063be3fff2d4042ebff6cd5eebd4747a225e
|
|
96
96
|
puppet_forge (6.2.0) sha256=9cde4841a7a6950afeb0c4fec02449931179863918c0a6e6909cb2a6c6998a0c
|
|
@@ -102,4 +102,4 @@ CHECKSUMS
|
|
|
102
102
|
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
|
|
103
103
|
|
|
104
104
|
BUNDLED WITH
|
|
105
|
-
|
|
105
|
+
2.6.9
|
|
@@ -316,6 +316,7 @@ def handle(message):
|
|
|
316
316
|
active['file'].close()
|
|
317
317
|
active = None
|
|
318
318
|
pending = None
|
|
319
|
+
status = 0
|
|
319
320
|
try:
|
|
320
321
|
with tempfile.NamedTemporaryFile(dir=os.path.dirname(destination), delete=False) as target:
|
|
321
322
|
pending = target.name
|
|
@@ -326,14 +327,16 @@ def handle(message):
|
|
|
326
327
|
os.fsync(target.fileno())
|
|
327
328
|
os.replace(pending, destination)
|
|
328
329
|
pending = None
|
|
329
|
-
send({'type': 'exit', 'status': 0, 'timed_out': False})
|
|
330
330
|
except OSError as error:
|
|
331
331
|
send({'type': 'stderr', 'data': base64.b64encode((os.strerror(error.errno) + '\n').encode()).decode()})
|
|
332
|
-
|
|
332
|
+
status = 1
|
|
333
333
|
finally:
|
|
334
334
|
os.unlink(staged)
|
|
335
335
|
if pending:
|
|
336
336
|
os.unlink(pending)
|
|
337
|
+
# Completion includes staging cleanup; an unlink failure must never
|
|
338
|
+
# acknowledge success to a controller that is already enrolling/Puppet.
|
|
339
|
+
send({'type': 'exit', 'status': status, 'timed_out': False})
|
|
337
340
|
else:
|
|
338
341
|
raise ValueError('Unexpected protocol operation')
|
|
339
342
|
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
ARG EMPEIRA_BASE_UBUNTU=library/ubuntu@sha256:da6fc2be547864451aa253836dd926da33623312df4a9a243e35dc877c378a78
|
|
2
2
|
FROM ${EMPEIRA_BASE_UBUNTU}
|
|
3
3
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
4
|
-
RUN
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
RUN ["apt-get", "--snapshot", "20261001T000000Z", "-o", "APT::Update::Error-Mode=any", "update"]
|
|
8
|
-
RUN ["apt-get", "--snapshot", "20261001T000000Z", "install", "--yes", "--no-install-recommends", "squid=7.2-2ubuntu2.2"]
|
|
9
|
-
RUN ["apt-get", "clean"]
|
|
4
|
+
RUN apt-get -o APT::Update::Error-Mode=any update \
|
|
5
|
+
&& apt-get install --yes --no-install-recommends ca-certificates squid \
|
|
6
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
10
7
|
USER proxy
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: empeira
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0.pre.alpha.
|
|
4
|
+
version: 0.1.0.pre.alpha.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Christian Meißner (c8m6)
|
|
@@ -72,6 +72,7 @@ files:
|
|
|
72
72
|
- lib/empeira/cli/progress.rb
|
|
73
73
|
- lib/empeira/cli/proxy.rb
|
|
74
74
|
- lib/empeira/cli/update.rb
|
|
75
|
+
- lib/empeira/compatibility/data.rb
|
|
75
76
|
- lib/empeira/completion/addons.rb
|
|
76
77
|
- lib/empeira/completion/bash.rb
|
|
77
78
|
- lib/empeira/completion/catalog.rb
|
|
@@ -313,7 +314,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
313
314
|
requirements:
|
|
314
315
|
- - ">="
|
|
315
316
|
- !ruby/object:Gem::Version
|
|
316
|
-
version: '3.
|
|
317
|
+
version: '3.1'
|
|
317
318
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
318
319
|
requirements:
|
|
319
320
|
- - ">="
|