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.
Files changed (274) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +661 -0
  3. data/README.md +150 -0
  4. data/bin/empeira +18 -0
  5. data/config/defaults.yaml +229 -0
  6. data/docs/addons.md +331 -0
  7. data/docs/architecture.md +277 -0
  8. data/docs/configuration.md +1204 -0
  9. data/docs/development.md +472 -0
  10. data/docs/hiera-and-eyaml.md +361 -0
  11. data/docs/installation.md +280 -0
  12. data/docs/networking.md +362 -0
  13. data/docs/nodes.md +642 -0
  14. data/docs/proxy.md +136 -0
  15. data/docs/troubleshooting.md +361 -0
  16. data/lib/empeira/addons/environment.rb +82 -0
  17. data/lib/empeira/addons/error.rb +14 -0
  18. data/lib/empeira/addons/installation.rb +119 -0
  19. data/lib/empeira/addons/manifest.rb +112 -0
  20. data/lib/empeira/addons/service.rb +50 -0
  21. data/lib/empeira/addons/storage.rb +94 -0
  22. data/lib/empeira/agent/acquisition.rb +120 -0
  23. data/lib/empeira/agent/artifact.rb +41 -0
  24. data/lib/empeira/agent/authentication.rb +122 -0
  25. data/lib/empeira/agent/cache.rb +122 -0
  26. data/lib/empeira/agent/cache_storage.rb +82 -0
  27. data/lib/empeira/agent/download.rb +84 -0
  28. data/lib/empeira/agent/native_commands.rb +84 -0
  29. data/lib/empeira/agent/release_sources.rb +64 -0
  30. data/lib/empeira/agent/target.rb +66 -0
  31. data/lib/empeira/agent/versions.rb +29 -0
  32. data/lib/empeira/application.rb +86 -0
  33. data/lib/empeira/build.json +5 -0
  34. data/lib/empeira/build_info.rb +46 -0
  35. data/lib/empeira/cli/addons.rb +45 -0
  36. data/lib/empeira/cli/base.rb +73 -0
  37. data/lib/empeira/cli/completion.rb +42 -0
  38. data/lib/empeira/cli/config.rb +22 -0
  39. data/lib/empeira/cli/main.rb +114 -0
  40. data/lib/empeira/cli/node.rb +87 -0
  41. data/lib/empeira/cli/progress.rb +169 -0
  42. data/lib/empeira/cli/proxy.rb +36 -0
  43. data/lib/empeira/cli/update.rb +23 -0
  44. data/lib/empeira/completion/addons.rb +93 -0
  45. data/lib/empeira/completion/bash.rb +62 -0
  46. data/lib/empeira/completion/catalog.rb +170 -0
  47. data/lib/empeira/configuration/additional_services.rb +74 -0
  48. data/lib/empeira/configuration/addons.rb +85 -0
  49. data/lib/empeira/configuration/agent_schema.rb +163 -0
  50. data/lib/empeira/configuration/agent_values.rb +54 -0
  51. data/lib/empeira/configuration/bootstrap_guests.rb +42 -0
  52. data/lib/empeira/configuration/command_mocks.rb +65 -0
  53. data/lib/empeira/configuration/display.rb +20 -0
  54. data/lib/empeira/configuration/dns_rewrites.rb +58 -0
  55. data/lib/empeira/configuration/document.rb +67 -0
  56. data/lib/empeira/configuration/eyaml.rb +46 -0
  57. data/lib/empeira/configuration/hiera_modulepath.rb +40 -0
  58. data/lib/empeira/configuration/hiera_mount_schema.rb +62 -0
  59. data/lib/empeira/configuration/hiera_mounts.rb +83 -0
  60. data/lib/empeira/configuration/image_schema.rb +68 -0
  61. data/lib/empeira/configuration/loader.rb +70 -0
  62. data/lib/empeira/configuration/merge.rb +48 -0
  63. data/lib/empeira/configuration/network_redirects.rb +73 -0
  64. data/lib/empeira/configuration/node_images.rb +64 -0
  65. data/lib/empeira/configuration/schema.rb +215 -0
  66. data/lib/empeira/configuration/server_mounts.rb +106 -0
  67. data/lib/empeira/configuration/service_configuration.rb +40 -0
  68. data/lib/empeira/configuration/ssh_preferences.rb +83 -0
  69. data/lib/empeira/configuration/user.rb +46 -0
  70. data/lib/empeira/configuration/vm_interfaces.rb +147 -0
  71. data/lib/empeira/control_plane/additional_configurations.rb +106 -0
  72. data/lib/empeira/control_plane/browser.rb +73 -0
  73. data/lib/empeira/control_plane/controller.rb +763 -0
  74. data/lib/empeira/control_plane/discovery.rb +69 -0
  75. data/lib/empeira/control_plane/environment.rb +101 -0
  76. data/lib/empeira/control_plane/files.rb +263 -0
  77. data/lib/empeira/control_plane/health.rb +104 -0
  78. data/lib/empeira/control_plane/plan.rb +356 -0
  79. data/lib/empeira/control_plane/storage.rb +48 -0
  80. data/lib/empeira/errors.rb +9 -0
  81. data/lib/empeira/execution/console.rb +45 -0
  82. data/lib/empeira/execution/diagnostics.rb +210 -0
  83. data/lib/empeira/execution/launch_error.rb +14 -0
  84. data/lib/empeira/execution/result.rb +11 -0
  85. data/lib/empeira/execution/runner.rb +235 -0
  86. data/lib/empeira/execution/terminal.rb +35 -0
  87. data/lib/empeira/hostname_pattern.rb +14 -0
  88. data/lib/empeira/images/configuration.rb +44 -0
  89. data/lib/empeira/images/identity.rb +30 -0
  90. data/lib/empeira/images/recipe.rb +22 -0
  91. data/lib/empeira/images/reference.rb +43 -0
  92. data/lib/empeira/images/source.rb +19 -0
  93. data/lib/empeira/immutable.rb +19 -0
  94. data/lib/empeira/infrastructure/cleanup.rb +328 -0
  95. data/lib/empeira/infrastructure/definition.rb +59 -0
  96. data/lib/empeira/infrastructure/owned_files.rb +63 -0
  97. data/lib/empeira/infrastructure/recovery_inventory.rb +53 -0
  98. data/lib/empeira/infrastructure/service.rb +237 -0
  99. data/lib/empeira/infrastructure/status.rb +73 -0
  100. data/lib/empeira/infrastructure/store.rb +274 -0
  101. data/lib/empeira/modules/events.rb +67 -0
  102. data/lib/empeira/modules/git_safety.rb +60 -0
  103. data/lib/empeira/modules/host_git.rb +91 -0
  104. data/lib/empeira/modules/image.rb +27 -0
  105. data/lib/empeira/modules/installer.rb +67 -0
  106. data/lib/empeira/modules/request.rb +68 -0
  107. data/lib/empeira/modules/state.rb +87 -0
  108. data/lib/empeira/modules/storage.rb +35 -0
  109. data/lib/empeira/network/bootstrap_proxy.rb +157 -0
  110. data/lib/empeira/network/definition.rb +61 -0
  111. data/lib/empeira/network/direct_egress.rb +133 -0
  112. data/lib/empeira/network/egress.rb +27 -0
  113. data/lib/empeira/network/gateway.rb +79 -0
  114. data/lib/empeira/network/host_policy.rb +53 -0
  115. data/lib/empeira/network/naming.rb +28 -0
  116. data/lib/empeira/network/peer/adapter_image.rb +32 -0
  117. data/lib/empeira/network/peer/allocation.rb +45 -0
  118. data/lib/empeira/network/peer/attachment.rb +27 -0
  119. data/lib/empeira/network/peer/backend.rb +108 -0
  120. data/lib/empeira/network/peer/channel.rb +133 -0
  121. data/lib/empeira/network/peer/channel_server.rb +71 -0
  122. data/lib/empeira/network/peer/docker_adapter.rb +165 -0
  123. data/lib/empeira/network/peer/helper_security.rb +40 -0
  124. data/lib/empeira/network/peer/layout.rb +55 -0
  125. data/lib/empeira/network/peer/linux_podman.rb +114 -0
  126. data/lib/empeira/network/peer/podman_machine.rb +112 -0
  127. data/lib/empeira/network/policy.rb +39 -0
  128. data/lib/empeira/network/proxy_bindings.rb +52 -0
  129. data/lib/empeira/network/proxy_policy.rb +64 -0
  130. data/lib/empeira/network/redirects.rb +89 -0
  131. data/lib/empeira/network/resource.rb +50 -0
  132. data/lib/empeira/node/agent_installer.rb +31 -0
  133. data/lib/empeira/node/agent_package.rb +125 -0
  134. data/lib/empeira/node/agent_repository.rb +160 -0
  135. data/lib/empeira/node/apt_configuration.rb +85 -0
  136. data/lib/empeira/node/bootstrap.rb +17 -0
  137. data/lib/empeira/node/certificates.rb +98 -0
  138. data/lib/empeira/node/command_mock.rb +38 -0
  139. data/lib/empeira/node/command_mocks.rb +114 -0
  140. data/lib/empeira/node/container.rb +134 -0
  141. data/lib/empeira/node/container_agent_bootstrap.rb +43 -0
  142. data/lib/empeira/node/container_bootstrap.rb +52 -0
  143. data/lib/empeira/node/container_guest.rb +42 -0
  144. data/lib/empeira/node/container_lifecycle.rb +145 -0
  145. data/lib/empeira/node/container_preparation.rb +144 -0
  146. data/lib/empeira/node/container_state.rb +129 -0
  147. data/lib/empeira/node/definition.rb +20 -0
  148. data/lib/empeira/node/diagnostic_command.rb +19 -0
  149. data/lib/empeira/node/dnf_agent_repository.rb +202 -0
  150. data/lib/empeira/node/external_fact.rb +21 -0
  151. data/lib/empeira/node/image.rb +38 -0
  152. data/lib/empeira/node/interactive_tools.rb +33 -0
  153. data/lib/empeira/node/interface.rb +18 -0
  154. data/lib/empeira/node/inventory.rb +143 -0
  155. data/lib/empeira/node/package_bootstrap.rb +129 -0
  156. data/lib/empeira/node/package_proxy.rb +102 -0
  157. data/lib/empeira/node/package_sources.rb +19 -0
  158. data/lib/empeira/node/puppet_command.rb +12 -0
  159. data/lib/empeira/node/rpm_configuration.rb +62 -0
  160. data/lib/empeira/node/run_request.rb +52 -0
  161. data/lib/empeira/node/runtime_proxy.rb +86 -0
  162. data/lib/empeira/node/service.rb +72 -0
  163. data/lib/empeira/node/ssh_client.rb +25 -0
  164. data/lib/empeira/node/ssh_credentials.rb +78 -0
  165. data/lib/empeira/node/ssh_endpoint.rb +58 -0
  166. data/lib/empeira/node/ssh_identity.rb +37 -0
  167. data/lib/empeira/node/user_ssh.rb +60 -0
  168. data/lib/empeira/node/vm.rb +89 -0
  169. data/lib/empeira/node/vm_bootstrap.rb +53 -0
  170. data/lib/empeira/node/vm_lifecycle.rb +212 -0
  171. data/lib/empeira/node/vm_preflight.rb +37 -0
  172. data/lib/empeira/node/vm_preparation.rb +161 -0
  173. data/lib/empeira/node/vm_state.rb +161 -0
  174. data/lib/empeira/platform/facts.rb +66 -0
  175. data/lib/empeira/platform/kvm.rb +91 -0
  176. data/lib/empeira/platform/locations.rb +51 -0
  177. data/lib/empeira/platform/resolvers.rb +85 -0
  178. data/lib/empeira/platform/routes.rb +50 -0
  179. data/lib/empeira/progress.rb +70 -0
  180. data/lib/empeira/project_root.rb +47 -0
  181. data/lib/empeira/providers/lifecycle.rb +96 -0
  182. data/lib/empeira/providers/registry.rb +21 -0
  183. data/lib/empeira/providers/resource.rb +32 -0
  184. data/lib/empeira/providers.rb +55 -0
  185. data/lib/empeira/runtime/agent_helper.rb +34 -0
  186. data/lib/empeira/runtime/container.rb +184 -0
  187. data/lib/empeira/runtime/diagnostic_execution.rb +52 -0
  188. data/lib/empeira/runtime/docker.rb +87 -0
  189. data/lib/empeira/runtime/image_metadata.rb +83 -0
  190. data/lib/empeira/runtime/interface.rb +8 -0
  191. data/lib/empeira/runtime/mount_probe.rb +57 -0
  192. data/lib/empeira/runtime/podman.rb +122 -0
  193. data/lib/empeira/runtime/recipe_build.rb +103 -0
  194. data/lib/empeira/runtime/registry_diagnostics.rb +23 -0
  195. data/lib/empeira/runtime/service_arguments.rb +55 -0
  196. data/lib/empeira/runtime/service_images.rb +118 -0
  197. data/lib/empeira/runtime/service_inspection.rb +159 -0
  198. data/lib/empeira/runtime/services.rb +120 -0
  199. data/lib/empeira/runtime/update_helper.rb +97 -0
  200. data/lib/empeira/runtime/workspace_network.rb +69 -0
  201. data/lib/empeira/server/environment_configuration.rb +53 -0
  202. data/lib/empeira/server/http.rb +38 -0
  203. data/lib/empeira/server/puppetdb_runtime.rb +74 -0
  204. data/lib/empeira/server/relay_certificate.rb +76 -0
  205. data/lib/empeira/server/runtime.rb +90 -0
  206. data/lib/empeira/services/definition.rb +42 -0
  207. data/lib/empeira/updates/images.rb +104 -0
  208. data/lib/empeira/updates/modules.rb +45 -0
  209. data/lib/empeira/updates/service.rb +45 -0
  210. data/lib/empeira/version_requirement.rb +23 -0
  211. data/lib/empeira/vm/agent.rb +66 -0
  212. data/lib/empeira/vm/bootstrap_requirements.rb +69 -0
  213. data/lib/empeira/vm/certificate_runtime.rb +30 -0
  214. data/lib/empeira/vm/cloud_init.rb +171 -0
  215. data/lib/empeira/vm/disk.rb +136 -0
  216. data/lib/empeira/vm/guest.rb +123 -0
  217. data/lib/empeira/vm/guest_channel.rb +110 -0
  218. data/lib/empeira/vm/guest_network.rb +94 -0
  219. data/lib/empeira/vm/guest_output.rb +52 -0
  220. data/lib/empeira/vm/guest_shell.rb +79 -0
  221. data/lib/empeira/vm/guest_upload.rb +43 -0
  222. data/lib/empeira/vm/image_cache.rb +77 -0
  223. data/lib/empeira/vm/image_source.rb +91 -0
  224. data/lib/empeira/vm/interface.rb +8 -0
  225. data/lib/empeira/vm/interface_ownership.rb +124 -0
  226. data/lib/empeira/vm/interface_routes.rb +101 -0
  227. data/lib/empeira/vm/interfaces.rb +240 -0
  228. data/lib/empeira/vm/management.rb +73 -0
  229. data/lib/empeira/vm/prerequisites.rb +42 -0
  230. data/lib/empeira/vm/qemu.rb +83 -0
  231. data/lib/empeira/vm/qemu_runtime.rb +404 -0
  232. data/lib/empeira/vm/removal.rb +30 -0
  233. data/lib/empeira/vm/root_disk.rb +92 -0
  234. data/lib/empeira/vm/session_lock.rb +56 -0
  235. data/lib/empeira/vm/system_ssh.rb +29 -0
  236. data/lib/empeira/workspace.rb +42 -0
  237. data/lib/empeira.rb +209 -0
  238. data/resources/browser/relay.rb +22 -0
  239. data/resources/gateway/Containerfile +8 -0
  240. data/resources/gateway/bridge.rb +66 -0
  241. data/resources/gateway/configure.rb +323 -0
  242. data/resources/modules/Containerfile +15 -0
  243. data/resources/modules/Gemfile +5 -0
  244. data/resources/modules/Gemfile.lock +105 -0
  245. data/resources/modules/worker.rb +161 -0
  246. data/resources/network/adapter/Containerfile +13 -0
  247. data/resources/network/adapter/bridge_linux.go +51 -0
  248. data/resources/network/adapter/framing.go +45 -0
  249. data/resources/network/adapter/framing_test.go +53 -0
  250. data/resources/network/adapter/go.mod +3 -0
  251. data/resources/network/adapter/main_linux.go +273 -0
  252. data/resources/network/channel.rb +18 -0
  253. data/resources/network/ssh_connect.rb +32 -0
  254. data/resources/nodes/apt_sources.rb +66 -0
  255. data/resources/nodes/debian/Containerfile +10 -0
  256. data/resources/nodes/diagnostic_exec.rb +109 -0
  257. data/resources/nodes/interactive_tools.rb +139 -0
  258. data/resources/nodes/managed_file.rb +91 -0
  259. data/resources/nodes/management/guest_agent.py +415 -0
  260. data/resources/nodes/management/setup.sh +20 -0
  261. data/resources/nodes/management/shell_rc.sh +12 -0
  262. data/resources/nodes/management/system_account.sh +24 -0
  263. data/resources/nodes/management/system_home.sh +15 -0
  264. data/resources/nodes/rpm/Containerfile +10 -0
  265. data/resources/nodes/runtime_proxy.rb +244 -0
  266. data/resources/nodes/ssh/proxy.rb +16 -0
  267. data/resources/nodes/ssh/sshd_config +15 -0
  268. data/resources/nodes/ssh/start +6 -0
  269. data/resources/proxy/Containerfile +10 -0
  270. data/resources/relay/Containerfile +5 -0
  271. data/resources/relay/puppetdb.rb +81 -0
  272. data/resources/relay/server_environment.rb +10 -0
  273. data/resources/relay/server_start.sh +41 -0
  274. metadata +326 -0
@@ -0,0 +1,105 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ base64 (0.3.0)
5
+ colored2 (4.0.3)
6
+ cri (2.15.12)
7
+ erubi (1.13.1)
8
+ faraday (2.14.4)
9
+ faraday-net_http (>= 2.0, < 3.5)
10
+ json
11
+ logger
12
+ faraday-follow_redirects (0.5.0)
13
+ faraday (>= 1, < 3)
14
+ faraday-net_http (3.4.4)
15
+ net-http (~> 0.5)
16
+ fast_gettext (4.1.1)
17
+ prime
18
+ racc
19
+ fiddle (1.1.8)
20
+ forwardable (1.4.0)
21
+ gettext (3.5.2)
22
+ erubi
23
+ locale (>= 2.0.5)
24
+ prime
25
+ racc
26
+ text (>= 1.3.0)
27
+ gettext-setup (1.1.1)
28
+ fast_gettext (>= 2.1, < 5.0)
29
+ gettext (~> 3.4)
30
+ locale
31
+ json (3.0.2)
32
+ jwt (2.10.3)
33
+ base64
34
+ locale (2.1.5)
35
+ fiddle
36
+ log4r (1.1.10)
37
+ logger (1.7.0)
38
+ minitar (1.1.0)
39
+ multi_json (1.21.2)
40
+ net-http (0.9.1)
41
+ uri (>= 0.11.1)
42
+ prime (0.1.4)
43
+ forwardable
44
+ singleton
45
+ puppet_forge (6.2.0)
46
+ base64 (>= 0.2.0, < 0.4.0)
47
+ faraday (~> 2.0)
48
+ faraday-follow_redirects (>= 0.3, < 0.6)
49
+ minitar (~> 1.0, >= 1.0.2)
50
+ semantic_puppet (~> 1.0)
51
+ r10k (5.0.3)
52
+ colored2 (~> 4.0)
53
+ cri (>= 2.15.10)
54
+ gettext-setup (>= 0.24, < 2.0)
55
+ jwt (>= 2.2.3, < 3)
56
+ log4r (= 1.1.10)
57
+ minitar (>= 0.9, < 2)
58
+ multi_json (~> 1.10)
59
+ puppet_forge (>= 6.1.0, < 7)
60
+ racc (1.8.1)
61
+ semantic_puppet (1.1.1)
62
+ singleton (0.3.0)
63
+ text (1.3.1)
64
+ uri (1.1.1)
65
+
66
+ PLATFORMS
67
+ ruby
68
+ x86_64-linux
69
+
70
+ DEPENDENCIES
71
+ r10k (= 5.0.3)
72
+
73
+ CHECKSUMS
74
+ base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
75
+ bundler (4.0.22) sha256=d8d5ec84c8555e0af71db63ed7aee4d1a8fb839ec46d84212d61979242a5d75a
76
+ colored2 (4.0.3) sha256=63e1038183976287efc43034f5cca17fb180b4deef207da8ba78d051cbce2b37
77
+ cri (2.15.12) sha256=8abfe924ef53e772a8e4ee907e791d3bfcfca78bc62a5859e3b9899ba29956e5
78
+ erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
79
+ faraday (2.14.4) sha256=9bb4408c44621b0dbaaaa39e5dbfc4dbe58cc6751b6eb94d16ae9e1f2f2fab6e
80
+ faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad
81
+ faraday-net_http (3.4.4) sha256=0e78af151747ed1b00f33e25973b4bc220d7f16c00c39676817c8b12331eb588
82
+ fast_gettext (4.1.1) sha256=e8c532f6945b0dc31efb2e91366bd56630bc3ae6a05a4126937124e40366efd8
83
+ fiddle (1.1.8) sha256=7fa8ee3627271497f3add5503acdbc3f40b32f610fc1cf49634f083ef3f32eee
84
+ forwardable (1.4.0) sha256=f1cd40cc9812937980e1c76f1aa053660990a7c9b6a98fc37d945468afcce838
85
+ gettext (3.5.2) sha256=ada02c59aa7e9f56bd2522faedaed16421dd2f3ddb5fe28628c0be5abcbf3c74
86
+ gettext-setup (1.1.1) sha256=15ce653696283c9835b0ad9f02f236b9f240cb35facd3341cc62b85d42c6b667
87
+ json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
88
+ jwt (2.10.3) sha256=e4d9352fbc7309b1a7448c7dd713dfe4d8c47077af80759cdbed8f878ea0b484
89
+ locale (2.1.5) sha256=1c6803e8aa6bdb2c29e91945d095050601bf6d58474993575adf6f3b89b32ef4
90
+ log4r (1.1.10) sha256=9b452928c964b7c54c09aeb25ff045b5a722b387b16c9ce37cb1baec00062966
91
+ logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
92
+ minitar (1.1.0) sha256=38db0cfb6f3801017946cdcd8dc53f2cf3fd41ff752892312bf9a1639c9ea23e
93
+ multi_json (1.21.2) sha256=245531eaf54bdba57aba515ff08b4503505c5e09911daa89c5a561e2f85bea8e
94
+ net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996
95
+ prime (0.1.4) sha256=4d755ebf7c2994a6f3a3fee0d072063be3fff2d4042ebff6cd5eebd4747a225e
96
+ puppet_forge (6.2.0) sha256=9cde4841a7a6950afeb0c4fec02449931179863918c0a6e6909cb2a6c6998a0c
97
+ r10k (5.0.3) sha256=a76daddd8cecdc1cf0816f3d19adb23782598d373344a9de23623f601d58a68b
98
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
99
+ semantic_puppet (1.1.1) sha256=15ff5b48d7f856549eb66b927a8894d3668b211970c9d7dc07dd4db57f5c7a96
100
+ singleton (0.3.0) sha256=83ea1bca5f4aa34d00305ab842a7862ea5a8a11c73d362cb52379d94e9615778
101
+ text (1.3.1) sha256=2fbbbc82c1ce79c4195b13018a87cbb00d762bda39241bb3cdc32792759dd3f4
102
+ uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
103
+
104
+ BUNDLED WITH
105
+ 4.0.22
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Runs only inside the disposable installer, never in the CLI process.
4
+ require 'bundler/setup'
5
+ require 'r10k/module_loader/puppetfile'
6
+ require 'r10k/git/cache'
7
+ require 'json'
8
+ require 'fileutils'
9
+
10
+ module EmpeiraModules
11
+ class Invalid < StandardError; end
12
+
13
+ # rubocop:disable-next Metrics/ClassLength -- Keep the small controlled r10k worker in one packaged file.
14
+ class Worker
15
+ def initialize(directory)
16
+ @directory = File.expand_path(directory)
17
+ @request = JSON.parse(File.read(File.join(@directory, 'request.json')))
18
+ R10K::Logging.disable_default_stderr = true
19
+ R10K::Git::Cache.settings[:cache_root] = @request.fetch('cache')
20
+ end
21
+
22
+ # rubocop:disable-next Metrics/AbcSize -- Evaluate once and describe both Forge and host-acquired Git modules.
23
+ def plan
24
+ sources = modules.grep(R10K::Module::Git).map { |mod| { 'name' => mod.name, 'remote' => mod.remote } }
25
+ report('TOTAL', modules.size)
26
+ descriptors = modules.map { |mod| descriptor(mod) }
27
+ File.write(File.join(@directory, 'install-plan.json'),
28
+ JSON.generate('forge' => PuppetForge.host, 'modules' => descriptors))
29
+ File.write(File.join(@directory, 'git-sources.json'),
30
+ JSON.generate('git' => sources, 'names' => modules.map(&:name).sort))
31
+ end
32
+
33
+ def run
34
+ selected = prepared_modules
35
+ selected.each { |mod| validate(mod) }
36
+ FileUtils.mkdir_p(File.join(@directory, 'modules'))
37
+ selected.each { |mod| install(mod) }
38
+ @request.fetch('overrides').each { |name| FileUtils.mkdir_p(File.join(@directory, 'modules', name)) }
39
+ end
40
+
41
+ private
42
+
43
+ def modules
44
+ @modules ||= load_modules.each { |mod| validate(mod) }
45
+ end
46
+
47
+ def descriptor(mod)
48
+ report('START', mod.name)
49
+ git = mod.is_a?(R10K::Module::Git)
50
+ version = git ? mod.desired_ref || mod.default_ref || 'HEAD' : mod.expected_version
51
+ { 'title' => mod.title, 'name' => mod.name, 'type' => git ? 'git' : 'forge', 'version' => version }
52
+ rescue StandardError => e
53
+ raise Invalid, "Module #{mod.name}: cannot resolve Forge module/version; " \
54
+ 'check module/version and your normal host/container network access',
55
+ cause: e
56
+ end
57
+
58
+ def prepared_modules
59
+ data = JSON.parse(File.read(File.join(@directory, 'install-plan.json')))
60
+ PuppetForge.host = data.fetch('forge')
61
+ data.fetch('modules').map { |entry| prepared_module(entry) }
62
+ end
63
+
64
+ def prepared_module(entry)
65
+ options = { version: entry.fetch('version'), type: entry.fetch('type'), exclude_spec: false }
66
+ options[:source] = acquired_git(entry.fetch('name')) if entry['type'] == 'git'
67
+ R10K::Module.new(entry.fetch('title'), File.join(@directory, 'modules'), options)
68
+ end
69
+
70
+ def load_modules
71
+ overrides = @request.fetch('overrides')
72
+ excluded = /\A(?:#{overrides.map { |name| Regexp.escape(name) }.join('|')})\z/ unless overrides.empty?
73
+ loader = R10K::ModuleLoader::Puppetfile.new(
74
+ basedir: @directory, puppetfile: File.join(@directory, 'Puppetfile'),
75
+ module_exclude_regex: excluded,
76
+ overrides: { modules: { exclude_spec: false }, forge: { allow_puppetfile_override: true } }
77
+ )
78
+ loader.load!.fetch(:modules)
79
+ rescue StandardError, ScriptError => e
80
+ raise Invalid, 'Invalid Puppetfile: check Ruby syntax, module declarations and duplicate normalized names',
81
+ cause: e
82
+ end
83
+
84
+ # rubocop:disable-next Metrics/AbcSize -- Check supported source and destination before modifying an existing module.
85
+ def validate(mod)
86
+ raise Invalid, 'Invalid Puppetfile: module names must be lowercase Puppet identifiers' unless
87
+ mod.name.match?(/\A[a-z][a-z0-9_]*\z/)
88
+
89
+ unless mod.dirname == File.join(@directory, 'modules')
90
+ raise Invalid, 'Puppetfile moduledir/install_path must use the normal environment modules directory'
91
+ end
92
+ if File.symlink?(mod.full_path) || File.symlink?(File.join(mod.full_path, '.git'))
93
+ raise Invalid, "Module #{mod.name}: refusing a symlinked module directory or Git metadata"
94
+ end
95
+
96
+ case mod
97
+ when R10K::Module::Git then validate_git(mod)
98
+ when R10K::Module::Forge then nil
99
+ else raise Invalid, "Module #{mod.name}: only Git and Forge entries are supported"
100
+ end
101
+ end
102
+
103
+ def validate_git(mod)
104
+ return unless mod.desired_ref == :control_branch
105
+
106
+ raise Invalid, "Module #{mod.name}: replace :control_branch with an explicit ref"
107
+ end
108
+
109
+ def acquired_git(name)
110
+ raise Invalid, 'Invalid Puppetfile: module name in installer plan' unless name.match?(/\A[a-z][a-z0-9_]*\z/)
111
+
112
+ acquired = JSON.parse(File.read(File.join(@directory, 'acquired.json')))
113
+ mirror = acquired.fetch(name)
114
+ unless File.dirname(mirror) == @request.fetch('sources') &&
115
+ File.basename(mirror).match?(/\A[0-9a-f]{64}\.git\z/) && File.directory?(mirror)
116
+ raise Invalid, "Module #{name}: host Git source is missing"
117
+ end
118
+
119
+ mirror
120
+ end
121
+
122
+ def install(mod)
123
+ report('START', mod.name)
124
+ mod.sync
125
+ report('DONE', mod.name)
126
+ rescue StandardError => e
127
+ source = mod.is_a?(R10K::Module::Git) ? 'Git repository/ref' : 'Forge module/version'
128
+ raise Invalid, "Module #{mod.name}: cannot synchronize #{source}; " \
129
+ 'check availability, ref/version and your normal host/container network access',
130
+ cause: e
131
+ end
132
+
133
+ def report(kind, value)
134
+ $stdout.puts "EMPEIRA_MODULE_#{kind}:#{value}"
135
+ $stdout.flush
136
+ end
137
+ end
138
+ end
139
+
140
+ if $PROGRAM_NAME == __FILE__
141
+ begin
142
+ worker = EmpeiraModules::Worker.new(ARGV.fetch(0))
143
+ ARGV[1] == 'plan' ? worker.plan : worker.run
144
+ rescue EmpeiraModules::Invalid => e
145
+ # rubocop:disable-next Style/StderrPuts -- r10k sets $VERBOSE=nil; failure diagnostics must remain visible.
146
+ $stderr.puts e.message
147
+ # Buffered by the central runner; only filtered diagnostics reach the user's terminal.
148
+ cause = e.cause
149
+ 3.times do
150
+ break unless cause
151
+
152
+ $stderr.puts cause.message # rubocop:disable Style/StderrPuts
153
+ cause = cause.cause
154
+ end
155
+ exit 1
156
+ rescue StandardError, ScriptError
157
+ # rubocop:disable-next Style/StderrPuts -- r10k sets $VERBOSE=nil; failure diagnostics must remain visible.
158
+ $stderr.puts 'Puppetfile synchronization failed: installer input/output is unavailable or inconsistent'
159
+ exit 1
160
+ end
161
+ end
@@ -0,0 +1,13 @@
1
+ # SPDX-License-Identifier: AGPL-3.0-only
2
+ ARG EMPEIRA_BASE_BUILDER=@BUILDER@
3
+ FROM ${EMPEIRA_BASE_BUILDER} AS build
4
+ WORKDIR /source
5
+ COPY *.go go.mod ./
6
+ ENV CGO_ENABLED=0 GOTOOLCHAIN=local GOPROXY=off
7
+ RUN go test ./... && go build -trimpath -buildvcs=false -ldflags='-s -w' -o /adapter .
8
+ FROM scratch
9
+ COPY --from=build /adapter /adapter
10
+ COPY --from=build /usr/local/go/LICENSE /licenses/go-LICENSE
11
+ COPY LICENSE /licenses/empeira-LICENSE
12
+ ENTRYPOINT ["/adapter"]
13
+ CMD ["hold"]
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ package main
3
+
4
+ import (
5
+ "encoding/binary"
6
+ "fmt"
7
+ "net"
8
+ "syscall"
9
+ )
10
+
11
+ // Docker's outer bridge can reflect broadcasts via its hairpin-enabled veth.
12
+ // Never relearn guest source MACs on this uplink: they belong to local TAP ports.
13
+ // Container destinations still work through unknown-unicast flooding on the uplink.
14
+ func disableUplinkLearning(name string) error {
15
+ nic, err := net.InterfaceByName(name)
16
+ if err != nil {
17
+ return err
18
+ }
19
+ fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE)
20
+ if err != nil {
21
+ return err
22
+ }
23
+ defer syscall.Close(fd)
24
+ message := make([]byte, 44)
25
+ binary.NativeEndian.PutUint32(message[0:4], uint32(len(message)))
26
+ binary.NativeEndian.PutUint16(message[4:6], syscall.RTM_SETLINK)
27
+ binary.NativeEndian.PutUint16(message[6:8], syscall.NLM_F_REQUEST|syscall.NLM_F_ACK)
28
+ binary.NativeEndian.PutUint32(message[8:12], 1)
29
+ message[16] = syscall.AF_BRIDGE
30
+ binary.NativeEndian.PutUint32(message[20:24], uint32(nic.Index))
31
+ binary.NativeEndian.PutUint16(message[32:34], 12)
32
+ binary.NativeEndian.PutUint16(message[34:36], syscall.IFLA_PROTINFO|0x8000)
33
+ binary.NativeEndian.PutUint16(message[36:38], 5)
34
+ binary.NativeEndian.PutUint16(message[38:40], 8) // IFLA_BRPORT_LEARNING, value 0
35
+ if err = syscall.Sendto(fd, message, 0, &syscall.SockaddrNetlink{Family: syscall.AF_NETLINK}); err != nil {
36
+ return err
37
+ }
38
+ response := make([]byte, 4096)
39
+ n, _, err := syscall.Recvfrom(fd, response, 0)
40
+ if err != nil {
41
+ return err
42
+ }
43
+ if n < 20 || binary.NativeEndian.Uint16(response[4:6]) != syscall.NLMSG_ERROR {
44
+ return fmt.Errorf("missing bridge netlink acknowledgement")
45
+ }
46
+ code := int32(binary.NativeEndian.Uint32(response[16:20]))
47
+ if code != 0 {
48
+ return syscall.Errno(-code)
49
+ }
50
+ return nil
51
+ }
@@ -0,0 +1,45 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ package main
3
+
4
+ import (
5
+ "encoding/binary"
6
+ "fmt"
7
+ "io"
8
+ )
9
+
10
+ // QEMU stream netdev: a big-endian uint32 length followed by one Ethernet frame.
11
+ // No application port or protocol is interpreted here.
12
+ const maxFrame = 65535
13
+
14
+ func readFrame(r io.Reader) ([]byte, error) {
15
+ var size uint32
16
+ if err := binary.Read(r, binary.BigEndian, &size); err != nil {
17
+ return nil, err
18
+ }
19
+ if size < 14 || size > maxFrame {
20
+ return nil, fmt.Errorf("invalid Ethernet frame length %d", size)
21
+ }
22
+ frame := make([]byte, size)
23
+ _, err := io.ReadFull(r, frame)
24
+ return frame, err
25
+ }
26
+
27
+ func writeFrame(w io.Writer, frame []byte) error {
28
+ if len(frame) < 14 || len(frame) > maxFrame {
29
+ return fmt.Errorf("invalid Ethernet frame length %d", len(frame))
30
+ }
31
+ packet := make([]byte, 4+len(frame))
32
+ binary.BigEndian.PutUint32(packet, uint32(len(frame)))
33
+ copy(packet[4:], frame)
34
+ for len(packet) > 0 {
35
+ n, err := w.Write(packet)
36
+ if err != nil {
37
+ return err
38
+ }
39
+ if n == 0 {
40
+ return io.ErrShortWrite
41
+ }
42
+ packet = packet[n:]
43
+ }
44
+ return nil
45
+ }
@@ -0,0 +1,53 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ package main
3
+
4
+ import (
5
+ "bytes"
6
+ "encoding/binary"
7
+ "io"
8
+ "testing"
9
+ )
10
+
11
+ type shortWriter struct{ bytes.Buffer }
12
+
13
+ func (w *shortWriter) Write(b []byte) (int, error) {
14
+ if len(b) > 3 {
15
+ b = b[:3]
16
+ }
17
+ return w.Buffer.Write(b)
18
+ }
19
+
20
+ func TestFrameRoundTrip(t *testing.T) {
21
+ var stream shortWriter
22
+ want := bytes.Repeat([]byte{0, 255, 42}, 500)
23
+ for i := 0; i < 2; i++ {
24
+ if err := writeFrame(&stream, want); err != nil {
25
+ t.Fatal(err)
26
+ }
27
+ }
28
+ for i := 0; i < 2; i++ {
29
+ got, err := readFrame(&stream)
30
+ if err != nil || !bytes.Equal(got, want) {
31
+ t.Fatalf("frame mismatch: %v", err)
32
+ }
33
+ }
34
+ if _, err := readFrame(&stream); err != io.EOF {
35
+ t.Fatalf("wanted EOF: %v", err)
36
+ }
37
+ }
38
+
39
+ func TestInvalidLengths(t *testing.T) {
40
+ for _, n := range []uint32{0, 13, 65536, 0xffffffff} {
41
+ var stream bytes.Buffer
42
+ binary.Write(&stream, binary.BigEndian, n)
43
+ if _, err := readFrame(&stream); err == nil {
44
+ t.Fatalf("accepted %d", n)
45
+ }
46
+ }
47
+ var truncated bytes.Buffer
48
+ binary.Write(&truncated, binary.BigEndian, uint32(100))
49
+ truncated.Write(make([]byte, 14))
50
+ if _, err := readFrame(&truncated); err != io.ErrUnexpectedEOF {
51
+ t.Fatal(err)
52
+ }
53
+ }
@@ -0,0 +1,3 @@
1
+ module empeira.networkproof.transport
2
+
3
+ go 1.23