empeira 0.1.0.pre.alpha.3 → 0.1.0.pre.alpha.4
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 +2 -2
- data/docs/architecture.md +6 -3
- data/docs/configuration.md +16 -11
- data/docs/development.md +5 -3
- data/docs/hiera-and-eyaml.md +4 -2
- data/docs/nodes.md +10 -6
- data/docs/troubleshooting.md +16 -5
- data/lib/empeira/agent/native_commands.rb +3 -3
- data/lib/empeira/build.json +3 -3
- data/lib/empeira/control_plane/controller.rb +4 -3
- data/lib/empeira/control_plane/environment.rb +25 -5
- data/lib/empeira/server/environment_configuration.rb +8 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4e4e7094658b9e3d8f4ee0edbafa3e4e45be28921900cce8eb4af7d66096cee6
|
|
4
|
+
data.tar.gz: 7f062dc35a9cef14ad52f55362beba6c4a5a0ab1b57225ce27a191123dc01fc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8410139aeffa1ccaab90f3ddac57a809a86420e385f1354f801f8181c936ecf5653762cc4dbade0178d6df99b2dad1cc8b68cb8d537013132ec09e2ed65aefa1
|
|
7
|
+
data.tar.gz: 52ba2b37546bc90263d9834193b5080440e2a66425c9f9403b19800e791bf5f26b895d4c4e1af4bc218951b3a0e433437c07c550f493f4577e4e8dfd156a06bb
|
data/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://github.com/c8m6/empeira/actions/workflows/openvox.yml)
|
|
7
7
|
[](https://github.com/c8m6/empeira/releases)
|
|
8
8
|
[](docs/installation.md)
|
|
9
|
-
[](LICENSE)
|
|
10
10
|
|
|
11
11
|
**ἐμπειρία (empeiría)** — experience gained through practice. The name reflects
|
|
12
12
|
learning about infrastructure by experimenting, testing and seeing what happens.
|
|
@@ -149,6 +149,6 @@ and [pull requests](https://github.com/c8m6/empeira/pulls) are welcome. Follow t
|
|
|
149
149
|
[security policy](SECURITY.md).
|
|
150
150
|
|
|
151
151
|
Project-owned code and documentation are licensed under
|
|
152
|
-
[AGPL-3.0-
|
|
152
|
+
[AGPL-3.0-or-later](LICENSE). Third-party packages and images retain their own licenses
|
|
153
153
|
and notices and are obtained from upstream; empeira does not bundle them or
|
|
154
154
|
redistribute proprietary Puppet Enterprise software.
|
data/docs/architecture.md
CHANGED
|
@@ -184,9 +184,12 @@ there are no implicit database-major migrations or automatic node replacements.
|
|
|
184
184
|
|
|
185
185
|
Managed servers disable environment caching through native Puppet configuration
|
|
186
186
|
(`environment_timeout = 0` in `[server]`), applied by the startup wrapper before
|
|
187
|
-
the configured image entrypoint. `
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
the configured image entrypoint. An independent `environment.conf` copy in the
|
|
188
|
+
managed environment enforces zero even when the control repository specifies
|
|
189
|
+
`unlimited`; the original remains unchanged and read-only. `up` refreshes the copy,
|
|
190
|
+
checks both native and selected-environment settings, and restarts only a server
|
|
191
|
+
whose native setting changed. It preserves every other configuration key and
|
|
192
|
+
retained storage. The configured Puppet confdir must agree with Puppetserver
|
|
190
193
|
HOCON `master-conf-dir`. Catalog
|
|
191
194
|
requests reload live code without repository hashes or environment-cache checkpoints.
|
|
192
195
|
See [nodes](nodes.md#environment-cache-and-live-code).
|
data/docs/configuration.md
CHANGED
|
@@ -404,20 +404,25 @@ runtime values without inferring them from the image name. Missing or unsafe
|
|
|
404
404
|
runtime fields fail configuration validation. Managed servers use
|
|
405
405
|
`environment_timeout = 0` in the native `[server]` section. The startup wrapper
|
|
406
406
|
uses `puppet config set` before the configured entrypoint, independently of image
|
|
407
|
-
environment-variable mappings.
|
|
408
|
-
|
|
409
|
-
|
|
407
|
+
environment-variable mappings. Empeira also prepares an independent copy of the
|
|
408
|
+
project's `environment.conf` in its managed environment directory, replacing or
|
|
409
|
+
adding only `environment_timeout = 0`. Other settings, including `modulepath` and
|
|
410
|
+
`config_version`, are preserved. The original file and the control repository
|
|
411
|
+
remain read-only in the server. The copy is refreshed during `up`, including when
|
|
412
|
+
the project has no `environment.conf` or Hiera mounts.
|
|
413
|
+
|
|
414
|
+
`up` verifies both the native server setting and the effective timeout for
|
|
415
|
+
`server.environment`, against the confdir containing
|
|
416
|
+
`server.runtime.paths.puppetdb_config`; custom Puppetserver
|
|
410
417
|
`jruby-puppet.master-conf-dir` must refer to that same directory. Puppetserver
|
|
411
|
-
HOCON master directories take precedence over Puppet CLI defaults.
|
|
412
|
-
|
|
418
|
+
HOCON master directories take precedence over Puppet CLI defaults. Native setting
|
|
419
|
+
drift updates only that key and restarts the same owned server; an
|
|
413
420
|
entrypoint that overwrites it fails verification. CA, SSL and database storage
|
|
414
421
|
are preserved. The next catalog request reloads live code without
|
|
415
|
-
an Empeira content scan or admin API invalidation.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
selected environment's override, so it can report `unlimited` while the native
|
|
420
|
-
server setting is zero. Inspect both configuration layers when diagnosing caching.
|
|
422
|
+
an Empeira content scan or admin API invalidation. A project timeout of `unlimited`
|
|
423
|
+
therefore stays unchanged in the checkout while the managed server uses zero.
|
|
424
|
+
To verify it, run `puppet config print environment_timeout --section server
|
|
425
|
+
--environment ENVIRONMENT` inside the server with the configured environment name.
|
|
421
426
|
|
|
422
427
|
`puppetdb.runtime` holds the independent OpenVoxDB process contract. Custom
|
|
423
428
|
images may override its executable, numeric user, Java and main arguments,
|
data/docs/development.md
CHANGED
|
@@ -253,6 +253,7 @@ The APT authentication regression uses a local HTTPS repository with synthetic B
|
|
|
253
253
|
credentials and an ephemeral GPG signing key. It checks the helper's effective
|
|
254
254
|
`auth.conf.d` configuration, private file mode and exact credential bytes, then
|
|
255
255
|
verifies metadata returns 401 before one interactive login and 200 after the retry.
|
|
256
|
+
The fixture omits the 401 reason phrase to exercise APT's bare status/IP diagnostic.
|
|
256
257
|
The selected package download must reuse that login and pass its SHA-256 check.
|
|
257
258
|
It requires host `gpg`/`gpgconf` and a locally reachable container engine; helper and
|
|
258
259
|
host TLS verification remain enabled. Run it explicitly for either engine:
|
|
@@ -511,9 +512,10 @@ Run `EMPEIRA_INTEGRATION=server-environment bundle exec rspec spec/integration/s
|
|
|
511
512
|
to check native timeout 0, live edits, CA retention, PuppetDB and idempotent up
|
|
512
513
|
under Docker/rootless Podman with the default server and a custom entrypoint
|
|
513
514
|
that ignores timeout environment mapping.
|
|
514
|
-
The same gate verifies
|
|
515
|
-
|
|
516
|
-
|
|
515
|
+
The same gate verifies that an explicit `environment.conf` timeout of `unlimited`
|
|
516
|
+
is zero in the managed copy while the original stays unchanged. It edits a Ruby
|
|
517
|
+
Puppet function between catalogs and checks the changed result without `up` or a
|
|
518
|
+
restart, followed by an idempotent `up`.
|
|
517
519
|
|
|
518
520
|
Run the isolated diagnostics/recovery gate with each native runtime:
|
|
519
521
|
|
data/docs/hiera-and-eyaml.md
CHANGED
|
@@ -105,7 +105,8 @@ An optional mount is not permission to ignore unsafe configuration.
|
|
|
105
105
|
Puppet's [default modulepath](https://help.puppet.com/core/current/Content/PuppetCore/config_file_environment.htm)
|
|
106
106
|
includes the environment's `modules` directory. Empeira checks explicit
|
|
107
107
|
`environment.conf` modulepaths and reports a known exclusion before startup. It
|
|
108
|
-
never rewrites
|
|
108
|
+
never rewrites the original file. Its managed copy changes only
|
|
109
|
+
`environment_timeout` to zero. Expressions containing unresolved Puppet variables cannot
|
|
109
110
|
be verified completely from the CLI host; ensure the effective server modulepath
|
|
110
111
|
includes the mount destination. Environment mounts can be referenced by ordinary
|
|
111
112
|
relative paths in `hiera.yaml`, such as `data/external` or `external` when the datadir
|
|
@@ -117,7 +118,8 @@ an image rebuild, `up`, or a service restart.
|
|
|
117
118
|
Empeira neither copies their data nor writes probe files into them. It uses a managed
|
|
118
119
|
environment directory containing links to the read-only control repository so nested
|
|
119
120
|
mount targets can exist without modifying control code. Existing control files and
|
|
120
|
-
linked directories remain live
|
|
121
|
+
linked directories remain live; `environment.conf` is an independent copy refreshed
|
|
122
|
+
by `up`. `up` also refreshes links for new top-level control entries and entries under
|
|
121
123
|
projected ancestor directories. EYAML keys remain configured separately in `eyaml`,
|
|
122
124
|
and decryption runs on the server.
|
|
123
125
|
|
data/docs/nodes.md
CHANGED
|
@@ -87,18 +87,22 @@ Managed servers enforce native `[server] environment_timeout = 0` before startup
|
|
|
87
87
|
and verify the effective setting during `up`, independently of image environment
|
|
88
88
|
variable support. Existing workspaces adopt it on
|
|
89
89
|
their next `up`; run that once after updating from a version that enabled caching.
|
|
90
|
+
Adopting the managed environment copy changes the server mount and recreates its
|
|
91
|
+
container once, retaining CA, SSL and database storage.
|
|
90
92
|
Each catalog request reloads live control code, modules and mounted Hiera data.
|
|
91
93
|
Empeira does not hash these trees,
|
|
92
94
|
persist content checkpoints or call the environment-cache admin API. Code edits
|
|
93
95
|
need neither `up` nor a server restart, including for agents invoked manually.
|
|
94
96
|
Empeira does not enable `use_cached_catalog`.
|
|
95
97
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
Empeira copies `environment.conf` into its managed environment and sets its timeout
|
|
99
|
+
to zero there, preserving all other settings and the original file. Run `up` to
|
|
100
|
+
refresh this copy after editing other environment settings. Avoid concurrent edits
|
|
101
|
+
during a catalog run. Existing files and directories stay live through read-only
|
|
102
|
+
links. New top-level entries and new siblings under ancestors projected for nested
|
|
103
|
+
Hiera mounts require `up` to create their links. `node start` resumes the node
|
|
104
|
+
without invoking Puppet; Puppet services enabled by a catalog may run independently
|
|
105
|
+
on startup.
|
|
102
106
|
|
|
103
107
|
## Distribution package sources
|
|
104
108
|
|
data/docs/troubleshooting.md
CHANGED
|
@@ -33,6 +33,14 @@ HTTP 403 does not trigger login, and HTTP 407 identifies proxy authentication. R
|
|
|
33
33
|
authentication continues to use native `docker login` / `podman login` and the reported
|
|
34
34
|
registry host; Empeira does not log into registries automatically.
|
|
35
35
|
|
|
36
|
+
APT can report an HTTP status without a reason phrase, for example
|
|
37
|
+
`401 [IP: 192.0.2.1 443]`. This still triggers the single repository login attempt
|
|
38
|
+
when no ENV credentials are set and both standard input and standard error are
|
|
39
|
+
connected to a TTY. The corresponding `403` and `407` forms retain their access-denied
|
|
40
|
+
and proxy-authentication diagnoses without prompting. A node retained as `incomplete`
|
|
41
|
+
after an acquisition failure must be destroyed with `empeira node destroy HOSTNAME`
|
|
42
|
+
and recreated with the original `empeira node run` arguments after resolving the cause.
|
|
43
|
+
|
|
36
44
|
APT helper credentials use literal `login` and `password` tokens in a temporary
|
|
37
45
|
0600 file under `/etc/apt/auth.conf.d`. APT treats surrounding quotes and added
|
|
38
46
|
backslashes as credential bytes, so Empeira does not add them. A successful login
|
|
@@ -140,11 +148,14 @@ problem. A successful probe with different directory listings indicates a
|
|
|
140
148
|
different engine view of the source. Empeira does not weaken mount checks or
|
|
141
149
|
change host permissions automatically.
|
|
142
150
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
Empeira enforces `environment_timeout = 0` in both the native server setting and
|
|
152
|
+
its independent copy of `environment.conf`. The project's original file remains
|
|
153
|
+
unchanged, even when it specifies `unlimited`. Run `up` after updating Empeira or
|
|
154
|
+
editing other settings in `environment.conf` to refresh the managed copy. Inside
|
|
155
|
+
the server, `puppet config print environment_timeout --section server --environment
|
|
156
|
+
ENVIRONMENT` must report `0` for the configured environment. A different value
|
|
157
|
+
fails startup verification; check the custom server's confdir and environmentpath.
|
|
158
|
+
No explicit cache invalidation is performed.
|
|
148
159
|
|
|
149
160
|
`config show` includes `effective_hiera_mounts`. A skipped optional source is
|
|
150
161
|
reported during `up`; mount it locally or correct the source path, then run `up`
|
|
@@ -39,11 +39,11 @@ module Empeira
|
|
|
39
39
|
diagnostic = Execution::Diagnostics.native(result.with(stderr: text, stdout: ''),
|
|
40
40
|
operation: "Agent #{operation}", tool: arguments.first)
|
|
41
41
|
case text
|
|
42
|
-
when /407\s+Proxy Authentication Required|(?:HTTP|Status code|HTTP code)\s*:?\s*407\b
|
|
42
|
+
when /407\s+Proxy Authentication Required|(?:HTTP|Status code|HTTP code)\s*:?\s*407\b|\b407[ \t]+\[IP:/i
|
|
43
43
|
raise Error, "Host helper proxy authentication failed\n#{diagnostic}", cause: nil
|
|
44
|
-
when /401\s+Unauthorized|(?:HTTP|Status code|HTTP code)\s*:?\s*401\b
|
|
44
|
+
when /401\s+Unauthorized|(?:HTTP|Status code|HTTP code)\s*:?\s*401\b|\b401[ \t]+\[IP:/i
|
|
45
45
|
raise Agent::AuthenticationRequired, diagnostic, cause: nil
|
|
46
|
-
when /403\s+Forbidden|(?:HTTP|Status code|HTTP code)\s*:?\s*403\b
|
|
46
|
+
when /403\s+Forbidden|(?:HTTP|Status code|HTTP code)\s*:?\s*403\b|\b403[ \t]+\[IP:/i
|
|
47
47
|
raise Error, "Agent repository access denied\n#{diagnostic}", cause: nil
|
|
48
48
|
end
|
|
49
49
|
raise Error, "Agent #{operation} failed\n#{diagnostic}", cause: nil
|
data/lib/empeira/build.json
CHANGED
|
@@ -350,10 +350,11 @@ module Empeira
|
|
|
350
350
|
|
|
351
351
|
def reconcile_server_environment
|
|
352
352
|
environment = Server::EnvironmentConfiguration.new(runtime: @runtime, plan: @plan)
|
|
353
|
-
|
|
353
|
+
if environment.reconcile(@observed.fetch('server'))
|
|
354
|
+
@changed = true
|
|
355
|
+
@health.wait('server', @observed)
|
|
356
|
+
end
|
|
354
357
|
|
|
355
|
-
@changed = true
|
|
356
|
-
@health.wait('server', @observed)
|
|
357
358
|
environment.verify!(@observed.fetch('server'))
|
|
358
359
|
end
|
|
359
360
|
|
|
@@ -9,7 +9,7 @@ module Empeira
|
|
|
9
9
|
def initialize(context:, hiera:)
|
|
10
10
|
@project = context.project.path
|
|
11
11
|
@root = root(context)
|
|
12
|
-
@targets = mount_targets(hiera)
|
|
12
|
+
@targets = ['environment.conf', *mount_targets(hiera)]
|
|
13
13
|
@modules = Modules::Storage.new(context: context).root if @project.join('Puppetfile').file?
|
|
14
14
|
@targets |= ['modules'] if @modules
|
|
15
15
|
@base = context.locations.workspace(context.workspace).join('environments')
|
|
@@ -17,14 +17,11 @@ module Empeira
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def mounts
|
|
20
|
-
return [bind(@project, @root)] if @targets.empty?
|
|
21
|
-
|
|
22
20
|
[bind(@project, CONTROL), bind(@directory, @root),
|
|
23
21
|
*(@modules ? [bind(@modules, "#{@root}/modules")] : [])]
|
|
24
22
|
end
|
|
25
23
|
|
|
26
24
|
def prepare
|
|
27
|
-
return if @targets.empty?
|
|
28
25
|
raise Error, 'Managed environment directory must not be a symlink' if @directory.symlink?
|
|
29
26
|
|
|
30
27
|
FileUtils.mkdir_p(@directory, mode: 0o755)
|
|
@@ -81,13 +78,36 @@ module Empeira
|
|
|
81
78
|
end
|
|
82
79
|
|
|
83
80
|
def create_entry(relative, destination)
|
|
84
|
-
if
|
|
81
|
+
if relative == 'environment.conf'
|
|
82
|
+
prepare_configuration(destination)
|
|
83
|
+
elsif @targets.any? { |target| target == relative || target.start_with?("#{relative}/") }
|
|
85
84
|
create_target(relative, destination)
|
|
86
85
|
else
|
|
87
86
|
create_link(relative, destination)
|
|
88
87
|
end
|
|
89
88
|
end
|
|
90
89
|
|
|
90
|
+
def prepare_configuration(destination)
|
|
91
|
+
content = environment_configuration
|
|
92
|
+
return if !destination.symlink? && destination.file? && destination.binread == content
|
|
93
|
+
|
|
94
|
+
Tempfile.create('environment-', @directory) do |file|
|
|
95
|
+
file.chmod(0o644)
|
|
96
|
+
file.write(content)
|
|
97
|
+
file.flush
|
|
98
|
+
File.rename(file.path, destination)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def environment_configuration
|
|
103
|
+
source = @project.join('environment.conf')
|
|
104
|
+
content = source.exist? ? source.binread : ''
|
|
105
|
+
content = content.gsub(/^[ \t]*environment_timeout[ \t]*=[^\r\n]*/, 'environment_timeout = 0')
|
|
106
|
+
content += "\n" unless content.empty? || content.end_with?("\n")
|
|
107
|
+
content += "environment_timeout = 0\n" unless content.match?(/^environment_timeout = 0\r?$/)
|
|
108
|
+
content
|
|
109
|
+
end
|
|
110
|
+
|
|
91
111
|
def create_target(relative, destination)
|
|
92
112
|
raise Error, 'Managed environment destination is unsafe' if destination.symlink?
|
|
93
113
|
|
|
@@ -24,10 +24,10 @@ module Empeira
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def verify!(resource)
|
|
27
|
-
return if current(resource) == '0'
|
|
27
|
+
return if current(resource) == '0' && effective(resource) == '0'
|
|
28
28
|
|
|
29
29
|
raise Error, 'Puppetserver environment_timeout is not 0 after startup; the custom entrypoint or ' \
|
|
30
|
-
'server confdir overrides the managed setting; inspect the server runtime contract'
|
|
30
|
+
'server confdir/environment overrides the managed setting; inspect the server runtime contract'
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
private
|
|
@@ -36,6 +36,12 @@ module Empeira
|
|
|
36
36
|
execute(resource, [ControlPlane::Health::RUBY, READER, '--confdir', confdir]).stdout.strip
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
def effective(resource)
|
|
40
|
+
arguments = [PUPPET, 'config', 'print', 'environment_timeout', '--section', 'server',
|
|
41
|
+
'--confdir', confdir, '--environment', @plan.config.dig('server', 'environment')]
|
|
42
|
+
execute(resource, arguments).stdout.strip
|
|
43
|
+
end
|
|
44
|
+
|
|
39
45
|
def execute(resource, arguments)
|
|
40
46
|
result = @runtime.service_exec(resource, arguments)
|
|
41
47
|
return result if result.success?
|
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.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Christian Meißner (c8m6)
|
|
@@ -304,7 +304,7 @@ files:
|
|
|
304
304
|
- resources/relay/server_start.sh
|
|
305
305
|
homepage: https://github.com/c8m6/empeira
|
|
306
306
|
licenses:
|
|
307
|
-
- AGPL-3.0-
|
|
307
|
+
- AGPL-3.0-or-later
|
|
308
308
|
metadata:
|
|
309
309
|
rubygems_mfa_required: 'true'
|
|
310
310
|
rdoc_options: []
|