Compare commits

..

110 Commits

Author SHA1 Message Date
Dimitris Karakasilis
d4ce271c3a Migrate legacy (already removed) scripts to auroraboot commands (#201)
* Migrate legacy (already removed) scripts to auroraboot commands

Since we switched to using auroraboot as the tool-image, these scripts
no longer exist. The functionality is provided by auroraboot itself.

Fixes https://github.com/kairos-io/kairos/issues/3779

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Add e2e tests for various cloud formats

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix "PVC already exists" error in tests

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix auroraboot commands

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Make build-iso an init container

so that the netboot container finds the ISO in place when it needs it

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix tests

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Increase timeout for namespace deletion

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Refactor commands

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Refactor auroraboot command strings to use strings.Builder (#203)

* Initial plan

* Refactor command string to use strings.Builder for better readability

Co-authored-by: jimmykarily <2794419+jimmykarily@users.noreply.github.com>

* Complete refactoring of command string

Co-authored-by: jimmykarily <2794419+jimmykarily@users.noreply.github.com>

* Refactor azureCmd and gceCmd to use strings.Builder

Co-authored-by: jimmykarily <2794419+jimmykarily@users.noreply.github.com>

* Revert unintended changes to generated files

Co-authored-by: jimmykarily <2794419+jimmykarily@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jimmykarily <2794419+jimmykarily@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Apply suggestion from @jimmidyson

Co-authored-by: Jimmi Dyson <jimmi.dyson@nutanix.com>
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Refactor auroraboot invocation for consistenty with the rest

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Use string builder everywhere (consistency)

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Make sure we don't match multiple files (PR suggestion)

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

---------

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jimmykarily <2794419+jimmykarily@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jimmi Dyson <jimmi.dyson@nutanix.com>
2025-12-16 20:57:42 +02:00
Dimitris Karakasilis
19b3a57878 The flag --name has been renamed to --override-name in newer auroraboot (#200)
* The flag --name has been renamed to --override-name in newer auroraboot

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Set the default tool-image to a compatible one

We'd better set this to the compatible auroraboot version each time
because changing the flags of auroraboot in the future means it may not always
work with `latest`.

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Use newer image to fix tests

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

---------

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2025-11-20 13:36:57 +02:00
dependabot[bot]
f3ee5c3dc1 Bump golang.org/x/crypto in the go_modules group across 1 directory (#193)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 08:36:00 +02:00
Dimitris Karakasilis
4aa7211f96 Remove tools image references and opt for auroraboot (#192)
* Remove references to osbuilder-tools image

because it has been merged with auroraboot here:

https://github.com/kairos-io/AuroraBoot/pull/110

as part of https://github.com/kairos-io/kairos/issues/1633

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* WIP

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Fix test command

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* go mod tidy

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Bump linting action

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

* Don't look for artifacts in build/ subdir

because it has been fixed here:

https://github.com/kairos-io/AuroraBoot/pull/115

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>

---------

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-11-15 16:16:13 +02:00
Itxaka
3aa1fa1104 Merge pull request #188 from kairos-io/renovate/major-repositories 2024-10-23 11:52:08 +02:00
renovate[bot]
8813eb4809 Update repositories 2024-10-23 09:51:38 +00:00
Itxaka
95509370f6 Merge pull request #187 from kairos-io/Itxaka-patch-1 2024-10-19 12:53:52 +02:00
Itxaka
42fde4a1fb bump enki
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-10-19 12:50:24 +02:00
Itxaka
169ba969f3 Merge pull request #186 from kairos-io/renovate/major-repositories 2024-10-18 15:34:22 +02:00
renovate[bot]
6b7aac0e4b Update repositories 2024-10-16 18:09:03 +00:00
Itxaka
405eda716a Merge pull request #185 from kairos-io/Itxaka-patch-1 2024-10-14 12:25:21 +02:00
Itxaka
c77f6c564a Bump enki version
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-10-14 11:57:37 +02:00
Itxaka
ac3bc8bcc6 Merge pull request #175 from kairos-io/renovate/major-repositories 2024-10-14 11:56:33 +02:00
renovate[bot]
cf125b7371 Update repositories 2024-10-11 09:42:31 +00:00
Itxaka
ff80eae58f Merge pull request #184 from kairos-io/kairos-release 2024-10-07 14:26:18 +02:00
Itxaka
8b243a00fa Bump enki version and packages
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-10-07 14:13:31 +02:00
Itxaka
745b2a18f1 Also update the controller
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-10-01 11:44:15 +02:00
Itxaka
28ff9cf07b Move to use kairos-release
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-10-01 11:32:42 +02:00
renovate[bot]
19d96a575a Update module github.com/onsi/ginkgo/v2 to v2.20.2 2024-08-29 00:43:46 +00:00
renovate[bot]
902fd4f3eb Update quay.io/luet/base Docker tag to v0.35.5 2024-08-28 23:03:26 +00:00
renovate[bot]
69396c7e73 Update module github.com/onsi/gomega to v1.34.2 2024-08-28 23:03:22 +00:00
renovate[bot]
6daeff735e Update quay.io/luet/base Docker tag to v0.35.4 2024-08-01 22:57:28 +00:00
renovate[bot]
87716e187f Update module github.com/onsi/gomega to v1.34.1 2024-07-29 22:25:41 +00:00
renovate[bot]
f70e8d5cde Update module github.com/onsi/ginkgo/v2 to v2.19.1 2024-07-26 22:42:48 +00:00
Itxaka
bc34ec93a9 Merge pull request #174 from kairos-io/renovate/major-repositories 2024-07-18 19:07:02 +02:00
renovate[bot]
95ea70f0c3 Update repositories 2024-07-18 17:06:53 +00:00
Itxaka
f9a79f337d Merge pull request #171 from kairos-io/renovate/major-repositories 2024-07-18 12:48:38 +02:00
renovate[bot]
e43cc63dec Update repositories 2024-07-18 09:34:03 +00:00
renovate[bot]
308e1cf479 Update kairos-io/linting-composite-action action to v0.0.9 2024-07-11 22:26:29 +00:00
Itxaka
5c512fa5d4 Merge pull request #172 from kairos-io/go122 2024-07-11 12:05:17 +02:00
Itxaka
bdcfec72d0 Bump to go1.22
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-07-11 11:27:58 +02:00
Itxaka
551e6018b4 Merge pull request #170 from kairos-io/Itxaka-patch-1 2024-06-27 11:58:15 +02:00
Itxaka
45ca6ce3e4 Merge pull request #169 from kairos-io/renovate/major-repositories 2024-06-27 11:57:41 +02:00
Itxaka
2b922cedd7 Update enki to latest
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-27 11:55:21 +02:00
renovate[bot]
601d02d4f7 Update repositories 2024-06-27 09:54:21 +00:00
Itxaka
823c3f5d6e Merge pull request #168 from kairos-io/bump_ukify2 2024-06-25 12:34:47 +02:00
Itxaka
f090954bac Bump enki
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-25 12:11:52 +02:00
Itxaka
c3f4026908 Merge pull request #113 from kairos-io/renovate/github.com-onsi-ginkgo-v2-2.x 2024-06-25 10:28:15 +02:00
Itxaka
fedf3911a0 Merge pull request #167 from kairos-io/renovate/major-repositories 2024-06-25 10:27:52 +02:00
renovate[bot]
2f7cd450cd Update repositories 2024-06-24 18:45:57 +00:00
Itxaka
ce1cd74d17 re-enable all managers for renovate
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-24 16:36:56 +02:00
Itxaka
6b9a74b772 Fix renovate
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-24 16:34:13 +02:00
Itxaka
240d812cca Update luet-arm64.yaml
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-24 16:23:01 +02:00
Itxaka
fa781ea885 Update luet-amd64.yaml
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-24 16:22:31 +02:00
Itxaka
d951f97d84 Fix renovate
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-24 16:15:45 +02:00
Itxaka
6a04794629 Update renovate.json5
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-24 16:12:46 +02:00
Itxaka
b6aafd6e23 Merge pull request #165 from kairos-io/bump_enki_ukify 2024-06-24 16:10:51 +02:00
Itxaka
9b9a4b248b Merge branch 'master' into bump_enki_ukify
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-24 16:10:43 +02:00
Itxaka
925f177f73 Update renovate.json5
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-24 16:03:32 +02:00
renovate[bot]
ffd6afdfbd Update module github.com/onsi/ginkgo/v2 to v2.19.0 2024-06-24 13:59:36 +00:00
Itxaka
37d0d025d1 Merge pull request #160 from kairos-io/dependabot/go_modules/go_modules-6a40ccb4dd 2024-06-24 15:58:31 +02:00
Itxaka
b16b67488a Merge pull request #164 from kairos-io/renovate/docker-build-push-action-6.x 2024-06-24 15:57:12 +02:00
Itxaka
c49b394e6c Build ostools image on PR as well
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-20 10:26:13 +02:00
Itxaka
bf4cb26932 Bump to use latest enki with ukifier
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-06-20 10:01:09 +02:00
renovate[bot]
94b36a31f8 Update docker/build-push-action action to v6 2024-06-17 22:13:50 +00:00
Itxaka
18122a9656 Rename renovate.json to renovate.json5
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-17 11:47:32 +02:00
Itxaka
9b9a0383ce Update renovate.json
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-17 11:47:09 +02:00
Itxaka
a06f226c7b Update renovate.json to deal with repositories
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-06-17 11:45:34 +02:00
Mauro Morales
9cd36189cd Merge pull request #163 from kairos-io/2212-local-flag
2212 local flag
2024-05-22 16:53:54 +02:00
Mauro Morales
0eb05808fc Remove --disable-lvm and --use-lvm flags
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2024-05-22 15:14:15 +02:00
Mauro Morales
a29158475f Remove local flag
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2024-05-22 15:10:26 +02:00
Dimitris Karakasilis
36ea48fa23 Bump enki
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-05-21 10:48:19 +03:00
Dimitris Karakasilis
3daf5c5421 Bump enki to 0.0.31 (to fix signing of signature databases)
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-05-17 10:36:08 +03:00
Itxaka
29f9840d90 Merge pull request #149 from ci-forks/create-pull-request/patch 2024-05-10 12:40:41 +00:00
Itxaka
22133b515c Merge pull request #162 from kairos-io/Itxaka-patch-1 2024-05-10 12:27:00 +00:00
Itxaka
d9148667f2 Bump enki version
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-05-10 12:06:35 +02:00
renovate[bot]
24b7fe2a6d Update quay.io/luet/base Docker tag to v0.35.2 2024-04-22 22:11:43 +00:00
dependabot[bot]
93bd16dd0f Bump the go_modules group across 1 directory with 4 updates
Bumps the go_modules group with 4 updates in the / directory: [github.com/emicklei/go-restful](https://github.com/emicklei/go-restful), [golang.org/x/crypto](https://github.com/golang/crypto), [golang.org/x/net](https://github.com/golang/net) and google.golang.org/protobuf.


Updates `github.com/emicklei/go-restful` from 2.9.5+incompatible to 2.16.0+incompatible
- [Release notes](https://github.com/emicklei/go-restful/releases)
- [Changelog](https://github.com/emicklei/go-restful/blob/v3/CHANGES.md)
- [Commits](https://github.com/emicklei/go-restful/compare/v2.9.5...v2.16.0)

Updates `golang.org/x/crypto` from 0.16.0 to 0.17.0
- [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0)

Updates `golang.org/x/net` from 0.19.0 to 0.23.0
- [Commits](https://github.com/golang/net/compare/v0.19.0...v0.23.0)

Updates `google.golang.org/protobuf` from 1.28.0 to 1.33.0

---
updated-dependencies:
- dependency-name: github.com/emicklei/go-restful
  dependency-type: indirect
  dependency-group: go_modules
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
  dependency-group: go_modules
- dependency-name: golang.org/x/net
  dependency-type: indirect
  dependency-group: go_modules
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-19 12:48:38 +00:00
Dimitris Karakasilis
0dca7d9ea1 Bump enki
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-04-19 15:11:14 +03:00
Dimitris Karakasilis
570b6a244f Bump enki to v0.0.28
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-04-11 15:46:08 +03:00
Dimitris Karakasilis
f4842fba7e Bump enki to 0.0.27
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-04-09 16:19:03 +03:00
mudler
95739cf7e6 ⬆️ Update repositories
Signed-off-by: GitHub <noreply@github.com>
2024-03-29 20:09:19 +00:00
renovate[bot]
9392be9bd8 Update quay.io/kairos/enki Docker tag to v0.0.26 2024-03-27 08:25:12 +00:00
Dimitris Karakasilis
8b2fac5bbb Bump enki to include microsoft certs (#154)
https://github.com/kairos-io/kairos/issues/2377

Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-03-22 11:38:52 +02:00
renovate[bot]
2806239183 Update quay.io/luet/base Docker tag to v0.35.1 2024-03-15 13:59:42 +00:00
renovate[bot]
66c7aa5fb3 Update quay.io/kairos/enki Docker tag to v0.0.23 2024-03-15 13:59:05 +00:00
Mauro Morales
a6d03cffdf Merge pull request #151 from kairos-io/mauromorales-patch-1
Update Enki to v0.0.22
2024-03-13 10:40:05 +01:00
Mauro Morales
b21a5725a8 Update Enki to v0.0.22
Signed-off-by: Mauro Morales <mauro.morales@spectrocloud.com>
2024-03-13 10:24:08 +01:00
Itxaka
46d1e8547b Update Dockerfile
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-03-07 21:09:30 +01:00
Itxaka
29b4eb5964 Merge pull request #148 from ci-forks/create-pull-request/patch 2024-03-07 20:46:20 +01:00
mudler
0340dbf5bf ⬆️ Update repositories
Signed-off-by: GitHub <noreply@github.com>
2024-03-06 20:07:01 +00:00
Itxaka
2a55c3e080 Merge pull request #147 from ci-forks/create-pull-request/patch 2024-02-27 10:12:20 +01:00
Itxaka
beabe36c36 Update Dockerfile
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-02-27 10:11:38 +01:00
mudler
9af9939367 ⬆️ Update repositories
Signed-off-by: GitHub <noreply@github.com>
2024-02-22 20:06:47 +00:00
Itxaka
0fe28a034f Update Dockerfile
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-02-22 00:23:31 +01:00
Itxaka
db9c52985b install the proper arch for systemd-boot
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-02-21 20:59:13 +01:00
Itxaka
fbe3874152 Merge pull request #144 from ci-forks/create-pull-request/patch 2024-02-21 20:16:07 +01:00
Itxaka
77756071c6 ⬆️ Update repositories
Signed-off-by: GitHub <noreply@github.com>
2024-02-21 19:15:11 +00:00
Dimitris Karakasilis
ee5df3f0ea Bump enki version (#145)
Signed-off-by: Dimitris Karakasilis <dimitris@karakasilis.me>
2024-02-19 18:23:28 +02:00
Itxaka
cbc77a5493 Merge pull request #143 from kairos-io/ukify 2024-02-19 16:04:21 +01:00
Itxaka
7813c2eec4 Revert to using leap as base image for tool image
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-19 16:03:55 +01:00
Itxaka
32cd7c76cb Use ukify from packages
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-17 11:11:30 +01:00
Itxaka
82c9a08353 Merge pull request #142 from kairos-io/Itxaka-patch-1 2024-02-16 20:11:19 +01:00
Itxaka
dcd3b4be97 Update Dockerfile
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-02-16 20:11:01 +01:00
Itxaka
cedc294836 Merge pull request #141 from kairos-io/systemd_boot_artifacts 2024-02-16 17:29:51 +01:00
Itxaka
c0fc19b345 Update tools-image/Dockerfile
Co-authored-by: Mauro Morales <mauro.morales@spectrocloud.com>
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-16 16:52:57 +01:00
Itxaka
40477e3ceb Provide systemd-boot artifacts on osbuilder image
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-16 12:20:20 +01:00
Ettore Di Giacinto
7df2f481f8 fix(entrypoint.sh): quote when passing-by arguments (#140)
Signed-off-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2024-02-15 18:07:25 +01:00
Itxaka
907b32d5e5 Merge pull request #139 from kairos-io/bump_fedora 2024-02-14 11:12:47 +01:00
Itxaka
446807680b Merge branch 'master' into bump_fedora
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-02-14 11:12:41 +01:00
Itxaka
e118e769fe Improve osbuidler arm scripts
Use ext3 for partitions
Do not let the rpi4 script recreate the mapping
Only call dmsetup if we are on rpi3
Try to remove the final image loop device as well

Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-14 11:11:25 +01:00
Itxaka
97b58723a9 Merge pull request #133 from ci-forks/create-pull-request/patch 2024-02-12 14:41:53 +01:00
Itxaka
8570a9ed85 revert small sgdisk change
Signed-off-by: Itxaka <itxakaserrano@gmail.com>
2024-02-12 14:41:45 +01:00
mudler
aa04578df9 ⬆️ Update repositories
Signed-off-by: GitHub <noreply@github.com>
2024-02-11 20:07:05 +00:00
Itxaka
39cfe7af30 Merge pull request #137 from kairos-io/bump_fedora 2024-02-10 17:14:03 +01:00
Itxaka
10d5f627fc Use fedora 40
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-10 17:13:39 +01:00
Itxaka
89dec58dd9 Merge pull request #136 from kairos-io/bump_fedora 2024-02-10 11:20:29 +01:00
Itxaka
54ae9607ee Use Fedora 38
Looks like fedora 39 is broken

Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-10 11:20:02 +01:00
Itxaka
ddb88c0e2e Merge pull request #135 from kairos-io/bump_fedora 2024-02-10 10:48:00 +01:00
Itxaka
2c18ce3fbd Use fedora 40 for os tools container
Fixes an issue with sgdisk creating the disk images properly
Alos removes some uneeded options from the rpi4 disk cration:
 - `-g` option mean to transform mbr to gptt, but the disk was already
   gpt
 - `-m` option tried to make the disk mbr from gpt... not sure why that
   was there
 - creating the disk with gpt. There is no need as sgdisk will default
   to create a gpt disk

Signed-off-by: Itxaka <itxaka@kairos.io>
2024-02-10 10:45:52 +01:00
45 changed files with 4041 additions and 5313 deletions

View File

@@ -57,7 +57,7 @@ jobs:
password: ${{ secrets.QUAY_PASSWORD }}
- name: Build
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
builder: ${{ steps.buildx.outputs.name }}
context: .

View File

@@ -15,7 +15,7 @@ env:
FORCE_COLOR: 1
jobs:
call-workflow:
uses: kairos-io/linting-composite-action/.github/workflows/reusable-linting.yaml@v0.0.8
uses: kairos-io/linting-composite-action/.github/workflows/reusable-linting.yaml@v0.0.10
with:
yamldirs: ".github/workflows/ config/ tools-image/"
yamldirs: ".github/workflows/ config/"
is-go: true

View File

@@ -1,66 +0,0 @@
---
name: 'build tools container images'
on:
push:
branches:
- master
tags:
- '*'
concurrency:
group: tool-image-${{ github.ref || github.head_ref }}
cancel-in-progress: true
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=quay.io/kairos/osbuilder-tools
VERSION=latest
SHORTREF=${GITHUB_SHA::8}
# If this is git tag, use the tag name as a docker tag
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
fi
TAGS="${DOCKER_IMAGE}:${VERSION},${DOCKER_IMAGE}:${SHORTREF}"
# If the VERSION looks like a version number, assume that
# this is the most recent version of the image and also
# tag it 'latest'.
if [[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
TAGS="$TAGS,${DOCKER_IMAGE}:latest"
fi
# Set output parameters.
echo ::set-output name=tags::${TAGS}
echo ::set-output name=docker_image::${DOCKER_IMAGE}
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@master
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Build
uses: docker/build-push-action@v5
with:
builder: ${{ steps.buildx.outputs.name }}
context: ./tools-image
file: ./tools-image/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.prep.outputs.tags }}

View File

@@ -1,5 +1,5 @@
# Build the manager binary
FROM golang:1.20 as builder
FROM golang:1.23 AS builder
WORKDIR /workspace
# Copy the Go Modules manifests

View File

@@ -1,25 +0,0 @@
VERSION 0.6
last-commit-packages:
FROM quay.io/skopeo/stable
RUN dnf install -y jq
WORKDIR build
RUN skopeo list-tags docker://quay.io/kairos/packages | jq -rc '.Tags | map(select( (. | contains("-repository.yaml")) )) | sort_by(. | sub("v";"") | sub("-repository.yaml";"") | sub("-";"") | split(".") | map(tonumber) ) | .[-1]' > REPO_AMD64
RUN skopeo list-tags docker://quay.io/kairos/packages-arm64 | jq -rc '.Tags | map(select( (. | contains("-repository.yaml")) )) | sort_by(. | sub("v";"") | sub("-repository.yaml";"") | sub("-";"") | split(".") | map(tonumber) ) | .[-1]' > REPO_ARM64
SAVE ARTIFACT REPO_AMD64 REPO_AMD64
SAVE ARTIFACT REPO_ARM64 REPO_ARM64
bump-repositories:
FROM mikefarah/yq
WORKDIR build
COPY +last-commit-packages/REPO_AMD64 REPO_AMD64
COPY +last-commit-packages/REPO_ARM64 REPO_ARM64
ARG REPO_AMD64=$(cat REPO_AMD64)
ARG REPO_ARM64=$(cat REPO_ARM64)
COPY tools-image/luet-amd64.yaml luet-amd64.yaml
COPY tools-image/luet-arm64.yaml luet-arm64.yaml
RUN yq eval ".repositories[0] |= . * { \"reference\": \"${REPO_AMD64}\" }" -i luet-amd64.yaml
RUN yq eval ".repositories[0] |= . * { \"reference\": \"${REPO_ARM64}\" }" -i luet-arm64.yaml
SAVE ARTIFACT luet-arm64.yaml AS LOCAL tools-image/luet-arm64.yaml
SAVE ARTIFACT luet-amd64.yaml AS LOCAL tools-image/luet-amd64.yaml

View File

@@ -177,13 +177,15 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest
## Tool Versions
KUSTOMIZE_VERSION ?= v3.8.7
CONTROLLER_TOOLS_VERSION ?= v0.9.0
CONTROLLER_TOOLS_VERSION ?= v0.16.5
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
$(KUSTOMIZE): $(LOCALBIN)
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
@if [ ! -f $(KUSTOMIZE) ]; then \
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); \
fi
.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.

View File

@@ -66,7 +66,7 @@ To install, use helm:
# Adds the kairos repo to helm
$ helm repo add kairos https://kairos-io.github.io/helm-charts
"kairos" has been added to your repositories
$ helm repo update
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kairos" chart repository
Update Complete. ⎈Happy Helming!⎈

View File

@@ -49,8 +49,9 @@ type OSArtifactSpec struct {
CloudConfigRef *SecretKeySelector `json:"cloudConfigRef,omitempty"`
GRUBConfig string `json:"grubConfig,omitempty"`
Bundles []string `json:"bundles,omitempty"`
OSRelease string `json:"osRelease,omitempty"`
Bundles []string `json:"bundles,omitempty"`
OSRelease string `json:"osRelease,omitempty"`
KairosRelease string `json:"kairosRelease,omitempty"`
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
Exporters []batchv1.JobSpec `json:"exporters,omitempty"`

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: manager-role
rules:
- apiGroups:
@@ -16,15 +15,6 @@ rules:
- ""
resources:
- persistentvolumeclaims
verbs:
- create
- delete
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create

View File

@@ -18,6 +18,7 @@ package controllers
import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -107,6 +108,29 @@ func osReleaseContainer(containerImage string) corev1.Container {
}
}
func kairosReleaseContainer(containerImage string) corev1.Container {
return corev1.Container{
ImagePullPolicy: corev1.PullAlways,
Name: "kairos-release",
Image: containerImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
"cp -rfv /etc/kairos-release /rootfs/etc/kairos-release",
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "config",
MountPath: "/etc/kairos-release",
SubPath: "kairos-release",
},
{
Name: "rootfs",
MountPath: "/rootfs",
},
},
}
}
func (r *OSArtifactReconciler) newArtifactPVC(artifact *osbuilder.OSArtifact) *corev1.PersistentVolumeClaim {
if artifact.Spec.Volume == nil {
artifact.Spec.Volume = &corev1.PersistentVolumeClaimSpec{
@@ -133,10 +157,10 @@ func (r *OSArtifactReconciler) newArtifactPVC(artifact *osbuilder.OSArtifact) *c
}
func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder.OSArtifact) *corev1.Pod {
cmd := fmt.Sprintf(
"/entrypoint.sh --debug --name %s build-iso --date=false --output /artifacts dir:/rootfs",
artifact.Name,
)
var cmd strings.Builder
cmd.WriteString("auroraboot --debug build-iso")
cmd.WriteString(fmt.Sprintf(" --override-name %s", artifact.Name))
cmd.WriteString(" --date=false")
volumeMounts := []corev1.VolumeMount{
{
@@ -157,27 +181,29 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
})
}
cloudImgCmd := fmt.Sprintf(
"/raw-images.sh /rootfs /artifacts/%s.raw",
artifact.Name,
)
var cloudImgCmd strings.Builder
cloudImgCmd.WriteString("auroraboot --debug")
cloudImgCmd.WriteString(" --set 'disk.raw=true'")
cloudImgCmd.WriteString(" --set 'disable_netboot=true'")
cloudImgCmd.WriteString(" --set 'disable_http_server=true'")
cloudImgCmd.WriteString(" --set 'state_dir=/artifacts'")
cloudImgCmd.WriteString(" --set 'container_image=dir:/rootfs'")
if artifact.Spec.CloudConfigRef != nil {
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "cloudconfig",
MountPath: "/iso/iso-overlay/cloud_config.yaml",
MountPath: "/cloud-config.yaml",
SubPath: artifact.Spec.CloudConfigRef.Key,
})
cloudImgCmd += " /iso/iso-overlay/cloud_config.yaml"
cloudImgCmd.WriteString(" --cloud-config /cloud-config.yaml")
}
cloudImgCmd.WriteString(fmt.Sprintf(" && file=$(ls /artifacts/*.raw 2>/dev/null | head -n1) && [ -n \"$file\" ] && mv \"$file\" /artifacts/%s.raw", artifact.Name))
if artifact.Spec.CloudConfigRef != nil || artifact.Spec.GRUBConfig != "" {
cmd = fmt.Sprintf(
"/entrypoint.sh --debug --name %s build-iso --date=false --overlay-iso /iso/iso-overlay --output /artifacts dir:/rootfs",
artifact.Name,
)
cmd.WriteString(" --cloud-config /cloud-config.yaml")
}
cmd.WriteString(" --output /artifacts dir:/rootfs")
buildIsoContainer := corev1.Container{
ImagePullPolicy: corev1.PullAlways,
@@ -186,7 +212,7 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
Image: r.ToolImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
cmd,
cmd.String(),
},
VolumeMounts: volumeMounts,
}
@@ -199,7 +225,7 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
cloudImgCmd,
cloudImgCmd.String(),
},
VolumeMounts: volumeMounts,
}
@@ -211,6 +237,12 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
}}
}
var netbootCmd strings.Builder
netbootCmd.WriteString("auroraboot --debug netboot")
netbootCmd.WriteString(fmt.Sprintf(" /artifacts/%s.iso", artifact.Name))
netbootCmd.WriteString(" /artifacts")
netbootCmd.WriteString(fmt.Sprintf(" %s", artifact.Name))
extractNetboot := corev1.Container{
ImagePullPolicy: corev1.PullAlways,
SecurityContext: &corev1.SecurityContext{Privileged: ptr(true)},
@@ -222,15 +254,24 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
Value: artifact.Spec.NetbootURL,
}},
Args: []string{
fmt.Sprintf(
"/netboot.sh /artifacts/%s.iso /artifacts/%s",
artifact.Name,
artifact.Name,
),
netbootCmd.String(),
},
VolumeMounts: volumeMounts,
}
var azureCmd strings.Builder
azureCmd.WriteString("auroraboot --debug")
azureCmd.WriteString(" --set 'disk.vhd=true'")
azureCmd.WriteString(" --set 'disable_netboot=true'")
azureCmd.WriteString(" --set 'disable_http_server=true'")
azureCmd.WriteString(" --set 'state_dir=/artifacts'")
azureCmd.WriteString(" --set 'container_image=dir:/rootfs'")
if artifact.Spec.CloudConfigRef != nil {
azureCmd.WriteString(" --cloud-config /cloud-config.yaml")
}
azureCmd.WriteString(fmt.Sprintf(" && file=$(ls /artifacts/*.vhd 2>/dev/null | head -n1) && [ -n \"$file\" ] && mv \"$file\" /artifacts/%s.vhd", artifact.Name))
buildAzureCloudImageContainer := corev1.Container{
ImagePullPolicy: corev1.PullAlways,
SecurityContext: &corev1.SecurityContext{Privileged: ptr(true)},
@@ -238,15 +279,24 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
Image: r.ToolImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"/azure.sh /artifacts/%s.raw /artifacts/%s.vhd",
artifact.Name,
artifact.Name,
),
azureCmd.String(),
},
VolumeMounts: volumeMounts,
}
var gceCmd strings.Builder
gceCmd.WriteString("auroraboot --debug")
gceCmd.WriteString(" --set 'disk.gce=true'")
gceCmd.WriteString(" --set 'disable_netboot=true'")
gceCmd.WriteString(" --set 'disable_http_server=true'")
gceCmd.WriteString(" --set 'state_dir=/artifacts'")
gceCmd.WriteString(" --set 'container_image=dir:/rootfs'")
if artifact.Spec.CloudConfigRef != nil {
gceCmd.WriteString(" --cloud-config /cloud-config.yaml")
}
gceCmd.WriteString(fmt.Sprintf(" && file=$(ls /artifacts/*.raw.gce.tar.gz 2>/dev/null | head -n1) && [ -n \"$file\" ] && mv \"$file\" /artifacts/%s.gce.tar.gz", artifact.Name))
buildGCECloudImageContainer := corev1.Container{
ImagePullPolicy: corev1.PullAlways,
SecurityContext: &corev1.SecurityContext{Privileged: ptr(true)},
@@ -254,11 +304,7 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
Image: r.ToolImage,
Command: []string{"/bin/bash", "-cxe"},
Args: []string{
fmt.Sprintf(
"/gce.sh /artifacts/%s.raw /artifacts/%s.gce.raw",
artifact.Name,
artifact.Name,
),
gceCmd.String(),
},
VolumeMounts: volumeMounts,
}
@@ -358,9 +404,15 @@ func (r *OSArtifactReconciler) newBuilderPod(pvcName string, artifact *osbuilder
if artifact.Spec.OSRelease != "" {
podSpec.InitContainers = append(podSpec.InitContainers, osReleaseContainer(r.ToolImage))
}
if artifact.Spec.KairosRelease != "" {
podSpec.InitContainers = append(podSpec.InitContainers, kairosReleaseContainer(r.ToolImage))
}
// build-iso runs as an init container to ensure it completes before build-netboot
// (which extracts artifacts from the ISO). Init containers run sequentially and must
// succeed before regular containers start.
if artifact.Spec.ISO || artifact.Spec.Netboot {
podSpec.Containers = append(podSpec.Containers, buildIsoContainer)
podSpec.InitContainers = append(podSpec.InitContainers, buildIsoContainer)
}
if artifact.Spec.Netboot {

View File

@@ -40,6 +40,7 @@ import (
const (
FinalizerName = "build.kairos.io/osbuilder-finalizer"
CompatibleAurorabootVersion = "v0.14.0"
artifactLabel = "build.kairos.io/artifact"
artifactExporterIndexAnnotation = "build.kairos.io/export-index"
)
@@ -127,6 +128,14 @@ func (r *OSArtifactReconciler) createPVC(ctx context.Context, artifact *osbuilde
return pvc, err
}
if err := r.Create(ctx, pvc); err != nil {
if apierrors.IsAlreadyExists(err) {
// PVC already exists, fetch and return it
existingPVC := &corev1.PersistentVolumeClaim{}
if err := r.Get(ctx, client.ObjectKeyFromObject(pvc), existingPVC); err != nil {
return pvc, err
}
return existingPVC, nil
}
return pvc, err
}

View File

@@ -8,7 +8,6 @@ import (
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/phayes/freeport"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -20,6 +19,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
var _ = Describe("OSArtifactReconciler", func() {
@@ -51,20 +51,15 @@ var _ = Describe("OSArtifactReconciler", func() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(osbuilder.AddToScheme(scheme))
metricsPort, err := freeport.GetFreePort()
Expect(err).ToNot(HaveOccurred())
fmt.Printf("metricsPort = %+v\n", metricsPort)
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: fmt.Sprintf("127.0.0.1:%d", metricsPort),
})
Expect(err).ToNot(HaveOccurred())
r = &OSArtifactReconciler{
ToolImage: "quay.io/kairos/osbuilder-tools:latest",
ToolImage: fmt.Sprintf("quay.io/kairos/auroraboot:%s", CompatibleAurorabootVersion),
}
err = (r).SetupWithManager(mgr)
// Create a direct client (no cache) for tests - we don't need reconciliation
// This avoids the complexity of managing a running manager
directClient, err := client.New(restConfig, client.Options{Scheme: scheme})
Expect(err).ToNot(HaveOccurred())
err = r.InjectClient(directClient)
Expect(err).ToNot(HaveOccurred())
})
@@ -170,4 +165,247 @@ var _ = Describe("OSArtifactReconciler", func() {
})
})
})
Describe("Auroraboot Commands", func() {
BeforeEach(func() {
artifact.Spec.ImageName = "quay.io/kairos/opensuse:leap-15.6-core-amd64-generic-v3.6.0"
})
When("CloudImage is enabled", func() {
BeforeEach(func() {
artifact.Spec.CloudImage = true
})
It("creates build-cloud-image container with correct auroraboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var cloudImageContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-cloud-image" {
cloudImageContainer = &pod.Spec.Containers[i]
break
}
}
Expect(cloudImageContainer).ToNot(BeNil())
Expect(cloudImageContainer.Args).To(HaveLen(1))
Expect(cloudImageContainer.Args[0]).To(ContainSubstring("auroraboot --debug --set 'disk.raw=true'"))
Expect(cloudImageContainer.Args[0]).To(ContainSubstring("--set 'state_dir=/artifacts'"))
Expect(cloudImageContainer.Args[0]).To(ContainSubstring("dir:/rootfs"))
Expect(cloudImageContainer.Args[0]).To(ContainSubstring(fmt.Sprintf("file=$(ls /artifacts/*.raw 2>/dev/null | head -n1) && [ -n \"$file\" ] && mv \"$file\" /artifacts/%s.raw", artifact.Name)))
})
When("CloudConfigRef is set", func() {
BeforeEach(func() {
secretName := artifact.Name + "-cloudconfig"
_, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(),
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: namespace,
},
StringData: map[string]string{
"cloud-config.yaml": "#cloud-config\nusers:\n - name: test",
},
Type: "Opaque",
}, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifact.Spec.CloudConfigRef = &osbuilder.SecretKeySelector{
Name: secretName,
Key: "cloud-config.yaml",
}
})
It("includes cloud-config flag in auroraboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var cloudImageContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-cloud-image" {
cloudImageContainer = &pod.Spec.Containers[i]
break
}
}
Expect(cloudImageContainer).ToNot(BeNil())
Expect(cloudImageContainer.Args[0]).To(ContainSubstring("--cloud-config /cloud-config.yaml"))
})
})
})
When("Netboot is enabled", func() {
BeforeEach(func() {
artifact.Spec.Netboot = true
artifact.Spec.ISO = true
artifact.Spec.NetbootURL = "http://example.com"
})
It("creates build-netboot container with correct auroraboot netboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var netbootContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-netboot" {
netbootContainer = &pod.Spec.Containers[i]
break
}
}
Expect(netbootContainer).ToNot(BeNil())
Expect(netbootContainer.Args).To(HaveLen(1))
Expect(netbootContainer.Args[0]).To(ContainSubstring("auroraboot --debug netboot"))
Expect(netbootContainer.Args[0]).To(ContainSubstring(fmt.Sprintf("/artifacts/%s.iso", artifact.Name)))
Expect(netbootContainer.Args[0]).To(ContainSubstring("/artifacts"))
Expect(netbootContainer.Args[0]).To(ContainSubstring(artifact.Name))
})
})
When("AzureImage is enabled", func() {
BeforeEach(func() {
artifact.Spec.AzureImage = true
})
It("creates build-azure-cloud-image container with correct auroraboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var azureContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-azure-cloud-image" {
azureContainer = &pod.Spec.Containers[i]
break
}
}
Expect(azureContainer).ToNot(BeNil())
Expect(azureContainer.Args).To(HaveLen(1))
Expect(azureContainer.Args[0]).To(ContainSubstring("auroraboot --debug --set 'disk.vhd=true'"))
Expect(azureContainer.Args[0]).To(ContainSubstring("--set 'state_dir=/artifacts'"))
Expect(azureContainer.Args[0]).To(ContainSubstring("dir:/rootfs"))
Expect(azureContainer.Args[0]).To(ContainSubstring(fmt.Sprintf("file=$(ls /artifacts/*.vhd 2>/dev/null | head -n1) && [ -n \"$file\" ] && mv \"$file\" /artifacts/%s.vhd", artifact.Name)))
})
When("CloudConfigRef is set", func() {
BeforeEach(func() {
secretName := artifact.Name + "-cloudconfig"
_, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(),
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: namespace,
},
StringData: map[string]string{
"cloud-config.yaml": "#cloud-config\nusers:\n - name: test",
},
Type: "Opaque",
}, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifact.Spec.CloudConfigRef = &osbuilder.SecretKeySelector{
Name: secretName,
Key: "cloud-config.yaml",
}
})
It("includes cloud-config flag in auroraboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var azureContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-azure-cloud-image" {
azureContainer = &pod.Spec.Containers[i]
break
}
}
Expect(azureContainer).ToNot(BeNil())
Expect(azureContainer.Args[0]).To(ContainSubstring("--cloud-config /cloud-config.yaml"))
})
})
})
When("GCEImage is enabled", func() {
BeforeEach(func() {
artifact.Spec.GCEImage = true
})
It("creates build-gce-cloud-image container with correct auroraboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var gceContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-gce-cloud-image" {
gceContainer = &pod.Spec.Containers[i]
break
}
}
Expect(gceContainer).ToNot(BeNil())
Expect(gceContainer.Args).To(HaveLen(1))
Expect(gceContainer.Args[0]).To(ContainSubstring("auroraboot --debug --set 'disk.gce=true'"))
Expect(gceContainer.Args[0]).To(ContainSubstring("--set 'state_dir=/artifacts'"))
Expect(gceContainer.Args[0]).To(ContainSubstring("dir:/rootfs"))
Expect(gceContainer.Args[0]).To(ContainSubstring(fmt.Sprintf("file=$(ls /artifacts/*.raw.gce.tar.gz 2>/dev/null | head -n1) && [ -n \"$file\" ] && mv \"$file\" /artifacts/%s.gce.tar.gz", artifact.Name)))
})
When("CloudConfigRef is set", func() {
BeforeEach(func() {
secretName := artifact.Name + "-cloudconfig"
_, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(),
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: namespace,
},
StringData: map[string]string{
"cloud-config.yaml": "#cloud-config\nusers:\n - name: test",
},
Type: "Opaque",
}, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifact.Spec.CloudConfigRef = &osbuilder.SecretKeySelector{
Name: secretName,
Key: "cloud-config.yaml",
}
})
It("includes cloud-config flag in auroraboot command", func() {
pvc, err := r.createPVC(context.TODO(), artifact)
Expect(err).ToNot(HaveOccurred())
pod, err := r.createBuilderPod(context.TODO(), artifact, pvc)
Expect(err).ToNot(HaveOccurred())
var gceContainer *corev1.Container
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == "build-gce-cloud-image" {
gceContainer = &pod.Spec.Containers[i]
break
}
}
Expect(gceContainer).ToNot(BeNil())
Expect(gceContainer.Args[0]).To(ContainSubstring("--cloud-config /cloud-config.yaml"))
})
})
})
})
})

View File

@@ -21,10 +21,12 @@ import (
"math/rand"
"path/filepath"
"testing"
"time"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
@@ -73,7 +75,6 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())
})
var _ = AfterSuite(func() {
@@ -100,10 +101,27 @@ func createRandomNamespace(clientset *kubernetes.Clientset) string {
}, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
// Create default service account to avoid pod creation errors
_, err = clientset.CoreV1().ServiceAccounts(name).Create(context.Background(), &v1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Namespace: name,
},
}, metav1.CreateOptions{})
if err != nil && !apierrors.IsAlreadyExists(err) {
Expect(err).ToNot(HaveOccurred())
}
return name
}
func deleteNamepace(clientset *kubernetes.Clientset, name string) {
err := clientset.CoreV1().Namespaces().Delete(context.Background(), name, metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
// Wait for the namespace to be fully deleted to ensure clean test isolation
Eventually(func() bool {
_, err := clientset.CoreV1().Namespaces().Get(context.Background(), name, metav1.GetOptions{})
return apierrors.IsNotFound(err)
}, 2*time.Minute, 1*time.Second).Should(BeTrue(), "namespace should be deleted")
}

30
go.mod
View File

@@ -1,10 +1,10 @@
module github.com/kairos-io/osbuilder
go 1.18
go 1.23.3
require (
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
k8s.io/api v0.24.0
k8s.io/apimachinery v0.24.0
@@ -25,28 +25,28 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
github.com/emicklei/go-restful v2.16.0+incompatible // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/zapr v1.2.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -60,17 +60,17 @@ require (
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/tools v0.16.1 // indirect
golang.org/x/tools v0.24.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

115
go.sum
View File

@@ -127,8 +127,9 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM=
github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -164,10 +165,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk=
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
@@ -180,8 +179,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -244,8 +243,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -269,8 +266,9 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -345,8 +343,9 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -381,31 +380,21 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY=
github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -485,8 +474,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -534,6 +524,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
@@ -552,14 +543,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -596,7 +582,6 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -646,14 +631,8 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -749,26 +728,12 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -778,14 +743,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -853,16 +812,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -997,8 +948,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -18,6 +18,7 @@ package main
import (
"flag"
"fmt"
"os"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
@@ -57,7 +58,7 @@ func main() {
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
// It needs luet inside
flag.StringVar(&toolImage, "tool-image", "quay.io/kairos/osbuilder-tools:latest", "Tool image.")
flag.StringVar(&toolImage, "tool-image", fmt.Sprintf("quay.io/kairos/auroraboot:%s", controllers.CompatibleAurorabootVersion), "Tool image.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,

View File

@@ -10,9 +10,17 @@
],
"timezone": "Europe/Brussels",
"packageRules": [
{
"groupName": "repositories",
"matchPackagePatterns": ["^quay.io/kairos/packages*"]
},
{
"matchPackagePatterns": ["^quay.io/kairos/packages*"],
"versioning": "regex:^(?<major>\\d{12})-git(?<patch>[a-f0-9]{8})-repository\\.yaml$"
},
{
"matchUpdateTypes": ["patch"],
"automerge": true
}
},
]
}

View File

@@ -1,5 +1,6 @@
#!/bin/bash
# TODO: Bump to some recent kubernetes version
KUBE_VERSION=${KUBE_VERSION:-v1.22.7}
CLUSTER_NAME="${CLUSTER_NAME:-kairos-osbuilder-e2e}"
@@ -30,4 +31,4 @@ EXTERNAL_IP=$(kubectl get nodes -o jsonpath='{.items[].status.addresses[?(@.type
export EXTERNAL_IP
export BRIDGE_IP="172.18.0.1"
kubectl get nodes -o wide
cd $ROOT_DIR/tests && $GINKGO -r -v ./e2e
cd $ROOT_DIR/tests && $GINKGO -r -v ./e2e

View File

@@ -0,0 +1,356 @@
package e2e_test
import (
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
. "github.com/onsi/ginkgo/v2"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
var _ = Describe("Artifact Format Tests", func() {
var tc *TestClients
BeforeEach(func() {
tc = SetupTestClients()
})
Describe("CloudImage (Raw Disk)", func() {
var artifactName string
var artifactLabelSelector labels.Selector
BeforeEach(func() {
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "cloudimage-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/opensuse:leap-15.6-core-amd64-generic-v3.6.0",
CloudImage: true,
Exporters: []batchv1.JobSpec{
{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Name: "verify",
Image: "debian:latest",
Command: []string{"bash"},
Args: []string{
"-xec",
`
set -e
# Check that raw file exists
raw_file=$(ls /artifacts/*.raw 2>/dev/null | head -n1)
if [ -z "$raw_file" ]; then
echo "No .raw file found"
exit 1
fi
# Check that it's a valid disk image (has non-zero size)
if [ ! -s "$raw_file" ]; then
echo "Raw file is empty"
exit 1
fi
# Check file size is reasonable (at least 100MB)
size=$(stat -c%s "$raw_file")
if [ "$size" -lt 104857600 ]; then
echo "Raw file too small: $size bytes"
exit 1
fi
echo "Raw disk verification passed: $raw_file"
`,
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "artifacts",
ReadOnly: true,
MountPath: "/artifacts",
},
},
},
},
},
},
},
},
},
}
artifactName, artifactLabelSelector = tc.CreateArtifact(artifact)
})
It("builds a valid raw disk image", func() {
tc.WaitForBuildCompletion(artifactName, artifactLabelSelector)
tc.WaitForExportCompletion(artifactLabelSelector)
tc.Cleanup(artifactName, artifactLabelSelector)
})
})
Describe("Netboot", func() {
var artifactName string
var artifactLabelSelector labels.Selector
BeforeEach(func() {
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "netboot-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/opensuse:leap-15.6-core-amd64-generic-v3.6.0",
ISO: true,
Netboot: true,
NetbootURL: "http://example.com",
Exporters: []batchv1.JobSpec{
{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Name: "verify",
Image: "debian:latest",
Command: []string{"bash"},
Args: []string{
"-xec",
`
set -e
# Check for kernel file (pattern: *-kernel)
kernel_file=$(ls /artifacts/*-kernel 2>/dev/null | head -n1)
if [ -z "$kernel_file" ]; then
echo "No kernel file found (pattern: *-kernel)"
ls -la /artifacts/ || true
exit 1
fi
# Check for initrd file (pattern: *-initrd)
initrd_file=$(ls /artifacts/*-initrd 2>/dev/null | head -n1)
if [ -z "$initrd_file" ]; then
echo "No initrd file found (pattern: *-initrd)"
ls -la /artifacts/ || true
exit 1
fi
# Check for squashfs file (pattern: *.squashfs)
squashfs_file=$(ls /artifacts/*.squashfs 2>/dev/null | head -n1)
if [ -z "$squashfs_file" ]; then
echo "No squashfs file found (pattern: *.squashfs)"
ls -la /artifacts/ || true
exit 1
fi
# Verify files are non-empty
for file in "$kernel_file" "$initrd_file" "$squashfs_file"; do
if [ ! -s "$file" ]; then
echo "File is empty: $file"
exit 1
fi
done
echo "Netboot artifacts verification passed"
echo "Kernel: $kernel_file"
echo "Initrd: $initrd_file"
echo "Squashfs: $squashfs_file"
`,
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "artifacts",
ReadOnly: true,
MountPath: "/artifacts",
},
},
},
},
},
},
},
},
},
}
artifactName, artifactLabelSelector = tc.CreateArtifact(artifact)
})
It("builds valid netboot artifacts", func() {
tc.WaitForBuildCompletion(artifactName, artifactLabelSelector)
tc.WaitForExportCompletion(artifactLabelSelector)
tc.Cleanup(artifactName, artifactLabelSelector)
})
})
Describe("AzureImage (VHD)", func() {
var artifactName string
var artifactLabelSelector labels.Selector
BeforeEach(func() {
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "azure-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/opensuse:leap-15.6-core-amd64-generic-v3.6.0",
AzureImage: true,
Exporters: []batchv1.JobSpec{
{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Name: "verify",
Image: "debian:latest",
Command: []string{"bash"},
Args: []string{
"-xec",
`
set -e
# Check that VHD file exists
vhd_file=$(ls /artifacts/*.vhd 2>/dev/null | head -n1)
if [ -z "$vhd_file" ]; then
echo "No .vhd file found"
exit 1
fi
# Check that it's non-empty
if [ ! -s "$vhd_file" ]; then
echo "VHD file is empty"
exit 1
fi
# Check file size is reasonable (at least 100MB)
size=$(stat -c%s "$vhd_file")
if [ "$size" -lt 104857600 ]; then
echo "VHD file too small: $size bytes"
exit 1
fi
# Check VHD footer (last 512 bytes should contain VHD signature)
# VHD footer starts at offset -512 and contains "conectix" string
tail -c 512 "$vhd_file" | grep -q "conectix" || {
echo "VHD file does not have valid VHD footer"
exit 1
}
echo "VHD verification passed: $vhd_file"
`,
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "artifacts",
ReadOnly: true,
MountPath: "/artifacts",
},
},
},
},
},
},
},
},
},
}
artifactName, artifactLabelSelector = tc.CreateArtifact(artifact)
})
It("builds a valid Azure VHD image", func() {
tc.WaitForBuildCompletion(artifactName, artifactLabelSelector)
tc.WaitForExportCompletion(artifactLabelSelector)
tc.Cleanup(artifactName, artifactLabelSelector)
})
})
Describe("GCEImage", func() {
var artifactName string
var artifactLabelSelector labels.Selector
BeforeEach(func() {
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
Kind: "OSArtifact",
APIVersion: osbuilder.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "gce-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/opensuse:leap-15.6-core-amd64-generic-v3.6.0",
GCEImage: true,
Exporters: []batchv1.JobSpec{
{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
Containers: []corev1.Container{
{
Name: "verify",
Image: "debian:latest",
Command: []string{"bash"},
Args: []string{
"-xec",
`
set -e
# Check that GCE tar.gz file exists
gce_file=$(ls /artifacts/*.gce.tar.gz 2>/dev/null | head -n1)
if [ -z "$gce_file" ]; then
echo "No .gce.tar.gz file found"
exit 1
fi
# Check that it's non-empty
if [ ! -s "$gce_file" ]; then
echo "GCE tar.gz file is empty"
exit 1
fi
# Extract and verify it contains disk.raw
temp_dir=$(mktemp -d)
trap "rm -rf $temp_dir" EXIT
tar -xzf "$gce_file" -C "$temp_dir"
if [ ! -f "$temp_dir/disk.raw" ]; then
echo "GCE archive does not contain disk.raw"
exit 1
fi
# Verify disk.raw is non-empty and reasonable size
if [ ! -s "$temp_dir/disk.raw" ]; then
echo "disk.raw in archive is empty"
exit 1
fi
size=$(stat -c%s "$temp_dir/disk.raw")
if [ "$size" -lt 104857600 ]; then
echo "disk.raw too small: $size bytes"
exit 1
fi
echo "GCE verification passed: $gce_file"
`,
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "artifacts",
ReadOnly: true,
MountPath: "/artifacts",
},
},
},
},
},
},
},
},
},
}
artifactName, artifactLabelSelector = tc.CreateArtifact(artifact)
})
It("builds a valid GCE image", func() {
tc.WaitForBuildCompletion(artifactName, artifactLabelSelector)
tc.WaitForExportCompletion(artifactLabelSelector)
tc.Cleanup(artifactName, artifactLabelSelector)
})
})
})

View File

@@ -1,41 +1,21 @@
package e2e_test
import (
"context"
"time"
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
ctrl "sigs.k8s.io/controller-runtime"
)
var _ = Describe("ISO build test", func() {
var artifactName string
var artifacts, pods, pvcs, jobs dynamic.ResourceInterface
var scheme *runtime.Scheme
var artifactLabelSelector labels.Selector
var tc *TestClients
BeforeEach(func() {
k8s := dynamic.NewForConfigOrDie(ctrl.GetConfigOrDie())
scheme = runtime.NewScheme()
err := osbuilder.AddToScheme(scheme)
Expect(err).ToNot(HaveOccurred())
artifacts = k8s.Resource(schema.GroupVersionResource{Group: osbuilder.GroupVersion.Group, Version: osbuilder.GroupVersion.Version, Resource: "osartifacts"}).Namespace("default")
pods = k8s.Resource(schema.GroupVersionResource{Group: corev1.GroupName, Version: corev1.SchemeGroupVersion.Version, Resource: "pods"}).Namespace("default")
pvcs = k8s.Resource(schema.GroupVersionResource{Group: corev1.GroupName, Version: corev1.SchemeGroupVersion.Version, Resource: "persistentvolumeclaims"}).Namespace("default")
jobs = k8s.Resource(schema.GroupVersionResource{Group: batchv1.GroupName, Version: batchv1.SchemeGroupVersion.Version, Resource: "jobs"}).Namespace("default")
tc = SetupTestClients()
artifact := &osbuilder.OSArtifact{
TypeMeta: metav1.TypeMeta{
@@ -46,7 +26,7 @@ var _ = Describe("ISO build test", func() {
GenerateName: "simple-",
},
Spec: osbuilder.OSArtifactSpec{
ImageName: "quay.io/kairos/core-opensuse:latest",
ImageName: "quay.io/kairos/opensuse:leap-15.6-core-amd64-generic-v3.6.0",
ISO: true,
DiskSize: "",
Exporters: []batchv1.JobSpec{
@@ -76,87 +56,12 @@ var _ = Describe("ISO build test", func() {
},
}
uArtifact := unstructured.Unstructured{}
uArtifact.Object, _ = runtime.DefaultUnstructuredConverter.ToUnstructured(artifact)
resp, err := artifacts.Create(context.TODO(), &uArtifact, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifactName = resp.GetName()
artifactLabelSelectorReq, err := labels.NewRequirement("build.kairos.io/artifact", selection.Equals, []string{artifactName})
Expect(err).ToNot(HaveOccurred())
artifactLabelSelector = labels.NewSelector().Add(*artifactLabelSelectorReq)
artifactName, artifactLabelSelector = tc.CreateArtifact(artifact)
})
It("works", func() {
By("starting the build")
Eventually(func(g Gomega) {
w, err := pods.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
By("exporting the artifacts")
Eventually(func(g Gomega) {
w, err := jobs.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
By("building the artifacts successfully")
Eventually(func(g Gomega) {
w, err := artifacts.Watch(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
var artifact osbuilder.OSArtifact
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = !ok
if event.Type == watch.Modified && event.Object.(*unstructured.Unstructured).GetName() == artifactName {
err := scheme.Convert(event.Object, &artifact, nil)
Expect(err).ToNot(HaveOccurred())
stopped = artifact.Status.Phase == osbuilder.Ready
}
}
}).WithTimeout(time.Hour).Should(Succeed())
By("cleaning up resources on deletion")
err := artifacts.Delete(context.TODO(), artifactName, metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
Eventually(func(g Gomega) int {
res, err := artifacts.List(context.TODO(), metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := pods.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := pvcs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := jobs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
tc.WaitForBuildCompletion(artifactName, artifactLabelSelector)
tc.WaitForExportCompletion(artifactLabelSelector)
tc.Cleanup(artifactName, artifactLabelSelector)
})
})

View File

@@ -1,13 +1,160 @@
package e2e_test
import (
"context"
"testing"
"time"
osbuilder "github.com/kairos-io/osbuilder/api/v1alpha2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
ctrl "sigs.k8s.io/controller-runtime"
)
func TestE2e(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "kairos-operator e2e test Suite")
}
// TestClients holds common Kubernetes clients used across e2e tests
type TestClients struct {
Artifacts dynamic.ResourceInterface
Pods dynamic.ResourceInterface
PVCs dynamic.ResourceInterface
Jobs dynamic.ResourceInterface
Scheme *runtime.Scheme
}
// SetupTestClients initializes and returns common Kubernetes clients
func SetupTestClients() *TestClients {
k8s := dynamic.NewForConfigOrDie(ctrl.GetConfigOrDie())
scheme := runtime.NewScheme()
err := osbuilder.AddToScheme(scheme)
Expect(err).ToNot(HaveOccurred())
return &TestClients{
Artifacts: k8s.Resource(schema.GroupVersionResource{
Group: osbuilder.GroupVersion.Group,
Version: osbuilder.GroupVersion.Version,
Resource: "osartifacts",
}).Namespace("default"),
Pods: k8s.Resource(schema.GroupVersionResource{
Group: corev1.GroupName,
Version: corev1.SchemeGroupVersion.Version,
Resource: "pods",
}).Namespace("default"),
PVCs: k8s.Resource(schema.GroupVersionResource{
Group: corev1.GroupName,
Version: corev1.SchemeGroupVersion.Version,
Resource: "persistentvolumeclaims",
}).Namespace("default"),
Jobs: k8s.Resource(schema.GroupVersionResource{
Group: batchv1.GroupName,
Version: batchv1.SchemeGroupVersion.Version,
Resource: "jobs",
}).Namespace("default"),
Scheme: scheme,
}
}
// CreateArtifact creates an OSArtifact and returns its name and label selector
func (tc *TestClients) CreateArtifact(artifact *osbuilder.OSArtifact) (string, labels.Selector) {
uArtifact := unstructured.Unstructured{}
uArtifact.Object, _ = runtime.DefaultUnstructuredConverter.ToUnstructured(artifact)
resp, err := tc.Artifacts.Create(context.TODO(), &uArtifact, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred())
artifactName := resp.GetName()
artifactLabelSelectorReq, err := labels.NewRequirement("build.kairos.io/artifact", selection.Equals, []string{artifactName})
Expect(err).ToNot(HaveOccurred())
artifactLabelSelector := labels.NewSelector().Add(*artifactLabelSelectorReq)
return artifactName, artifactLabelSelector
}
// WaitForBuildCompletion waits for the build pod to complete and artifact to be ready
func (tc *TestClients) WaitForBuildCompletion(artifactName string, artifactLabelSelector labels.Selector) {
By("waiting for build pod to complete")
Eventually(func(g Gomega) {
w, err := tc.Pods.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
g.Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
By("waiting for artifact to be ready")
Eventually(func(g Gomega) {
w, err := tc.Artifacts.Watch(context.TODO(), metav1.ListOptions{})
g.Expect(err).ToNot(HaveOccurred())
var artifact osbuilder.OSArtifact
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = !ok
if event.Type == watch.Modified && event.Object.(*unstructured.Unstructured).GetName() == artifactName {
err := tc.Scheme.Convert(event.Object, &artifact, nil)
g.Expect(err).ToNot(HaveOccurred())
stopped = artifact.Status.Phase == osbuilder.Ready
}
}
}).WithTimeout(time.Hour).Should(Succeed())
}
// WaitForExportCompletion waits for the export job to complete
func (tc *TestClients) WaitForExportCompletion(artifactLabelSelector labels.Selector) {
By("waiting for export job to complete")
Eventually(func(g Gomega) {
w, err := tc.Jobs.Watch(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
g.Expect(err).ToNot(HaveOccurred())
var stopped bool
for !stopped {
event, ok := <-w.ResultChan()
stopped = event.Type != watch.Deleted && event.Type != watch.Error || !ok
}
}).WithTimeout(time.Hour).Should(Succeed())
}
// Cleanup deletes the artifact and waits for all related resources to be cleaned up
func (tc *TestClients) Cleanup(artifactName string, artifactLabelSelector labels.Selector) {
By("cleaning up resources")
err := tc.Artifacts.Delete(context.TODO(), artifactName, metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
Eventually(func(g Gomega) int {
res, err := tc.Artifacts.List(context.TODO(), metav1.ListOptions{})
g.Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := tc.Pods.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
g.Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := tc.PVCs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
g.Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
Eventually(func(g Gomega) int {
res, err := tc.Jobs.List(context.TODO(), metav1.ListOptions{LabelSelector: artifactLabelSelector.String()})
g.Expect(err).ToNot(HaveOccurred())
return len(res.Items)
}).WithTimeout(time.Minute).Should(Equal(0))
}

View File

@@ -1,114 +0,0 @@
# https://quay.io/repository/kairos/packages?tab=tags&tag=latest
ARG LEAP_VERSION=15.5
ARG LUET_VERSION=0.35.0
ARG ENKI_VERSION=v0.0.16
FROM quay.io/luet/base:$LUET_VERSION AS luet
FROM quay.io/kairos/enki:${ENKI_VERSION} as enki
FROM opensuse/leap:$LEAP_VERSION as default
RUN zypper ref && zypper dup -y
## ISO+ Arm image + Netboot + cloud images Build depedencies
RUN zypper ref && zypper in -y bc qemu-tools jq cdrtools docker git curl gptfdisk kpartx sudo xfsprogs parted util-linux-systemd e2fsprogs curl util-linux udev rsync grub2 dosfstools grub2-x86_64-efi squashfs mtools xorriso lvm2 zstd
COPY --from=luet /usr/bin/luet /usr/bin/luet
ENV LUET_NOLOCK=true
ENV TMPDIR=/tmp
ARG TARGETARCH
# copy both arches
COPY luet-arm64.yaml /tmp/luet-arm64.yaml
COPY luet-amd64.yaml /tmp/luet-amd64.yaml
# Set the default luet config to the current build arch
RUN mkdir -p /etc/luet/
RUN cp /tmp/luet-${TARGETARCH}.yaml /etc/luet/luet.yaml
## Live CD artifacts
RUN luet install -y livecd/grub2 --system-target /grub2
RUN luet install -y livecd/grub2-efi-image --system-target /efi
## RPI64
RUN luet install -y firmware/raspberrypi-firmware firmware/raspberrypi-firmware-config firmware/raspberrypi-firmware-dt --system-target /rpi/
COPY luet-arm64-old.yaml /tmp/luet-arm64.yaml
COPY luet-amd64-old.yaml /tmp/luet-amd64.yaml
RUN cp /tmp/luet-${TARGETARCH}.yaml /etc/luet/luet.yaml
RUN luet install -y firmware/u-boot-rpi64 --system-target /rpi/
COPY luet-arm64.yaml /tmp/luet-arm64.yaml
COPY luet-amd64.yaml /tmp/luet-amd64.yaml
## PineBook64 Pro
RUN luet install -y arm-vendor-blob/u-boot-rockchip --system-target /pinebookpro/u-boot
## Odroid fw
RUN luet install -y firmware/odroid-c2 --system-target /firmware/odroid-c2
## RAW images for current arch
RUN luet install -y static/grub-efi --system-target /raw/grub
RUN luet install -y static/grub-config --system-target /raw/grubconfig
RUN luet install -y static/grub-artifacts --system-target /raw/grubartifacts
## RAW images for arm64
# Luet will install this artifacts from the current arch repo, so in x86 it will
# get them from the x86 repo and we want it to do it from the arm64 repo, even on x86
# so we use the arm64 luet config and use that to install those on x86
# This is being used by the prepare_arm_images.sh and build-arch-image.sh scripts
RUN luet install --config /tmp/luet-arm64.yaml -y static/grub-efi --system-target /arm/raw/grubefi
RUN luet install --config /tmp/luet-arm64.yaml -y static/grub-config --system-target /arm/raw/grubconfig
RUN luet install --config /tmp/luet-arm64.yaml -y static/grub-artifacts --system-target /arm/raw/grubartifacts
# kairos-agent so we can use the pull-image
RUN luet install -y system/kairos-agent
# remove luet tmp files. Side effect of setting the system-target is that it treats it as a root fs
# so temporal files are stored in each dir
RUN rm -Rf /grub2/var/tmp
RUN rm -Rf /grub2/var/cache
RUN rm -Rf /efi/var/tmp
RUN rm -Rf /efi/var/cache
RUN rm -Rf /rpi/var/tmp
RUN rm -Rf /rpi/var/cache
RUN rm -Rf /pinebookpro/u-boot/var/tmp
RUN rm -Rf /pinebookpro/u-boot/var/cache
RUN rm -Rf /firmware/odroid-c2/var/tmp
RUN rm -Rf /firmware/odroid-c2/var/cache
RUN rm -Rf /raw/grub/var/tmp
RUN rm -Rf /raw/grub/var/cache
RUN rm -Rf /raw/grubconfig/var/tmp
RUN rm -Rf /raw/grubconfig/var/cache
RUN rm -Rf /raw/grubartifacts/var/tmp
RUN rm -Rf /raw/grubartifacts/var/cache
RUN rm -Rf /arm/raw/grubefi/var/tmp
RUN rm -Rf /arm/raw/grubefi/var/cache
RUN rm -Rf /arm/raw/grubconfig/var/tmp
RUN rm -Rf /arm/raw/grubconfig/var/cache
RUN rm -Rf /arm/raw/grubartifacts/var/tmp
RUN rm -Rf /arm/raw/grubartifacts/var/cache
RUN mkdir /config
# ISO build config
COPY ./config.yaml /config/manifest.yaml
COPY ./entrypoint.sh /entrypoint.sh
COPY ./add-cloud-init.sh /add-cloud-init.sh
COPY ./os-release.tmpl /os-release.tmpl
COPY ./ipxe.tmpl /ipxe.tmpl
COPY ./update-os-release.sh /update-os-release.sh
# ARM helpers
COPY ./build-arm-image.sh /build-arm-image.sh
COPY ./arm /arm
COPY ./prepare_arm_images.sh /prepare_arm_images.sh
# RAW images helpers
COPY ./gce.sh /gce.sh
COPY ./raw-images.sh /raw-images.sh
COPY ./azure.sh /azure.sh
COPY ./netboot.sh /netboot.sh
COPY defaults.yaml /defaults.yaml
COPY --from=enki /enki /usr/bin/enki
ENTRYPOINT [ "/entrypoint.sh" ]

View File

@@ -1,18 +0,0 @@
#!/bin/bash
# docker run --entrypoint /add-cloud-init.sh -v $PWD:/work -ti --rm test https://github.com/kairos-io/kairos/releases/download/v1.1.2/kairos-alpine-v1.1.2.iso /work/test.iso /work/config.yaml
set -ex
ISO=$1
OUT=$2
CONFIG=$3
case ${ISO} in
http*)
curl -L "${ISO}" -o in.iso
ISO=in.iso
;;
esac
# Needs xorriso >=1.5.4
xorriso -indev $ISO -outdev $OUT -map $CONFIG /config.yaml -boot_image any replay

View File

@@ -1,13 +0,0 @@
#!/bin/bash
image=$1
if [ -z "$image" ]; then
echo "No image specified"
exit 1
fi
# conv=notrunc ?
dd if=/firmware/odroid-c2/bl1.bin.hardkernel of=$image conv=fsync bs=1 count=442
dd if=/firmware/odroid-c2/bl1.bin.hardkernel of=$image conv=fsync bs=512 skip=1 seek=1
dd if=/firmware/odroid-c2/u-boot.odroidc2 of=$image conv=fsync bs=512 seek=97

View File

@@ -1,19 +0,0 @@
#!/bin/bash
image=$1
if [ -z "$image" ]; then
echo "No image specified"
exit 1
fi
LOADER_OFFSET=${LOADER_OFFSET:-"64"}
LOADER_IMAGE=${LOADER_IMAGE:-"idbloader.img"}
UBOOT_IMAGE=${UBOOT_IMAGE:-"u-boot.itb"}
UBOOT_OFFSET=${UBOOT_OFFSET:-"16384"}
echo "Writing idbloader"
dd conv=notrunc if=/pinebookpro/u-boot/usr/lib/u-boot/pinebook-pro-rk3399/${LOADER_IMAGE} of="$image" conv=fsync seek=${LOADER_OFFSET}
echo "Writing u-boot image"
dd conv=notrunc if=/pinebookpro/u-boot/usr/lib/u-boot/pinebook-pro-rk3399/${UBOOT_IMAGE} of="$image" conv=fsync seek=${UBOOT_OFFSET}
sync $image

View File

@@ -1,22 +0,0 @@
#!/bin/bash
partprobe
kpartx -va $DRIVE
image=$1
if [ -z "$image" ]; then
echo "No image specified"
exit 1
fi
set -ax
TEMPDIR="$(mktemp -d)"
echo $TEMPDIR
mount "${device}p1" "${TEMPDIR}"
# Copy all rpi files
cp -rfv /rpi/* $TEMPDIR
umount "${TEMPDIR}"

View File

@@ -1,22 +0,0 @@
#!/bin/bash
partprobe
kpartx -va $DRIVE
image=$1
if [ -z "$image" ]; then
echo "No image specified"
exit 1
fi
set -ax
TEMPDIR="$(mktemp -d)"
echo $TEMPDIR
mount "${device}p1" "${TEMPDIR}"
# Copy all rpi files
cp -rfv /rpi/* $TEMPDIR
umount "${TEMPDIR}"

View File

@@ -1,17 +0,0 @@
#!/bin/bash
# Transform a raw image disk to azure vhd
RAWIMAGE="$1"
VHDDISK="${2:-disk.vhd}"
cp -rf $RAWIMAGE $VHDDISK.work
MB=$((1024*1024))
size=$(qemu-img info -f raw --output json "$RAWIMAGE" | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}')
# shellcheck disable=SC2004
ROUNDED_SIZE=$(((($size+$MB-1)/$MB)*$MB))
echo "Resizing raw image to $ROUNDED_SIZE"
qemu-img resize -f raw "$VHDDISK.work" $ROUNDED_SIZE
echo "Converting $RAWIMAGE to $VHDDISK"
qemu-img convert -f raw -o subformat=fixed,force_size -O vpc "$VHDDISK.work" "$VHDDISK"
echo "Done"
rm -rf "$VHDDISK.work"

View File

@@ -1,27 +0,0 @@
#!/bin/bash
# Generates raw bootable images with qemu
set -ex
CLOUD_INIT=${1:-cloud_init.yaml}
QEMU=${QEMU:-qemu-system-x86_64}
ISO=${2:-iso.iso}
mkdir -p build
pushd build
touch meta-data
cp -rfv $CLOUD_INIT user-data
mkisofs -output ci.iso -volid cidata -joliet -rock user-data meta-data
truncate -s "+$((20000*1024*1024))" disk.raw
${QEMU} -m 8096 -smp cores=2 \
-nographic -cpu host \
-serial mon:stdio \
-rtc base=utc,clock=rt \
-chardev socket,path=qga.sock,server,nowait,id=qga0 \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \
-drive if=virtio,media=disk,file=disk.raw \
-drive format=raw,media=cdrom,readonly=on,file=$ISO \
-drive format=raw,media=cdrom,readonly=on,file=ci.iso \
-boot d \
-enable-kvm

View File

@@ -1,511 +0,0 @@
#!/bin/bash
## This is a re-adaptation of https://github.com/rancher/elemental-toolkit/blob/main/images/arm-img-builder.sh
set -ex
load_vars() {
model=${MODEL:-odroid_c2}
disable_lvm=${DISABLE_LVM:-false}
directory=${DIRECTORY:-}
output_image="${OUTPUT_IMAGE:-arm.img}"
# Img creation options. Size is in MB for all of the vars below
size="${SIZE:-7608}"
state_size="${STATE_SIZE:-4992}"
oem_size="${OEM_SIZE:-64}"
recovery_size="${RECOVERY_SIZE:-2192}"
default_active_size="${DEFAULT_ACTIVE_SIZE:-2400}"
menu_entry="${DEFAULT_MENU_ENTRY:-Kairos}"
## Repositories
final_repo="${FINAL_REPO:-quay.io/costoolkit/releases-teal-arm64}"
repo_type="${REPO_TYPE:-docker}"
# Warning: these default values must be aligned with the values provided
# in 'packages/cos-config/cos-config', provide an environment file using the
# --cos-config flag if different values are needed.
: "${OEM_LABEL:=COS_OEM}"
: "${RECOVERY_LABEL:=COS_RECOVERY}"
: "${ACTIVE_LABEL:=COS_ACTIVE}"
: "${PASSIVE_LABEL:=COS_PASSIVE}"
: "${PERSISTENT_LABEL:=COS_PERSISTENT}"
: "${SYSTEM_LABEL:=COS_SYSTEM}"
: "${STATE_LABEL:=COS_STATE}"
}
cleanup() {
sync
sync
sleep 5
sync
if [ -n "$EFI" ]; then
rm -rf $EFI
fi
if [ -n "$RECOVERY" ]; then
rm -rf $RECOVERY
fi
if [ -n "$STATEDIR" ]; then
rm -rf $STATEDIR
fi
if [ -n "$TARGET" ]; then
umount $TARGET || true
umount $LOOP || true
rm -rf $TARGET
fi
if [ -n "$WORKDIR" ]; then
rm -rf $WORKDIR
fi
if [ -n "$DRIVE" ]; then
umount $DRIVE || true
fi
if [ -n "$recovery" ]; then
umount $recovery || true
fi
if [ -n "$state" ]; then
umount $state || true
fi
if [ -n "$efi" ]; then
umount $efi || true
fi
if [ -n "$oem" ]; then
umount $oem || true
fi
losetup -D "${LOOP}" || true;
dmsetup remove KairosVG-oem || true;
dmsetup remove KairosVG-recovery || true;
}
ensure_dir_structure() {
local target=$1
for mnt in /sys /proc /dev /tmp /boot /usr/local /oem
do
if [ ! -d "${target}${mnt}" ]; then
mkdir -p ${target}${mnt}
fi
done
}
usage()
{
echo "Usage: $0 [options] image.img"
echo ""
echo "Example: $0 --cos-config cos-config --model odroid-c2 --docker-image <image> output.img"
echo ""
echo "Flags:"
echo " --cos-config: (optional) Specifies a cos-config file for required environment variables"
echo " --config: (optional) Specify a cloud-init config file to embed into the final image"
echo " --manifest: (optional) Specify a manifest file to customize efi/grub packages installed into the image"
echo " --size: (optional) Image size (MB)"
echo " --state-partition-size: (optional) Size of the state partition (MB)"
echo " --recovery-partition-size: (optional) Size of the recovery partition (MB)"
echo " --images-size: (optional) Size of the active/passive/recovery images (MB)"
echo " --docker-image: (optional) A container image which will be used for active/passive/recovery system"
echo " --local: (optional) Use local repository when building"
echo " --directory: (optional) A directory which will be used for active/passive/recovery system"
echo " --model: (optional) The board model"
echo " --efi-dir: (optional) A directory with files which will be added to the efi partition"
echo " --disable-lvm: (optional- no arguments) LVM for the recovery and oem partitions will be disabled"
echo " --use-lvm: (deprecated and ignored. Kept for backwards compatibility)"
exit 1
}
get_url()
{
FROM=$1
TO=$2
case $FROM in
ftp*|http*|tftp*)
n=0
attempts=5
until [ "$n" -ge "$attempts" ]
do
curl -o $TO -fL ${FROM} && break
n=$((n+1))
echo "Failed to download, retry attempt ${n} out of ${attempts}"
sleep 2
done
;;
*)
cp -f $FROM $TO
;;
esac
}
trap "cleanup" 1 2 3 6 14 15 EXIT
load_vars
while [ "$#" -gt 0 ]; do
case $1 in
--cos-config)
shift 1
cos_config=$1
;;
--config)
shift 1
config=$1
;;
--manifest)
shift 1
manifest=$1
;;
--size)
shift 1
size=$1
;;
--local)
local_build=true
;;
--state-partition-size)
shift 1
state_size=$1
;;
--recovery-partition-size)
shift 1
recovery_size=$1
;;
--images-size)
shift 1
default_active_size=$1
;;
--docker-image)
shift 1
CONTAINER_IMAGE=$1
;;
--directory)
shift 1
directory=$1
;;
--model)
shift 1
model=$1
;;
--efi-dir)
shift 1
efi_dir=$1
;;
--final-repo)
shift 1
final_repo=$1
;;
--repo-type)
shift 1
repo_type=$1
;;
--disable-lvm)
disable_lvm=true
;;
--use-lvm)
disable_lvm=false
;;
-h)
usage
;;
--help)
usage
;;
*)
if [ "$#" -gt 2 ]; then
usage
fi
output_image=$1
break
;;
esac
shift 1
done
if [ "$model" == "rpi64" ];then
echo "rpi64 model not supported anymore, please select either rpi3 or rpi4"
exit 1
fi
if [ "$model" == "rpi3" ] || [ "$model" == "rpi4" ]; then
container_image=${CONTAINER_IMAGE:-quay.io/costoolkit/examples:rpi-latest}
else
# Odroid C2 image contains kernel-default-extra, might have broader support
container_image=${CONTAINER_IMAGE:-quay.io/costoolkit/examples:odroid-c2-latest}
fi
if [ -n "$cos_config" ] && [ -e "$cos_config" ]; then
# shellcheck source=/dev/null
source "$cos_config"
fi
if [ -z "$output_image" ]; then
echo "No image file specified"
exit 1
fi
if [ -n "$manifest" ]; then
YQ_PACKAGES_COMMAND=(yq e -o=json "$manifest")
final_repo=${final_repo:-$(yq e ".raw_disk.$model.repo" "${manifest}")}
fi
echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
echo "Image Size: $size MB."
echo "Recovery Partition: $recovery_size."
echo "State Partition: $state_size MB."
echo "Images size (active/passive/recovery.img): $default_active_size MB."
echo "Model: $model"
if [ -n "$container_image" ] && [ -z "$directory" ]; then
echo "Container image: $container_image"
fi
if [ -n "$directory" ]; then
echo "Root from directory: $directory"
fi
echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
# Temp dir used during build
WORKDIR=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
#ROOT_DIR=$(git rev-parse --show-toplevel)
TARGET=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
STATEDIR=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
export WORKDIR
# Prepare active.img
echo ">> Preparing active.img"
mkdir -p ${STATEDIR}/cOS
dd if=/dev/zero of=${STATEDIR}/cOS/active.img bs=1M count=$default_active_size
mkfs.ext2 ${STATEDIR}/cOS/active.img -L ${ACTIVE_LABEL}
sync
LOOP=$(losetup --show -f ${STATEDIR}/cOS/active.img)
if [ -z "$LOOP" ]; then
echo "No device"
exit 1
fi
mount -t ext2 $LOOP $TARGET
ensure_dir_structure $TARGET
# Download the container image
if [ -z "$directory" ]; then
echo ">>> Downloading container image"
kairos-agent pull-image $container_image $TARGET
else
echo ">>> Copying files from $directory"
rsync -axq --exclude='host' --exclude='mnt' --exclude='proc' --exclude='sys' --exclude='dev' --exclude='tmp' ${directory}/ $TARGET
fi
# We copy the grubmenu.cfg to a temporary location to be copied later in the state partition
# https://github.com/kairos-io/kairos/blob/62c67e3e61d49435c362014522e5c6696335376f/overlay/files/system/oem/08_grub.yaml#L105
# This is a hack and we need a better way: https://github.com/kairos-io/kairos/issues/1427
tmpgrubconfig=$(mktemp /tmp/grubmeny.cfg.XXXXXX)
cp -rfv $TARGET/etc/kairos/branding/grubmenu.cfg "${tmpgrubconfig}"
umount $TARGET
sync
if [ -n "$LOOP" ]; then
losetup -d $LOOP
fi
echo ">> Preparing passive.img"
cp -rfv ${STATEDIR}/cOS/active.img ${STATEDIR}/cOS/passive.img
tune2fs -L ${PASSIVE_LABEL} ${STATEDIR}/cOS/passive.img
# Preparing recovery
echo ">> Preparing recovery.img"
RECOVERY=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
if [ -z "$RECOVERY" ]; then
echo "No recovery directory"
exit 1
fi
mkdir -p ${RECOVERY}/cOS
cp -rfv ${STATEDIR}/cOS/active.img ${RECOVERY}/cOS/recovery.img
tune2fs -L ${SYSTEM_LABEL} ${RECOVERY}/cOS/recovery.img
# Install real grub config to recovery
cp -rfv /arm/raw/grubconfig/* $RECOVERY
mkdir -p $RECOVERY/grub2/fonts
cp -rfv /arm/raw/grubartifacts/* $RECOVERY/grub2
mv $RECOVERY/grub2/*pf2 $RECOVERY/grub2/fonts
sync
# Prepare efi files
echo ">> Preparing EFI partition"
EFI=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
if [ -z "$EFI" ]; then
echo "No EFI directory"
exit 1
fi
cp -rfv /arm/raw/grubefi/* $EFI
if [ -n "$EFI" ] && [ -n "$efi_dir" ]; then
echo "Copy $efi_dir to EFI directory"
cp -rfv $efi_dir/* $EFI
fi
partprobe
echo ">> Writing image and partition table"
dd if=/dev/zero of="${output_image}" bs=1024000 count="${size}" || exit 1
# Image partitions
# only rpi4 supports gpt
if [ "$model" == "rpi3" ]; then
sgdisk -n 1:8192:+96M -c 1:EFI -t 1:0c00 ${output_image}
sgdisk -n 2:0:+${state_size}M -c 2:state -t 2:8300 ${output_image}
sgdisk -n 3:0:+$(( recovery_size + oem_size ))M -c 3:lvm -t 3:8e00 ${output_image}
sgdisk -n 4:0:+64M -c 4:persistent -t 4:8300 ${output_image}
sgdisk -m 1:2:3:4 ${output_image}
sfdisk --part-type ${output_image} 1 c
elif [ "$model" == "rpi4" ]; then
echo "label: gpt" | sfdisk "${output_image}"
sgdisk -n 1:8192:+96M -c 1:EFI -t 1:0c00 ${output_image}
sgdisk -n 2:0:+${state_size}M -c 2:state -t 2:8300 ${output_image}
sgdisk -n 3:0:+${recovery_size}M -c 3:recovery -t 3:8300 ${output_image}
sgdisk -n 4:0:+${oem_size}M -c 4:oem -t 4:8300 ${output_image}
sgdisk -n 5:0:+64M -c 5:persistent -t 5:8300 ${output_image}
sgdisk -g ${output_image}
sgdisk -m 1:2:3:4:5 ${output_image}
else
sgdisk -n 1:8192:+16M -c 1:EFI -t 1:0700 ${output_image}
sgdisk -n 2:0:+${state_size}M -c 2:state -t 2:8300 ${output_image}
sgdisk -n 3:0:+$(( recovery_size + oem_size ))M -c 3:lvm -t 3:8e00 ${output_image}
sgdisk -n 4:0:+64M -c 4:persistent -t 4:8300 ${output_image}
sgdisk -m 1:2:3:4 ${output_image}
fi
# Prepare the image and copy over the files
DRIVE=$(losetup -f "${output_image}" --show)
export DRIVE
if [ -z "${DRIVE}" ]; then
echo "Cannot execute losetup for $output_image"
exit 1
fi
device=${DRIVE/\/dev\//}
if [ -z "$device" ]; then
echo "No device"
exit 1
fi
export device="/dev/mapper/${device}"
partprobe
if [ "$model" == 'rpi4' ]; then
kpartx -vag $DRIVE
else
kpartx -va $DRIVE
fi
echo ">> Populating partitions"
efi=${device}p1
state=${device}p2
recovery=${device}p3
if [ "$model" == 'rpi4' ]; then
oem=${device}p4
persistent=${device}p5
else
persistent=${device}p4
oem_lv=/dev/mapper/KairosVG-oem
recovery_lv=/dev/mapper/KairosVG-recovery
fi
# Create partitions (RECOVERY, STATE, COS_PERSISTENT)
mkfs.vfat -F 32 ${efi}
fatlabel ${efi} COS_GRUB
mkfs.ext4 -F -L ${STATE_LABEL} $state
mkfs.ext4 -F -L ${PERSISTENT_LABEL} $persistent
if [ "$model" == 'rpi4' ]; then
mkfs.ext4 -F -L ${RECOVERY_LABEL} $recovery
mkfs.ext4 -F -L ${OEM_LABEL} $oem
else
pvcreate $recovery
vgcreate KairosVG $recovery
lvcreate -Z n -n oem -L ${oem_size} KairosVG
lvcreate -Z n -n recovery -l 100%FREE KairosVG
vgchange -ay
vgmknodes
mkfs.ext4 -F -L ${OEM_LABEL} $oem_lv
mkfs.ext4 -F -L ${RECOVERY_LABEL} $recovery_lv
fi
mkdir $WORKDIR/state
mkdir $WORKDIR/recovery
mkdir $WORKDIR/efi
mkdir $WORKDIR/oem
mount $state $WORKDIR/state
mount $efi $WORKDIR/efi
if [ "$model" == 'rpi4' ]; then
mount $recovery $WORKDIR/recovery
mount $oem $WORKDIR/oem
else
mount $recovery_lv $WORKDIR/recovery
mount $oem_lv $WORKDIR/oem
fi
cp -rfv /defaults.yaml $WORKDIR/oem/01_defaults.yaml
# Set a OEM config file if specified
if [ -n "$config" ]; then
echo ">> Copying $config OEM config file"
get_url $config $WORKDIR/oem/99_custom.yaml
fi
grub2-editenv $WORKDIR/state/grub_oem_env set "default_menu_entry=$menu_entry"
# We copy the file we saved earier to the STATE partition
cp -rfv "${tmpgrubconfig}" $WORKDIR/state/grubmenu
# Copy over content
cp -arf $EFI/* $WORKDIR/efi
cp -arf $RECOVERY/* $WORKDIR/recovery
cp -arf $STATEDIR/* $WORKDIR/state
umount $WORKDIR/recovery
umount $WORKDIR/state
umount $WORKDIR/efi
umount $WORKDIR/oem
if [ "$model" != 'rpi4' ]; then
vgchange -an
fi
sync
# Flash uboot and vendor-specific bits
echo ">> Performing $model specific bits.."
/arm/boards/$model.sh ${DRIVE}
sync
sleep 5
sync
if [ "$model" == 'rpi4' ]; then
kpartx -dvg $DRIVE
else
kpartx -dv $DRIVE || true
fi
umount $DRIVE || true
echo ">> Done writing $output_image"
echo ">> Creating SHA256 sum"
sha256sum $output_image > $output_image.sha256
cleanup

View File

@@ -1,3 +0,0 @@
iso:
image:
- dir:/grub2

View File

@@ -1,8 +0,0 @@
#cloud-config
name: "Default user"
stages:
initramfs:
- name: "Set default user/pass"
users:
kairos:
passwd: "kairos"

View File

@@ -1,5 +0,0 @@
#!/bin/bash
set -ex
enki --config-dir /config $@

View File

@@ -1,15 +0,0 @@
#!/bin/bash
# Transform a raw image disk to gce compatible
RAWIMAGE="$1"
OUT="${2:-$RAWIMAGE.gce.raw}"
cp -rf $RAWIMAGE $OUT
GB=$((1024*1024*1024))
size=$(qemu-img info -f raw --output json "$OUT" | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}')
# shellcheck disable=SC2004
ROUNDED_SIZE=$(echo "$size/$GB+1"|bc)
echo "Resizing raw image from \"$size\"MB to \"$ROUNDED_SIZE\"GB"
qemu-img resize -f raw "$OUT" "$ROUNDED_SIZE"G
echo "Compressing raw image $OUT to $OUT.tar.gz"
tar -c -z --format=oldgnu -f "$OUT".tar.gz $OUT

View File

@@ -1,7 +0,0 @@
#!ipxe
set dns 8.8.8.8
ifconf
kernel ${RELEASE_URL}/${VERSION}/${ISO_NAME}-kernel root=live:${RELEASE_URL}/${VERSION}/${ISO_NAME}.squashfs initrd=${ISO_NAME}-initrd rd.neednet=1 ip=dhcp rd.cos.disable netboot install-mode config_url=${config} console=tty1 console=ttyS0 rd.live.overlay.overlayfs ${cmdline}
initrd ${RELEASE_URL}/${VERSION}/${ISO_NAME}-initrd
boot

View File

@@ -1,15 +0,0 @@
general:
debug: false
spinner_charset: 9
logging:
enable_emoji: false
repositories:
- name: "kairos"
description: "kairos repository"
type: "docker"
cached: true
enable: true
priority: 2
urls:
- "quay.io/kairos/packages"
reference: 20240202131847-repository.yaml

View File

@@ -1,15 +0,0 @@
general:
debug: false
spinner_charset: 9
logging:
enable_emoji: false
repositories:
- name: "kairos"
description: "kairos repository"
type: "docker"
cached: true
enable: true
priority: 2
urls:
- "quay.io/kairos/packages"
reference: 20240207153537-repository.yaml

View File

@@ -1,15 +0,0 @@
general:
debug: false
spinner_charset: 9
logging:
enable_emoji: false
repositories:
- name: "kairos-arm64"
description: "kairos repository arm64"
type: "docker"
cached: true
enable: true
priority: 2
urls:
- "quay.io/kairos/packages-arm64"
reference: 20240202135656-repository.yaml

View File

@@ -1,15 +0,0 @@
general:
debug: false
spinner_charset: 9
logging:
enable_emoji: false
repositories:
- name: "kairos-arm64"
description: "kairos repository arm64"
type: "docker"
cached: true
enable: true
priority: 2
urls:
- "quay.io/kairos/packages-arm64"
reference: 20240207154912-repository.yaml

View File

@@ -1,25 +0,0 @@
#!/bin/bash
# Extracts squashfs, kernel, initrd and generates a ipxe template script
ISO=$1
OUTPUT_NAME=$2
ARTIFACT_NAME=$(basename $OUTPUT_NAME)
isoinfo -x /rootfs.squashfs -R -i $ISO > $OUTPUT_NAME.squashfs
isoinfo -x /boot/kernel -R -i $ISO > $OUTPUT_NAME-kernel
isoinfo -x /boot/initrd -R -i $ISO > $OUTPUT_NAME-initrd
URL=${URL:-https://github.com/kairos-io/kairos/releases/download}
cat > $OUTPUT_NAME.ipxe << EOF
#!ipxe
set url ${URL}/
set kernel $ARTIFACT_NAME-kernel
set initrd $ARTIFACT_NAME-initrd
set rootfs $ARTIFACT_NAME.squashfs
# set config https://example.com/machine-config
# set cmdline extra.values=1
kernel \${url}/\${kernel} initrd=\${initrd} ip=dhcp rd.cos.disable root=live:\${url}/\${rootfs} netboot install-mode config_url=\${config} console=tty1 console=ttyS0 \${cmdline}
initrd \${url}/\${initrd}
boot
EOF

View File

@@ -1,13 +0,0 @@
KAIROS_NAME="${OS_NAME}"
KAIROS_VERSION="${OS_VERSION}"
KAIROS_ID="${OS_ID}"
KAIROS_ID_LIKE="${OS_NAME}"
KAIROS_VERSION_ID="${OS_VERSION}"
KAIROS_PRETTY_NAME="${OS_NAME} ${OS_VERSION}"
KAIROS_BUG_REPORT_URL="${BUG_REPORT_URL}"
KAIROS_HOME_URL="${HOME_URL}"
KAIROS_IMAGE_REPO="${OS_REPO}"
KAIROS_IMAGE_LABEL="${OS_LABEL}"
KAIROS_GITHUB_REPO="${GITHUB_REPO}"
KAIROS_VARIANT="${VARIANT}"
KAIROS_FLAVOR="${FLAVOR}"

View File

@@ -1,140 +0,0 @@
#!/bin/bash
# This script prepares Kairos state, recovery, oem and pesistent partitions as img files.
set -e
# Temp dir used during build
WORKDIR=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
TARGET=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
STATEDIR=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
: "${OEM_LABEL:=COS_OEM}"
: "${RECOVERY_LABEL:=COS_RECOVERY}"
: "${ACTIVE_LABEL:=COS_ACTIVE}"
: "${PASSIVE_LABEL:=COS_PASSIVE}"
: "${PERSISTENT_LABEL:=COS_PERSISTENT}"
: "${SYSTEM_LABEL:=COS_SYSTEM}"
: "${STATE_LABEL:=COS_STATE}"
size="${SIZE:-7544}"
state_size="${STATE_SIZE:-4992}"
recovery_size="${RECOVERY_SIZE:-2192}"
default_active_size="${DEFAULT_ACTIVE_SIZE:-2400}"
menu_entry="${DEFAULT_MENU_ENTRY:-Kairos}"
container_image="${container_image:-quay.io/kairos/kairos-opensuse-leap-arm-rpi:v1.5.1-k3sv1.25.6-k3s1}"
ensure_dir_structure() {
local target=$1
for mnt in /sys /proc /dev /tmp /boot /usr/local /oem
do
if [ ! -d "${target}${mnt}" ]; then
mkdir -p ${target}${mnt}
fi
done
}
mkdir -p $WORKDIR/tmpefi
# Create the EFI partition FAT16 and include the EFI image and a basic grub.cfg
truncate -s $((20*1024*1024)) bootloader/efi.img
cp -rfv /arm/raw/grubefi/* $WORKDIR/tmpefi
mkfs.fat -F16 -n COS_GRUB bootloader/efi.img
mcopy -s -i bootloader/efi.img $WORKDIR/tmpefi/EFI ::EFI
mkdir -p ${STATEDIR}/cOS
dd if=/dev/zero of=${STATEDIR}/cOS/active.img bs=1M count=$default_active_size
mkfs.ext2 ${STATEDIR}/cOS/active.img -L ${ACTIVE_LABEL}
LOOP=$(losetup --show -f ${STATEDIR}/cOS/active.img)
if [ -z "$LOOP" ]; then
echo "No device"
exit 1
fi
mount -t ext2 $LOOP $TARGET
ensure_dir_structure $TARGET
# Download the container image
if [ -z "$directory" ]; then
echo ">>> Downloading container image"
luet util unpack $container_image $TARGET
else
echo ">>> Copying files from $directory"
rsync -axq --exclude='host' --exclude='mnt' --exclude='proc' --exclude='sys' --exclude='dev' --exclude='tmp' ${directory}/ $TARGET
fi
# We copy the grubmenu.cfg to a temporary location to be copied later in the state partition
# https://github.com/kairos-io/kairos/blob/62c67e3e61d49435c362014522e5c6696335376f/overlay/files/system/oem/08_grub.yaml#L105
# This is a hack and we need a better way: https://github.com/kairos-io/kairos/issues/1427
tmpgrubconfig=$(mktemp /tmp/grubmeny.cfg.XXXXXX)
cp -rfv $TARGET/etc/kairos/branding/grubmenu.cfg "${tmpgrubconfig}"
umount $TARGET
sync
losetup -d $LOOP
echo ">> Preparing passive.img"
cp -rfv ${STATEDIR}/cOS/active.img ${STATEDIR}/cOS/passive.img
tune2fs -L ${PASSIVE_LABEL} ${STATEDIR}/cOS/passive.img
# Preparing recovery
echo ">> Preparing recovery.img"
RECOVERY=$(mktemp -d --tmpdir arm-builder.XXXXXXXXXX)
mkdir -p ${RECOVERY}/cOS
cp -rfv ${STATEDIR}/cOS/active.img ${RECOVERY}/cOS/recovery.img
tune2fs -L ${SYSTEM_LABEL} ${RECOVERY}/cOS/recovery.img
# Install real grub config to recovery
cp -rfv /arm/raw/grubconfig/* $RECOVERY
mkdir -p $RECOVERY/grub2/fonts
cp -rfv /arm/raw/grubartifacts/* $RECOVERY/grub2
mv $RECOVERY/grub2/*pf2 $RECOVERY/grub2/fonts
dd if=/dev/zero of=recovery_partition.img bs=1M count=$recovery_size
dd if=/dev/zero of=state_partition.img bs=1M count=$state_size
mkfs.ext4 -F -L ${RECOVERY_LABEL} recovery_partition.img
LOOP=$(losetup --show -f recovery_partition.img)
mkdir -p $WORKDIR/recovery
mount $LOOP $WORKDIR/recovery
cp -arf $RECOVERY/* $WORKDIR/recovery
umount $WORKDIR/recovery
losetup -d $LOOP
mkfs.ext4 -F -L ${STATE_LABEL} state_partition.img
LOOP=$(losetup --show -f state_partition.img)
mkdir -p $WORKDIR/state
mount $LOOP $WORKDIR/state
cp -arf $STATEDIR/* $WORKDIR/state
grub2-editenv $WORKDIR/state/grub_oem_env set "default_menu_entry=$menu_entry"
# We copy the file we saved earier to the STATE partition
cp -rfv "${tmpgrubconfig}" $WORKDIR/state/grubmenu
umount $WORKDIR/state
losetup -d $LOOP
cp -rfv state_partition.img bootloader/
cp -rfv recovery_partition.img bootloader/
## Optional, prepare COS_OEM and COS_PERSISTENT
# Create the grubenv forcing first boot to be on recovery system
mkdir -p $WORKDIR/oem
cp -rfv /defaults.yaml $WORKDIR/oem/01_defaults.yaml
# Create a 64MB filesystem for OEM volume
truncate -s $((64*1024*1024)) bootloader/oem.img
mkfs.ext2 -L "${OEM_LABEL}" -d $WORKDIR/oem bootloader/oem.img
# Create a 2GB filesystem for COS_PERSISTENT volume
truncate -s $((2048*1024*1024)) bootloader/persistent.img
mkfs.ext2 -L "${PERSISTENT_LABEL}" bootloader/persistent.img

View File

@@ -1,81 +0,0 @@
#!/bin/bash
# Generates EFI bootable images (statically)
# This is a re-adaptation of https://github.com/rancher/elemental-toolkit/blob/v0.8.10-1/images/img-builder.sh, which was dropped
# How to use:
# First extract the image which you want to create an image from:
### luet util unpack <image> rootfs
# Then convert it to a raw disk (EFI only):
### docker run -v $PWD:/output --entrypoint /raw-images.sh -ti --rm test-image /output/rootfs /output/foo.raw cloud-init.yaml
: "${OEM_LABEL:=COS_OEM}"
: "${RECOVERY_LABEL:=COS_RECOVERY}"
: "${EXTEND:=}"
: "${RECOVERY_SIZE:=2048}"
DIRECTORY=$1
OUT=${2:-disk.raw}
CONFIG=$3
echo "Output: $OUT"
set -e
mkdir -p /build/root/grub2
mkdir /build/root/cOS
mkdir /build/efi
cp -rf /raw/grub/* /build/efi
cp -rf /raw/grubconfig/* /build/root
cp -rf /raw/grubartifacts/* /build/root/grub2
echo "Generating squashfs from $DIRECTORY"
mksquashfs $DIRECTORY recovery.squashfs -b 1024k -comp xz -Xbcj x86
mv recovery.squashfs /build/root/cOS/recovery.squashfs
grub2-editenv /build/root/grub_oem_env set "default_menu_entry=Kairos"
# Create a 2GB filesystem for RECOVERY including the contents for root (grub config and squasfs container)
# shellcheck disable=SC2004
truncate -s $(($RECOVERY_SIZE*1024*1024)) rootfs.part
mkfs.ext2 -L "${RECOVERY_LABEL}" -d /build/root rootfs.part
# Create the EFI partition FAT16 and include the EFI image and a basic grub.cfg
truncate -s $((20*1024*1024)) efi.part
mkfs.fat -F16 -n COS_GRUB efi.part
mcopy -s -i efi.part /build/efi/EFI ::EFI
# Create the grubenv forcing first boot to be on recovery system
mkdir -p /build/oem
cp /build/root/etc/cos/grubenv_firstboot /build/oem/grubenv
if [ -n "$CONFIG" ]; then
echo "Copying config file ($CONFIG)"
cp $CONFIG /build/oem
fi
# Create a 64MB filesystem for OEM volume
truncate -s $((64*1024*1024)) oem.part
mkfs.ext2 -L "${OEM_LABEL}" -d /build/oem oem.part
echo "Generating image $OUT"
# Create disk image, add 3MB of initial free space to disk, 1MB is for proper alignement, 2MB are for the hybrid legacy boot.
truncate -s $((3*1024*1024)) $OUT
{
cat efi.part
cat oem.part
cat rootfs.part
} >> $OUT
# Add an extra MB at the end of the disk for the gpt headers, in fact 34 sectors would be enough, but adding some more does not hurt.
truncate -s "+$((1024*1024))" $OUT
if [ -n "$EXTEND" ]; then
echo "Extending image of $EXTEND MB"
truncate -s "+$((EXTEND*1024*1024))" $OUT
fi
# Create the partition table in $OUT (assumes sectors of 512 bytes)
sgdisk -n 1:2048:+2M -c 1:legacy -t 1:EF02 $OUT
sgdisk -n 2:0:+20M -c 2:UEFI -t 2:EF00 $OUT
sgdisk -n 3:0:+64M -c 3:oem -t 3:8300 $OUT
sgdisk -n 4:0:+${RECOVERY_SIZE}M -c 4:root -t 4:8300 $OUT

View File

@@ -1,23 +0,0 @@
#!/bin/bash
# usage:
# docker run --rm -ti --entrypoint /update-os-release.sh \
# -v /etc:/workspace \ # mount the directory where your os-release is, this is by default in /etc but you can mount a different dir for testing
# -e OS_NAME=kairos-core-opensuse-leap \
# -e OS_VERSION=v2.2.0 \
# -e OS_ID="kairos" \
# -e OS_NAME=kairos-core-opensuse-leap \
# -e BUG_REPORT_URL="https://github.com/kairos-io/kairos/issues" \
# -e HOME_URL="https://github.com/kairos-io/kairos" \
# -e OS_REPO="quay.io/kairos/core-opensuse-leap" \
# -e OS_LABEL="latest" \
# -e GITHUB_REPO="kairos-io/kairos" \
# -e VARIANT="core" \
# -e FLAVOR="opensuse-leap"
# quay.io/kairos/osbuilder-tools:latest
set -ex
sed -i -n '/KAIROS_/!p' /workspace/os-release
envsubst >>/workspace/os-release < /os-release.tmpl
cat /workspace/os-release