empeira 0.1.0.pre.alpha.1
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 +7 -0
- data/LICENSE +661 -0
- data/README.md +150 -0
- data/bin/empeira +18 -0
- data/config/defaults.yaml +229 -0
- data/docs/addons.md +331 -0
- data/docs/architecture.md +277 -0
- data/docs/configuration.md +1204 -0
- data/docs/development.md +472 -0
- data/docs/hiera-and-eyaml.md +361 -0
- data/docs/installation.md +280 -0
- data/docs/networking.md +362 -0
- data/docs/nodes.md +642 -0
- data/docs/proxy.md +136 -0
- data/docs/troubleshooting.md +361 -0
- data/lib/empeira/addons/environment.rb +82 -0
- data/lib/empeira/addons/error.rb +14 -0
- data/lib/empeira/addons/installation.rb +119 -0
- data/lib/empeira/addons/manifest.rb +112 -0
- data/lib/empeira/addons/service.rb +50 -0
- data/lib/empeira/addons/storage.rb +94 -0
- data/lib/empeira/agent/acquisition.rb +120 -0
- data/lib/empeira/agent/artifact.rb +41 -0
- data/lib/empeira/agent/authentication.rb +122 -0
- data/lib/empeira/agent/cache.rb +122 -0
- data/lib/empeira/agent/cache_storage.rb +82 -0
- data/lib/empeira/agent/download.rb +84 -0
- data/lib/empeira/agent/native_commands.rb +84 -0
- data/lib/empeira/agent/release_sources.rb +64 -0
- data/lib/empeira/agent/target.rb +66 -0
- data/lib/empeira/agent/versions.rb +29 -0
- data/lib/empeira/application.rb +86 -0
- data/lib/empeira/build.json +5 -0
- data/lib/empeira/build_info.rb +46 -0
- data/lib/empeira/cli/addons.rb +45 -0
- data/lib/empeira/cli/base.rb +73 -0
- data/lib/empeira/cli/completion.rb +42 -0
- data/lib/empeira/cli/config.rb +22 -0
- data/lib/empeira/cli/main.rb +114 -0
- data/lib/empeira/cli/node.rb +87 -0
- data/lib/empeira/cli/progress.rb +169 -0
- data/lib/empeira/cli/proxy.rb +36 -0
- data/lib/empeira/cli/update.rb +23 -0
- data/lib/empeira/completion/addons.rb +93 -0
- data/lib/empeira/completion/bash.rb +62 -0
- data/lib/empeira/completion/catalog.rb +170 -0
- data/lib/empeira/configuration/additional_services.rb +74 -0
- data/lib/empeira/configuration/addons.rb +85 -0
- data/lib/empeira/configuration/agent_schema.rb +163 -0
- data/lib/empeira/configuration/agent_values.rb +54 -0
- data/lib/empeira/configuration/bootstrap_guests.rb +42 -0
- data/lib/empeira/configuration/command_mocks.rb +65 -0
- data/lib/empeira/configuration/display.rb +20 -0
- data/lib/empeira/configuration/dns_rewrites.rb +58 -0
- data/lib/empeira/configuration/document.rb +67 -0
- data/lib/empeira/configuration/eyaml.rb +46 -0
- data/lib/empeira/configuration/hiera_modulepath.rb +40 -0
- data/lib/empeira/configuration/hiera_mount_schema.rb +62 -0
- data/lib/empeira/configuration/hiera_mounts.rb +83 -0
- data/lib/empeira/configuration/image_schema.rb +68 -0
- data/lib/empeira/configuration/loader.rb +70 -0
- data/lib/empeira/configuration/merge.rb +48 -0
- data/lib/empeira/configuration/network_redirects.rb +73 -0
- data/lib/empeira/configuration/node_images.rb +64 -0
- data/lib/empeira/configuration/schema.rb +215 -0
- data/lib/empeira/configuration/server_mounts.rb +106 -0
- data/lib/empeira/configuration/service_configuration.rb +40 -0
- data/lib/empeira/configuration/ssh_preferences.rb +83 -0
- data/lib/empeira/configuration/user.rb +46 -0
- data/lib/empeira/configuration/vm_interfaces.rb +147 -0
- data/lib/empeira/control_plane/additional_configurations.rb +106 -0
- data/lib/empeira/control_plane/browser.rb +73 -0
- data/lib/empeira/control_plane/controller.rb +763 -0
- data/lib/empeira/control_plane/discovery.rb +69 -0
- data/lib/empeira/control_plane/environment.rb +101 -0
- data/lib/empeira/control_plane/files.rb +263 -0
- data/lib/empeira/control_plane/health.rb +104 -0
- data/lib/empeira/control_plane/plan.rb +356 -0
- data/lib/empeira/control_plane/storage.rb +48 -0
- data/lib/empeira/errors.rb +9 -0
- data/lib/empeira/execution/console.rb +45 -0
- data/lib/empeira/execution/diagnostics.rb +210 -0
- data/lib/empeira/execution/launch_error.rb +14 -0
- data/lib/empeira/execution/result.rb +11 -0
- data/lib/empeira/execution/runner.rb +235 -0
- data/lib/empeira/execution/terminal.rb +35 -0
- data/lib/empeira/hostname_pattern.rb +14 -0
- data/lib/empeira/images/configuration.rb +44 -0
- data/lib/empeira/images/identity.rb +30 -0
- data/lib/empeira/images/recipe.rb +22 -0
- data/lib/empeira/images/reference.rb +43 -0
- data/lib/empeira/images/source.rb +19 -0
- data/lib/empeira/immutable.rb +19 -0
- data/lib/empeira/infrastructure/cleanup.rb +328 -0
- data/lib/empeira/infrastructure/definition.rb +59 -0
- data/lib/empeira/infrastructure/owned_files.rb +63 -0
- data/lib/empeira/infrastructure/recovery_inventory.rb +53 -0
- data/lib/empeira/infrastructure/service.rb +237 -0
- data/lib/empeira/infrastructure/status.rb +73 -0
- data/lib/empeira/infrastructure/store.rb +274 -0
- data/lib/empeira/modules/events.rb +67 -0
- data/lib/empeira/modules/git_safety.rb +60 -0
- data/lib/empeira/modules/host_git.rb +91 -0
- data/lib/empeira/modules/image.rb +27 -0
- data/lib/empeira/modules/installer.rb +67 -0
- data/lib/empeira/modules/request.rb +68 -0
- data/lib/empeira/modules/state.rb +87 -0
- data/lib/empeira/modules/storage.rb +35 -0
- data/lib/empeira/network/bootstrap_proxy.rb +157 -0
- data/lib/empeira/network/definition.rb +61 -0
- data/lib/empeira/network/direct_egress.rb +133 -0
- data/lib/empeira/network/egress.rb +27 -0
- data/lib/empeira/network/gateway.rb +79 -0
- data/lib/empeira/network/host_policy.rb +53 -0
- data/lib/empeira/network/naming.rb +28 -0
- data/lib/empeira/network/peer/adapter_image.rb +32 -0
- data/lib/empeira/network/peer/allocation.rb +45 -0
- data/lib/empeira/network/peer/attachment.rb +27 -0
- data/lib/empeira/network/peer/backend.rb +108 -0
- data/lib/empeira/network/peer/channel.rb +133 -0
- data/lib/empeira/network/peer/channel_server.rb +71 -0
- data/lib/empeira/network/peer/docker_adapter.rb +165 -0
- data/lib/empeira/network/peer/helper_security.rb +40 -0
- data/lib/empeira/network/peer/layout.rb +55 -0
- data/lib/empeira/network/peer/linux_podman.rb +114 -0
- data/lib/empeira/network/peer/podman_machine.rb +112 -0
- data/lib/empeira/network/policy.rb +39 -0
- data/lib/empeira/network/proxy_bindings.rb +52 -0
- data/lib/empeira/network/proxy_policy.rb +64 -0
- data/lib/empeira/network/redirects.rb +89 -0
- data/lib/empeira/network/resource.rb +50 -0
- data/lib/empeira/node/agent_installer.rb +31 -0
- data/lib/empeira/node/agent_package.rb +125 -0
- data/lib/empeira/node/agent_repository.rb +160 -0
- data/lib/empeira/node/apt_configuration.rb +85 -0
- data/lib/empeira/node/bootstrap.rb +17 -0
- data/lib/empeira/node/certificates.rb +98 -0
- data/lib/empeira/node/command_mock.rb +38 -0
- data/lib/empeira/node/command_mocks.rb +114 -0
- data/lib/empeira/node/container.rb +134 -0
- data/lib/empeira/node/container_agent_bootstrap.rb +43 -0
- data/lib/empeira/node/container_bootstrap.rb +52 -0
- data/lib/empeira/node/container_guest.rb +42 -0
- data/lib/empeira/node/container_lifecycle.rb +145 -0
- data/lib/empeira/node/container_preparation.rb +144 -0
- data/lib/empeira/node/container_state.rb +129 -0
- data/lib/empeira/node/definition.rb +20 -0
- data/lib/empeira/node/diagnostic_command.rb +19 -0
- data/lib/empeira/node/dnf_agent_repository.rb +202 -0
- data/lib/empeira/node/external_fact.rb +21 -0
- data/lib/empeira/node/image.rb +38 -0
- data/lib/empeira/node/interactive_tools.rb +33 -0
- data/lib/empeira/node/interface.rb +18 -0
- data/lib/empeira/node/inventory.rb +143 -0
- data/lib/empeira/node/package_bootstrap.rb +129 -0
- data/lib/empeira/node/package_proxy.rb +102 -0
- data/lib/empeira/node/package_sources.rb +19 -0
- data/lib/empeira/node/puppet_command.rb +12 -0
- data/lib/empeira/node/rpm_configuration.rb +62 -0
- data/lib/empeira/node/run_request.rb +52 -0
- data/lib/empeira/node/runtime_proxy.rb +86 -0
- data/lib/empeira/node/service.rb +72 -0
- data/lib/empeira/node/ssh_client.rb +25 -0
- data/lib/empeira/node/ssh_credentials.rb +78 -0
- data/lib/empeira/node/ssh_endpoint.rb +58 -0
- data/lib/empeira/node/ssh_identity.rb +37 -0
- data/lib/empeira/node/user_ssh.rb +60 -0
- data/lib/empeira/node/vm.rb +89 -0
- data/lib/empeira/node/vm_bootstrap.rb +53 -0
- data/lib/empeira/node/vm_lifecycle.rb +212 -0
- data/lib/empeira/node/vm_preflight.rb +37 -0
- data/lib/empeira/node/vm_preparation.rb +161 -0
- data/lib/empeira/node/vm_state.rb +161 -0
- data/lib/empeira/platform/facts.rb +66 -0
- data/lib/empeira/platform/kvm.rb +91 -0
- data/lib/empeira/platform/locations.rb +51 -0
- data/lib/empeira/platform/resolvers.rb +85 -0
- data/lib/empeira/platform/routes.rb +50 -0
- data/lib/empeira/progress.rb +70 -0
- data/lib/empeira/project_root.rb +47 -0
- data/lib/empeira/providers/lifecycle.rb +96 -0
- data/lib/empeira/providers/registry.rb +21 -0
- data/lib/empeira/providers/resource.rb +32 -0
- data/lib/empeira/providers.rb +55 -0
- data/lib/empeira/runtime/agent_helper.rb +34 -0
- data/lib/empeira/runtime/container.rb +184 -0
- data/lib/empeira/runtime/diagnostic_execution.rb +52 -0
- data/lib/empeira/runtime/docker.rb +87 -0
- data/lib/empeira/runtime/image_metadata.rb +83 -0
- data/lib/empeira/runtime/interface.rb +8 -0
- data/lib/empeira/runtime/mount_probe.rb +57 -0
- data/lib/empeira/runtime/podman.rb +122 -0
- data/lib/empeira/runtime/recipe_build.rb +103 -0
- data/lib/empeira/runtime/registry_diagnostics.rb +23 -0
- data/lib/empeira/runtime/service_arguments.rb +55 -0
- data/lib/empeira/runtime/service_images.rb +118 -0
- data/lib/empeira/runtime/service_inspection.rb +159 -0
- data/lib/empeira/runtime/services.rb +120 -0
- data/lib/empeira/runtime/update_helper.rb +97 -0
- data/lib/empeira/runtime/workspace_network.rb +69 -0
- data/lib/empeira/server/environment_configuration.rb +53 -0
- data/lib/empeira/server/http.rb +38 -0
- data/lib/empeira/server/puppetdb_runtime.rb +74 -0
- data/lib/empeira/server/relay_certificate.rb +76 -0
- data/lib/empeira/server/runtime.rb +90 -0
- data/lib/empeira/services/definition.rb +42 -0
- data/lib/empeira/updates/images.rb +104 -0
- data/lib/empeira/updates/modules.rb +45 -0
- data/lib/empeira/updates/service.rb +45 -0
- data/lib/empeira/version_requirement.rb +23 -0
- data/lib/empeira/vm/agent.rb +66 -0
- data/lib/empeira/vm/bootstrap_requirements.rb +69 -0
- data/lib/empeira/vm/certificate_runtime.rb +30 -0
- data/lib/empeira/vm/cloud_init.rb +171 -0
- data/lib/empeira/vm/disk.rb +136 -0
- data/lib/empeira/vm/guest.rb +123 -0
- data/lib/empeira/vm/guest_channel.rb +110 -0
- data/lib/empeira/vm/guest_network.rb +94 -0
- data/lib/empeira/vm/guest_output.rb +52 -0
- data/lib/empeira/vm/guest_shell.rb +79 -0
- data/lib/empeira/vm/guest_upload.rb +43 -0
- data/lib/empeira/vm/image_cache.rb +77 -0
- data/lib/empeira/vm/image_source.rb +91 -0
- data/lib/empeira/vm/interface.rb +8 -0
- data/lib/empeira/vm/interface_ownership.rb +124 -0
- data/lib/empeira/vm/interface_routes.rb +101 -0
- data/lib/empeira/vm/interfaces.rb +240 -0
- data/lib/empeira/vm/management.rb +73 -0
- data/lib/empeira/vm/prerequisites.rb +42 -0
- data/lib/empeira/vm/qemu.rb +83 -0
- data/lib/empeira/vm/qemu_runtime.rb +404 -0
- data/lib/empeira/vm/removal.rb +30 -0
- data/lib/empeira/vm/root_disk.rb +92 -0
- data/lib/empeira/vm/session_lock.rb +56 -0
- data/lib/empeira/vm/system_ssh.rb +29 -0
- data/lib/empeira/workspace.rb +42 -0
- data/lib/empeira.rb +209 -0
- data/resources/browser/relay.rb +22 -0
- data/resources/gateway/Containerfile +8 -0
- data/resources/gateway/bridge.rb +66 -0
- data/resources/gateway/configure.rb +323 -0
- data/resources/modules/Containerfile +15 -0
- data/resources/modules/Gemfile +5 -0
- data/resources/modules/Gemfile.lock +105 -0
- data/resources/modules/worker.rb +161 -0
- data/resources/network/adapter/Containerfile +13 -0
- data/resources/network/adapter/bridge_linux.go +51 -0
- data/resources/network/adapter/framing.go +45 -0
- data/resources/network/adapter/framing_test.go +53 -0
- data/resources/network/adapter/go.mod +3 -0
- data/resources/network/adapter/main_linux.go +273 -0
- data/resources/network/channel.rb +18 -0
- data/resources/network/ssh_connect.rb +32 -0
- data/resources/nodes/apt_sources.rb +66 -0
- data/resources/nodes/debian/Containerfile +10 -0
- data/resources/nodes/diagnostic_exec.rb +109 -0
- data/resources/nodes/interactive_tools.rb +139 -0
- data/resources/nodes/managed_file.rb +91 -0
- data/resources/nodes/management/guest_agent.py +415 -0
- data/resources/nodes/management/setup.sh +20 -0
- data/resources/nodes/management/shell_rc.sh +12 -0
- data/resources/nodes/management/system_account.sh +24 -0
- data/resources/nodes/management/system_home.sh +15 -0
- data/resources/nodes/rpm/Containerfile +10 -0
- data/resources/nodes/runtime_proxy.rb +244 -0
- data/resources/nodes/ssh/proxy.rb +16 -0
- data/resources/nodes/ssh/sshd_config +15 -0
- data/resources/nodes/ssh/start +6 -0
- data/resources/proxy/Containerfile +10 -0
- data/resources/relay/Containerfile +5 -0
- data/resources/relay/puppetdb.rb +81 -0
- data/resources/relay/server_environment.rb +10 -0
- data/resources/relay/server_start.sh +41 -0
- metadata +326 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Hiera and EYAML
|
|
2
|
+
|
|
3
|
+
The canonical selected control repository is mounted read-only at
|
|
4
|
+
`/etc/puppetlabs/code/environments/production`. Change `server.environment` to use
|
|
5
|
+
another ordinary Puppet environment name. Environment caching is disabled so local,
|
|
6
|
+
uncommitted manifests, modules and data are visible without image rebuilds. The
|
|
7
|
+
repository supplies its normal `environment.conf`, `hiera.yaml`, manifests and
|
|
8
|
+
vendored modules. Puppetfile modules are synchronized explicitly with `update modules` into `modules.path`.
|
|
9
|
+
Empeira installs the structured `facts.empeira` fact before the first catalog:
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
empeira:
|
|
13
|
+
provider: vm # container on container nodes
|
|
14
|
+
hierarchy: empeira
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The hierarchy selector is always the literal string `empeira`. Empeira does not edit
|
|
18
|
+
the repository's `hiera.yaml`.
|
|
19
|
+
|
|
20
|
+
Repositories that need disposable-node overrides can optionally add this hierarchy:
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
hierarchy:
|
|
24
|
+
- name: "Empeira provider"
|
|
25
|
+
path: "virtual/empeira-%{facts.empeira.provider}.yaml"
|
|
26
|
+
- name: "Empeira common"
|
|
27
|
+
path: "virtual/%{facts.empeira.hierarchy}.yaml"
|
|
28
|
+
- name: "Virtualization"
|
|
29
|
+
path: "virtual/%{facts.virtual}.yaml"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Priority lookups select the first matching value: provider-specific overrides in
|
|
33
|
+
`virtual/empeira-vm.yaml` or `virtual/empeira-container.yaml`, then shared overrides
|
|
34
|
+
in `virtual/empeira.yaml`, then the normal virtualization data. Merge lookups retain
|
|
35
|
+
ordinary Hiera merge semantics. For example:
|
|
36
|
+
|
|
37
|
+
`virtual/empeira-vm.yaml`:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
example::profile: vm
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`virtual/empeira-container.yaml`:
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
example::profile: container
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`virtual/empeira.yaml`:
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
example::dns_servers: [198.18.0.53]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
A production node without `facts.empeira` cannot select either Empeira file and uses
|
|
56
|
+
only `virtual/<facts.virtual>.yaml`. The native lookup integration gate verifies
|
|
57
|
+
this negative case with the configured server image, including an existing common
|
|
58
|
+
file. Do not add a static `path: virtual/empeira.yaml`: that would apply the shared
|
|
59
|
+
overrides to production nodes too. `facts.virtual` remains Facter's own platform fact.
|
|
60
|
+
|
|
61
|
+
Existing provisioned nodes receive the selector on their next `up`, `node start`
|
|
62
|
+
or `node puppet`; the owned fact file is verified before recording its revision.
|
|
63
|
+
Unchanged revisions reuse the inventory stamp without extra guest probes. The fact
|
|
64
|
+
file is reserved for Empeira; Puppet should not manage it. Empeira never edits the
|
|
65
|
+
user's hierarchy or adds server-side selection logic. The files can live in the
|
|
66
|
+
normal control repository or existing Hiera mounts; generic repositories need no
|
|
67
|
+
Empeira-specific hierarchy.
|
|
68
|
+
|
|
69
|
+
## External Hiera repositories
|
|
70
|
+
|
|
71
|
+
Configure Puppet-aware mounts in `.empeira.yaml`:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
hiera:
|
|
75
|
+
mounts:
|
|
76
|
+
- source: ../hieradata-register
|
|
77
|
+
type: module
|
|
78
|
+
name: hieradata_register
|
|
79
|
+
- source: ../hieradata-secure
|
|
80
|
+
type: module
|
|
81
|
+
name: hieradata_secure
|
|
82
|
+
- source: ../environment-data
|
|
83
|
+
type: environment
|
|
84
|
+
target: data/external
|
|
85
|
+
required: true
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`module` mounts appear read-only at
|
|
89
|
+
`/etc/puppetlabs/code/environments/<server.environment>/modules/<name>`.
|
|
90
|
+
Names must start with a lowercase letter and contain lowercase letters, digits or
|
|
91
|
+
underscores. `environment` mounts appear at the configured relative `target` below
|
|
92
|
+
the same environment root. Absolute targets, `.`/`..` segments, unsafe mount syntax,
|
|
93
|
+
duplicate targets and overlapping parent/child targets are rejected, including
|
|
94
|
+
collisions across mount types. Existing destination symlinks must stay inside the
|
|
95
|
+
environment. Generic absolute container destinations are not supported.
|
|
96
|
+
|
|
97
|
+
Relative sources resolve against the canonical control-repository root; absolute
|
|
98
|
+
local sources are supported. Existing paths are canonicalized, including macOS
|
|
99
|
+
`/var` symlinks. Sources may live outside the control repository. `required` defaults
|
|
100
|
+
to `false`: missing, inaccessible or dangling optional repositories produce a visible
|
|
101
|
+
warning during `up` and are skipped. `required: true` makes unavailability fatal.
|
|
102
|
+
Existing non-directories, looping symlinks and malformed definitions remain errors.
|
|
103
|
+
An optional mount is not permission to ignore unsafe configuration.
|
|
104
|
+
|
|
105
|
+
Puppet's [default modulepath](https://help.puppet.com/core/current/Content/PuppetCore/config_file_environment.htm)
|
|
106
|
+
includes the environment's `modules` directory. Empeira checks explicit
|
|
107
|
+
`environment.conf` modulepaths and reports a known exclusion before startup. It
|
|
108
|
+
never rewrites that file. Expressions containing unresolved Puppet variables cannot
|
|
109
|
+
be verified completely from the CLI host; ensure the effective server modulepath
|
|
110
|
+
includes the mount destination. Environment mounts can be referenced by ordinary
|
|
111
|
+
relative paths in `hiera.yaml`, such as `data/external` or `external` when the datadir
|
|
112
|
+
is already `data`.
|
|
113
|
+
|
|
114
|
+
All repositories stay live and read-only. Changes inside mounted Hiera repositories
|
|
115
|
+
are visible to the next catalog request with `environment_timeout = 0`, without
|
|
116
|
+
an image rebuild, `up`, or a service restart.
|
|
117
|
+
Empeira neither copies their data nor writes probe files into them. It uses a managed
|
|
118
|
+
environment directory containing links to the read-only control repository so nested
|
|
119
|
+
mount targets can exist without modifying control code. Existing control files and
|
|
120
|
+
linked directories remain live. `up` refreshes links for new control entries under
|
|
121
|
+
projected ancestor directories. EYAML keys remain configured separately in `eyaml`,
|
|
122
|
+
and decryption runs on the server.
|
|
123
|
+
|
|
124
|
+
`config show` includes `effective_hiera_mounts` with resolved destinations and
|
|
125
|
+
`available`/`skipped` states. These are desired mount observations, not a container
|
|
126
|
+
readiness claim. Mount definitions, required flags and source availability affect
|
|
127
|
+
only the server fingerprint; Hiera file contents are not hashed. Run `up` after
|
|
128
|
+
changing mount definitions or making a skipped source available to reconcile the
|
|
129
|
+
server.
|
|
130
|
+
|
|
131
|
+
## Puppetfile modules
|
|
132
|
+
|
|
133
|
+
`empeira update modules` resolves Hiera mounts and synchronizes the root `Puppetfile`.
|
|
134
|
+
Run it explicitly before `up` when required modules have not been installed. `up`
|
|
135
|
+
consumes existing modules without r10k, Forge or Git access and never repairs them.
|
|
136
|
+
An obviously missing module tree fails early with:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
Puppetfile modules are not available.
|
|
140
|
+
Run: empeira update modules
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Without a Puppetfile, the repository's existing module layout continues to work unchanged.
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
hiera:
|
|
147
|
+
mounts:
|
|
148
|
+
- source: ../hieradata
|
|
149
|
+
type: module
|
|
150
|
+
name: hieradata
|
|
151
|
+
required: false
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
When `../hieradata` is available, Empeira uses that local repository and does not
|
|
155
|
+
install the matching Puppetfile module. When the optional path is unavailable,
|
|
156
|
+
Empeira warns and skips its mount. `update modules` installs the Puppetfile version;
|
|
157
|
+
`up` uses that existing fallback or reports missing modules. With
|
|
158
|
+
`required: true`, an unavailable local repository aborts before synchronization;
|
|
159
|
+
there is no fallback. Only available `type: module` entries are overrides.
|
|
160
|
+
`owner-hieradata`, `owner/hieradata` and `hieradata` normalize to the module name
|
|
161
|
+
`hieradata`. Duplicate normalized Puppetfile names are errors, including overrides.
|
|
162
|
+
|
|
163
|
+
The installer uses the pinned [r10k Puppetfile loader](https://github.com/puppetlabs/r10k)
|
|
164
|
+
and its native `module_exclude_regex`, before module synchronization. The Puppetfile
|
|
165
|
+
is evaluated once in the disposable update helper. Its validated installation plan is
|
|
166
|
+
then used for host Git acquisition and r10k synchronization without reevaluation.
|
|
167
|
+
Empeira never rewrites the original Puppetfile. r10k synchronizes modules directly
|
|
168
|
+
into `modules.path`, reusing existing installations and native Git/r10k caches.
|
|
169
|
+
The existing managed environment projection exposes installed modules at the normal
|
|
170
|
+
`/etc/puppetlabs/code/environments/<environment>/modules` path. Parent environment
|
|
171
|
+
mounts precede local Hiera mounts, which stay live and read-only. An explicitly
|
|
172
|
+
excluded `modules` path in `environment.conf` remains an error. Git-tracked module
|
|
173
|
+
contents are protected before synchronization. Undeclared directories in the managed
|
|
174
|
+
path are retained; Empeira does not purge them. Environment mounts overlapping `modules` are
|
|
175
|
+
rejected when a Puppetfile exists; use module mounts for overrides.
|
|
176
|
+
|
|
177
|
+
Git entries support HTTPS/HTTP, `ssh://` URLs and normal SCP-style Git URLs such as
|
|
178
|
+
`git@private-alias:team/profile.git`, with `ref`, `branch`, `tag` or `commit`.
|
|
179
|
+
Without a selector, the acquired remote's HEAD is used. Prefer a full commit ID
|
|
180
|
+
for reproducibility. Forge entries support exact versions and r10k's `:latest`;
|
|
181
|
+
pin versions for reproducibility. Unpinned branches and `:latest` are resolved only
|
|
182
|
+
during synchronization, not on every `up`. Custom
|
|
183
|
+
Forge endpoints use the ordinary Puppetfile `forge` directive. `moduledir` and
|
|
184
|
+
`install_path` must resolve to `modules`; alternate installation trees, SVN, local
|
|
185
|
+
Puppetfile entries, `:control_branch`, embedded HTTP credentials and SSH URL passwords
|
|
186
|
+
are unsupported and fail clearly. An excluded override does not need a usable
|
|
187
|
+
remote or ref. Git source acquisition runs on the host as the invoking user, using
|
|
188
|
+
normal Git/OpenSSH behavior: SSH agent, identities, `~/.ssh/config`, aliases,
|
|
189
|
+
ProxyJump, known hosts and VPN routing. Empeira supplies no SSH flags or replacement
|
|
190
|
+
identity, copies no private keys, and manages no Git credentials. Interactive Git
|
|
191
|
+
retains terminal access for authentication; unattended execution needs an already usable identity/agent.
|
|
192
|
+
Persistent bare Git mirrors are kept in the normal external Empeira state and updated
|
|
193
|
+
incrementally using host Git. The helper reads these mirrors and reuses r10k's native
|
|
194
|
+
cache and working copies; no temporary bundles or fresh module trees are produced.
|
|
195
|
+
Neither SSH sockets nor private keys enter the helper. Empeira disables Git template
|
|
196
|
+
copying when creating mirrors, so user template hooks are not copied.
|
|
197
|
+
|
|
198
|
+
The installer receives a copy of the Puppetfile, not the control repository or host
|
|
199
|
+
SSH configuration: external Ruby includes and host-dependent Puppetfiles are unsupported.
|
|
200
|
+
Puppetfiles remain trusted executable Ruby input. The helper is configured through
|
|
201
|
+
`images.r10k.build: modules/Containerfile`; its reviewed recipe produces
|
|
202
|
+
`localhost/empeira-r10k:<recipe-hash>` and includes Ruby, r10k, Git and CA certificates.
|
|
203
|
+
The obsolete `images.modules` key is rejected.
|
|
204
|
+
|
|
205
|
+
The disposable installer belongs to the update plane. It uses the selected
|
|
206
|
+
runtime's normal bridge network (`bridge` on Docker, `podman` on Podman), with
|
|
207
|
+
normal runtime DNS and external connectivity. It never joins an Empeira workspace
|
|
208
|
+
network and needs neither CoreDNS nor Squid. Workspace `network.egress`, `proxy.enabled`,
|
|
209
|
+
`proxy.global` and `proxy.rules` do not affect
|
|
210
|
+
Forge or Git acquisition. Supplied `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY` and their
|
|
211
|
+
lowercase equivalents are inherited unchanged; Empeira generates no proxy URL.
|
|
212
|
+
The host/runtime's normal network and corporate-proxy configuration must permit
|
|
213
|
+
Forge access, including redirects. Node and service isolation remains unchanged.
|
|
214
|
+
|
|
215
|
+
The helper bind-mounts readonly Puppetfile/request inputs and source mirrors, plus the
|
|
216
|
+
writable `modules.path` and native r10k cache. The caches stay outside the control
|
|
217
|
+
repository in the normal workspace state. It runs with the invoking user's UID/GID
|
|
218
|
+
(Podman uses `keep-id`) and dropped capabilities. Per-invocation ownership and observed
|
|
219
|
+
network membership are verified. Success, failure and interruption remove the owned
|
|
220
|
+
helper where the engine remains reachable; no persistent service or internal DNS
|
|
221
|
+
identity is created. Reviewed image builds contain no control code or credentials.
|
|
222
|
+
|
|
223
|
+
`up` performs a shallow availability check, without evaluating Puppetfile Ruby or
|
|
224
|
+
contacting any source. An existing small external list of module names helps detect
|
|
225
|
+
missing directories and unavailable optional-override fallbacks. Manually populated
|
|
226
|
+
module directories can also be used without this metadata. An explicit successful
|
|
227
|
+
zero-module update permits an empty directory. This is a plausibility check, not a
|
|
228
|
+
version/content check: Puppetfile changes never trigger automatic synchronization.
|
|
229
|
+
Module acquisition has no freshness fingerprints or implicit repair actions. The
|
|
230
|
+
server reloads live code for each catalog with `environment_timeout = 0`; it never
|
|
231
|
+
requests or enforces module synchronization.
|
|
232
|
+
|
|
233
|
+
`empeira update modules` always synchronizes, including moving refs, directly into the
|
|
234
|
+
configured directory. Existing Git repositories are fetched incrementally, and r10k
|
|
235
|
+
reuses installed modules where possible; unchanged Forge releases are not downloaded
|
|
236
|
+
again. Native r10k synchronization may reset local edits to managed modules. Use local
|
|
237
|
+
Hiera mounts for maintained overrides. Updates work before the first `up` and after
|
|
238
|
+
`down` or `destroy`; they do not start services or rewrite infrastructure inventory.
|
|
239
|
+
Both commands use the existing version gate and workspace mutation lock.
|
|
240
|
+
|
|
241
|
+
A running server can see changes immediately through its readonly module mount.
|
|
242
|
+
There is no deployment generation, activation pointer or subsequent `up` requirement
|
|
243
|
+
for module content changes. This is intentional for a disposable local test environment.
|
|
244
|
+
The next catalog request sees the edits, including from agents invoked outside Empeira.
|
|
245
|
+
Empeira does not automatically run Puppet agents. A failed or interrupted update may
|
|
246
|
+
leave partially updated modules visible; there is no rollback. Inspect the reported
|
|
247
|
+
module/ref/version or connectivity error and rerun `update modules`. The installed-name
|
|
248
|
+
list is invalidated before a sync. `up` may consume plausible partial contents;
|
|
249
|
+
it never retries the update. Recovery is an explicit `update modules`.
|
|
250
|
+
|
|
251
|
+
Both `down` and `destroy` retain the actual module directory, native source/r10k caches
|
|
252
|
+
and small installed-name list. The next `up` consumes these existing dependencies without downloading
|
|
253
|
+
again. Module and cache removal is a separate manual action.
|
|
254
|
+
|
|
255
|
+
During synchronization, the existing two-line progress display shows the current
|
|
256
|
+
module name and completed count, for example `profile (14/28)` at 50%.
|
|
257
|
+
The total excludes available local overrides. A module is counted only after its
|
|
258
|
+
complete r10k sync succeeds; Git acquisition displays its name without incrementing
|
|
259
|
+
the counter. An empty effective Puppetfile completes at 100% without division by zero. Local module mounts appear as
|
|
260
|
+
`name (local override)`. Redirected output and CI use the same messages as plain
|
|
261
|
+
lines. Successful Git, SSH, HTTP, Forge and r10k output is buffered and never
|
|
262
|
+
printed as a subprocess transcript. Authentication prompts can still use the
|
|
263
|
+
user's terminal; Empeira does not disable normal Git/SSH authentication.
|
|
264
|
+
|
|
265
|
+
On failure, Empeira reports the module and bounded, filtered diagnostic lines for
|
|
266
|
+
authentication, DNS, HTTP, versions and refs. Commands, authorization headers,
|
|
267
|
+
private key material, filesystem paths and credential-bearing URLs are suppressed
|
|
268
|
+
or redacted. A failed module is not counted, and failure never emits a successful
|
|
269
|
+
completion event. Check the reported
|
|
270
|
+
cause before retrying; raw successful subprocess logs are not part of normal output.
|
|
271
|
+
|
|
272
|
+
`modules.path` is the actual module directory, relative to the canonical control
|
|
273
|
+
repository root unless absolute. The default:
|
|
274
|
+
|
|
275
|
+
```yaml
|
|
276
|
+
modules:
|
|
277
|
+
path: modules
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
produces a flat installation:
|
|
281
|
+
|
|
282
|
+
```text
|
|
283
|
+
<control-repo>/modules/
|
|
284
|
+
├── stdlib/
|
|
285
|
+
├── concat/
|
|
286
|
+
└── profile/
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
`path: ../puppet-modules` instead installs directly into that sibling directory.
|
|
290
|
+
There are no `.empeira`, workspace or generation subdirectories beneath the module
|
|
291
|
+
path. Internal metadata and caches stay in the platform workspace state. The server
|
|
292
|
+
sees the configured directory at its normal environment `modules/<name>` path.
|
|
293
|
+
Available local Hiera overrides are mounted over destination directories in that
|
|
294
|
+
tree (created empty if missing); their source remains live and readonly. Changing `modules.path` requires
|
|
295
|
+
`up` to change the server mount, but does not delete the previous directory.
|
|
296
|
+
Old generation directories from development versions are neither adopted nor deleted
|
|
297
|
+
automatically; they can be removed manually after the old infrastructure is torn down.
|
|
298
|
+
|
|
299
|
+
If the path is inside the canonical control repository, Empeira checks it with Git
|
|
300
|
+
before synchronization. Git-tracked contents anywhere under that path are a hard
|
|
301
|
+
error before changing module output. For an untracked path
|
|
302
|
+
not covered by Git's ignore rules, Empeira prints one repository-relative
|
|
303
|
+
recommendation per command and continues. It never edits `.gitignore`. Nested
|
|
304
|
+
ignore files, `.git/info/exclude` and configured global excludes are respected.
|
|
305
|
+
An external module directory needs no Git-ignore recommendation.
|
|
306
|
+
|
|
307
|
+
With the default path, the recommendation is:
|
|
308
|
+
|
|
309
|
+
```text
|
|
310
|
+
Recommendation: modules/ is not ignored by Git. Add /modules/ to .gitignore.
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
If the repository already tracks vendored modules there, select a different
|
|
314
|
+
`modules.path`; tracked files are never overwritten or deleted by synchronization.
|
|
315
|
+
|
|
316
|
+
## EYAML
|
|
317
|
+
|
|
318
|
+
Enable server-side PKCS7 keys explicitly in `.empeira.yaml`:
|
|
319
|
+
|
|
320
|
+
```yaml
|
|
321
|
+
eyaml:
|
|
322
|
+
enabled: true
|
|
323
|
+
private_key: secrets/private_key.pkcs7.pem
|
|
324
|
+
public_key: secrets/public_key.pkcs7.pem
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Relative paths resolve against the canonical project root. Absolute paths are also
|
|
328
|
+
supported. Both must resolve to readable regular files. The private key is a PEM
|
|
329
|
+
RSA private key for PKCS7 and the public file is its PEM X.509 certificate, as generated
|
|
330
|
+
by `eyaml createkeys`. Keep keys outside version control. Empeira neither generates
|
|
331
|
+
nor copies these keys into the repository, inventory or images. It mounts the files
|
|
332
|
+
read-only, exclusively in the configuration server. OpenVox mounts them directly;
|
|
333
|
+
the Puppet Server image changes ownership recursively under `/etc/puppetlabs/puppet`
|
|
334
|
+
at startup, so Empeira mounts its sources outside that tree and stages the keys in
|
|
335
|
+
a container-local tmpfs. Both providers expose the keys to Hiera at:
|
|
336
|
+
|
|
337
|
+
- `/etc/puppetlabs/puppet/eyaml/private_key.pkcs7.pem`
|
|
338
|
+
- `/etc/puppetlabs/puppet/eyaml/public_key.pkcs7.pem`
|
|
339
|
+
|
|
340
|
+
Point the existing control repository's `hiera.yaml` at these paths, for example:
|
|
341
|
+
|
|
342
|
+
```yaml
|
|
343
|
+
version: 5
|
|
344
|
+
hierarchy:
|
|
345
|
+
- name: Encrypted common data
|
|
346
|
+
lookup_key: eyaml_lookup_key
|
|
347
|
+
path: common.eyaml
|
|
348
|
+
options:
|
|
349
|
+
pkcs7_private_key: /etc/puppetlabs/puppet/eyaml/private_key.pkcs7.pem
|
|
350
|
+
pkcs7_public_key: /etc/puppetlabs/puppet/eyaml/public_key.pkcs7.pem
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
The server's JRuby environment must include `hiera-eyaml` (the default OpenVox
|
|
354
|
+
image includes it). The runtime must expose the source files through its UID
|
|
355
|
+
mapping and shared filesystem. Empeira verifies engine visibility
|
|
356
|
+
without printing file contents. It does not detect EYAML usage automatically or
|
|
357
|
+
rewrite `hiera.yaml`. `config show` redacts the private-key path under the existing secret-redaction
|
|
358
|
+
model and never displays key contents.
|
|
359
|
+
For Puppet Server, run `empeira up` after changing a key file to refresh the
|
|
360
|
+
container-local tmpfs copy without recreating the server.
|
|
361
|
+
EYAML is disabled by default.
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
Empeira runs natively on Linux and macOS. Windows uses **WSL2 → Linux → Empeira**;
|
|
4
|
+
native Windows Ruby is unsupported. The gemspec requires **Ruby >= 3.4**; the
|
|
5
|
+
supported Ruby versions are **3.4 and 4.0**. Normal CI tests both on Ubuntu;
|
|
6
|
+
release gems are built with Ruby 3.4. Use source installation until a release gem
|
|
7
|
+
is available. No RubyGems.org publication is assumed.
|
|
8
|
+
|
|
9
|
+
## Linux and WSL2
|
|
10
|
+
|
|
11
|
+
These commands target **Ubuntu 24.04 LTS** and **Debian 13 trixie**. Their default
|
|
12
|
+
Ruby packages are below Empeira's minimum; Ruby 3.2 and 3.3 are unsupported.
|
|
13
|
+
Install Ruby 3.4+ with your established Ruby version manager before using Empeira.
|
|
14
|
+
Ubuntu 22.04 and Debian 12 also need a newer Ruby. Installing the distribution's
|
|
15
|
+
default `ruby` package does not satisfy the gemspec on these hosts.
|
|
16
|
+
|
|
17
|
+
Core/source development dependencies and SSH access:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
sudo apt-get update
|
|
21
|
+
sudo apt-get install -y git build-essential openssh-client iproute2
|
|
22
|
+
# Activate Ruby 3.4+ using your Ruby version manager before continuing.
|
|
23
|
+
gem install bundler
|
|
24
|
+
ruby --version
|
|
25
|
+
gem --version
|
|
26
|
+
bundle --version
|
|
27
|
+
git --version
|
|
28
|
+
ssh -V
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The selected Ruby installation must supply `gem` and matching development headers;
|
|
32
|
+
`gem install bundler` supplies `bundle`. `build-essential` builds native development
|
|
33
|
+
gems; additional Ruby build prerequisites depend on your version manager.
|
|
34
|
+
`openssh-client` supplies `ssh` and `ssh-keygen` for regular node SSH. VM management
|
|
35
|
+
uses private VirtIO-Serial and Python 3 already present in the selected cloud image.
|
|
36
|
+
`iproute2` supplies host route inspection for automatic workspace subnet allocation. Coreutils supplies
|
|
37
|
+
`tail` for VM logs; Bash supplies optional completion. Both are standard on these
|
|
38
|
+
hosts. Downloads use Ruby libraries; Empeira does not invoke host curl/wget.
|
|
39
|
+
|
|
40
|
+
Default runtime (Podman with Netavark):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
sudo apt-get install -y podman netavark
|
|
44
|
+
podman --version
|
|
45
|
+
podman info --format '{{.Host.NetworkBackend}}'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The backend must be `netavark`. Run Empeira as your normal user with rootless
|
|
49
|
+
Podman; do not mix rootful and rootless inventories.
|
|
50
|
+
|
|
51
|
+
Docker alternative: use **Docker Engine >= 28** with the Linux bridge driver.
|
|
52
|
+
Ubuntu 24.04's and Debian 13's distribution `docker.io` packages are too old for isolated gateway mode.
|
|
53
|
+
The following uses Docker's official apt repository on Ubuntu or Debian; it
|
|
54
|
+
assumes conflicting distribution Docker packages have already been removed as
|
|
55
|
+
specified by the upstream guide:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
sudo apt-get install -y ca-certificates curl
|
|
59
|
+
sudo install -m 0755 -d /etc/apt/keyrings
|
|
60
|
+
. /etc/os-release
|
|
61
|
+
curl -fsSL "https://download.docker.com/linux/$ID/gpg" | sudo tee /etc/apt/keyrings/docker.asc >/dev/null
|
|
62
|
+
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
|
63
|
+
printf 'deb [arch=%s signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/%s %s stable\n' \
|
|
64
|
+
"$(dpkg --print-architecture)" "$ID" "${UBUNTU_CODENAME:-$VERSION_CODENAME}" |
|
|
65
|
+
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
|
|
66
|
+
sudo apt-get update
|
|
67
|
+
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin
|
|
68
|
+
sudo systemctl enable --now docker
|
|
69
|
+
sudo usermod -aG docker "$USER"
|
|
70
|
+
# Start a new login session before continuing. Docker group access controls the engine.
|
|
71
|
+
docker --version
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Set `runtime.container_engine: docker` in `.empeira.yaml`, or use
|
|
75
|
+
`--container-engine docker`. WSL2 can instead use Docker Desktop's WSL integration
|
|
76
|
+
with a Linux engine >= 28; do not install a competing daemon in that distribution.
|
|
77
|
+
|
|
78
|
+
### VM prerequisites
|
|
79
|
+
|
|
80
|
+
Optional packages, only for VM users:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# amd64 host:
|
|
84
|
+
sudo apt-get install -y qemu-system-x86 qemu-utils xorriso openssh-client
|
|
85
|
+
qemu-system-x86_64 --version
|
|
86
|
+
|
|
87
|
+
# arm64 host instead:
|
|
88
|
+
sudo apt-get install -y qemu-system-arm qemu-efi-aarch64 qemu-utils xorriso openssh-client
|
|
89
|
+
qemu-system-aarch64 --version
|
|
90
|
+
|
|
91
|
+
# Both architectures:
|
|
92
|
+
qemu-img --version
|
|
93
|
+
xorriso -version
|
|
94
|
+
ssh -V
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`qemu-utils` supplies `qemu-img`. AArch64 requires the `qemu-efi-aarch64` firmware;
|
|
98
|
+
x86_64 uses QEMU's default firmware. Linux VM creation requires usable KVM:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
ls -l /dev/kvm
|
|
102
|
+
id
|
|
103
|
+
# If /dev/kvm belongs to group kvm and your account lacks access:
|
|
104
|
+
sudo usermod -aG kvm "$USER"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Start a new login session after a group change. The device must exist, permit
|
|
108
|
+
read/write access and support the KVM API; group membership alone is insufficient.
|
|
109
|
+
Empeira reports ioctl failures and never silently falls back to TCG.
|
|
110
|
+
|
|
111
|
+
### WSL2 specifics
|
|
112
|
+
|
|
113
|
+
Use the Linux commands above inside an Ubuntu 24.04 or Debian 13 WSL2 distribution,
|
|
114
|
+
with source/control checkouts on its Linux filesystem. KVM is unnecessary for
|
|
115
|
+
container-only use. VM use requires `/dev/kvm` and functional nested virtualization;
|
|
116
|
+
check `ls -l /dev/kvm` and apply the group/access remediation above if appropriate.
|
|
117
|
+
After group changes, run this **from Windows PowerShell**, then reopen WSL:
|
|
118
|
+
|
|
119
|
+
```powershell
|
|
120
|
+
wsl --shutdown
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
A missing KVM device requires a compatible Windows/WSL kernel and virtualization
|
|
124
|
+
configuration; adding a group cannot create acceleration. WSL mirrored networking
|
|
125
|
+
is not a prerequisite. Windows-host QEMU/WHPX is not currently implemented.
|
|
126
|
+
|
|
127
|
+
## macOS with Homebrew
|
|
128
|
+
|
|
129
|
+
Install Homebrew using its [official instructions](https://brew.sh/), then core:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
brew install git ruby@3.4 openssh
|
|
133
|
+
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
|
+
ruby --version
|
|
137
|
+
gem --version
|
|
138
|
+
bundle --version
|
|
139
|
+
git --version
|
|
140
|
+
ssh -V
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Keep those PATH settings in your shell configuration if desired. Apple’s system
|
|
144
|
+
Ruby is not suitable. Ruby 3.4 is the recommended development version. macOS supplies `scutil` for host/split DNS discovery and `tail` for logs.
|
|
145
|
+
|
|
146
|
+
Default runtime:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
brew install podman
|
|
150
|
+
podman machine init
|
|
151
|
+
podman machine start
|
|
152
|
+
podman --version
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Podman runs Linux containers in its managed Linux VM. Run `machine init` only once.
|
|
156
|
+
The engine must use Netavark and see the control repository and Empeira state bind
|
|
157
|
+
mounts. Configure machine sharing for paths outside its normal shared directories.
|
|
158
|
+
|
|
159
|
+
Docker alternative:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
brew install --cask docker-desktop
|
|
163
|
+
open -a Docker
|
|
164
|
+
docker --version
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Wait for Docker Desktop to start, use its Linux engine >= 28, and select Docker in
|
|
168
|
+
Empeira configuration. Docker Desktop has its own distribution/license terms; it
|
|
169
|
+
is not bundled with Empeira. The CLI host and engine must agree on mount paths.
|
|
170
|
+
|
|
171
|
+
Optional VM tools:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
brew install qemu xorriso
|
|
175
|
+
qemu-img --version
|
|
176
|
+
xorriso -version
|
|
177
|
+
# Apple Silicon:
|
|
178
|
+
qemu-system-aarch64 --version
|
|
179
|
+
qemu-system-aarch64 -accel help
|
|
180
|
+
# Intel instead:
|
|
181
|
+
qemu-system-x86_64 --version
|
|
182
|
+
qemu-system-x86_64 -accel help
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Homebrew QEMU provides its firmware. **HVF** is the expected accelerator; Empeira
|
|
186
|
+
fails if unavailable. Real macOS/HVF VM E2E, macOS container engine integration,
|
|
187
|
+
and arm64 browser/runtime E2E remain separate manual gates. Lightweight CI does
|
|
188
|
+
not establish those results. See the [VM validation gates](development.md#vm-and-shared-network-prerequisites).
|
|
189
|
+
|
|
190
|
+
## Source installation and project opt-in
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
git clone https://github.com/c8m6/empeira.git
|
|
194
|
+
cd empeira
|
|
195
|
+
bundle config set --local path vendor/bundle
|
|
196
|
+
bundle install
|
|
197
|
+
export EMPEIRA_SOURCE="$PWD"
|
|
198
|
+
empeira() { BUNDLE_GEMFILE="$EMPEIRA_SOURCE/Gemfile" bundle exec ruby "$EMPEIRA_SOURCE/bin/empeira" "$@"; }
|
|
199
|
+
empeira --version
|
|
200
|
+
empeira help
|
|
201
|
+
cd ../control-repo
|
|
202
|
+
touch .empeira.yaml
|
|
203
|
+
empeira config validate
|
|
204
|
+
empeira update modules # only when the project uses a Puppetfile
|
|
205
|
+
empeira up
|
|
206
|
+
empeira browser
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The control repository must already be a Git repository. Project commands resolve
|
|
210
|
+
`git rev-parse --show-toplevel` through the execution runner and require an actual
|
|
211
|
+
`.empeira.yaml` at that canonical root. An empty file uses defaults. Subdirectory
|
|
212
|
+
invocation and paths with spaces work. No Puppet-file heuristic or `--project`
|
|
213
|
+
selector exists. The source shell function preserves the current directory.
|
|
214
|
+
Version/help/self-update work outside Git (self-update currently reports unavailable).
|
|
215
|
+
|
|
216
|
+
## Release gem installation
|
|
217
|
+
|
|
218
|
+
Download the `.gem` asset from a [GitHub release](https://github.com/c8m6/empeira/releases)
|
|
219
|
+
when one is available, then install it with your existing Ruby environment:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
gem install --user-install ./empeira-VERSION.gem
|
|
223
|
+
export PATH="$(ruby -r rubygems -e 'puts Gem.user_dir')/bin:$PATH"
|
|
224
|
+
empeira --version
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Replace `VERSION` with the downloaded asset's filename. RubyGems installs the Thor
|
|
228
|
+
runtime dependency; no third-party agents, images or binaries are bundled. The
|
|
229
|
+
release version is embedded in BuildInfo. Standalone binaries and automatic
|
|
230
|
+
self-update are unavailable. Do not use `sudo gem install` for normal operation.
|
|
231
|
+
|
|
232
|
+
For other Linux distributions, install equivalent Ruby/Git/runtime packages through
|
|
233
|
+
your established host setup. Guest OS support does not imply a tested host recipe.
|
|
234
|
+
Report native Linux, WSL2, macOS and runtime/architecture validation separately.
|
|
235
|
+
|
|
236
|
+
## Bash completion
|
|
237
|
+
|
|
238
|
+
For an installed executable or the source function above in Bash:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
source <(empeira completion bash)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Completion includes browser, additional lifecycle commands, node names from
|
|
245
|
+
inventory, configured OS versions, providers and runtime values. Both spaced and
|
|
246
|
+
`--provider=con` forms work, including Bash's split `=` tokens. Project-dependent
|
|
247
|
+
completion uses the current Git repository and returns no project candidates outside
|
|
248
|
+
one. It never probes a runtime. No shell configuration is changed automatically.
|
|
249
|
+
|
|
250
|
+
## Installation references
|
|
251
|
+
|
|
252
|
+
Upstream installation references:
|
|
253
|
+
[Ubuntu noble indexes](https://archive.ubuntu.com/ubuntu/dists/noble/),
|
|
254
|
+
[Debian trixie index](https://deb.debian.org/debian/dists/trixie/main/),
|
|
255
|
+
[Docker Ubuntu](https://docs.docker.com/engine/install/ubuntu/),
|
|
256
|
+
[Docker Debian](https://docs.docker.com/engine/install/debian/),
|
|
257
|
+
[Homebrew Ruby 3.4](https://formulae.brew.sh/formula/ruby@3.4),
|
|
258
|
+
[Podman](https://formulae.brew.sh/formula/podman),
|
|
259
|
+
[QEMU](https://formulae.brew.sh/formula/qemu),
|
|
260
|
+
[xorriso](https://formulae.brew.sh/formula/xorriso),
|
|
261
|
+
[OpenSSH](https://formulae.brew.sh/formula/openssh),
|
|
262
|
+
[Docker Desktop](https://formulae.brew.sh/cask/docker-desktop).
|
|
263
|
+
|
|
264
|
+
### Peer networking prerequisites
|
|
265
|
+
|
|
266
|
+
Linux/WSL2 subnet allocation requires iproute2 even for container-only use.
|
|
267
|
+
Native rootless Podman VM networking also requires Netavark,
|
|
268
|
+
user namespaces, `/dev/net/tun`, and KVM access inside the rootless namespace:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
podman --remote=false unshare --rootless-netns test -w /dev/net/tun
|
|
272
|
+
podman --remote=false unshare --rootless-netns test -w /dev/kvm
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Normal operation does not use sudo. Device/ACL setup is an administrator's one-time
|
|
276
|
+
host task. Linux Docker uses the owned packet-helper model and requires its engine
|
|
277
|
+
to support `/dev/net/tun` and `NET_ADMIN` for that helper. macOS uses QEMU/HVF plus
|
|
278
|
+
rootless Podman Machine or Docker Desktop, with the canonical state directory
|
|
279
|
+
shared where needed. The runtime builds the packaged static adapter; **Go is not
|
|
280
|
+
a normal Empeira prerequisite**. IPv4 is the supported peer protocol initially.
|