go.mod: update osbuild/images to v0.168.0

tag v0.165.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.165.0

----------------
  *  distro: move rhel9 into a generic distro (osbuild/images#1645)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * Revert "distro: drop `ImageType.BasePartitionTable()`" (osbuild/images#1691)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * Update dependencies 2025-07-20 (osbuild/images#1675)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * defs: add missing `bootstrap_containers` (osbuild/images#1679)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * disk: handle adding `PReP` partition on PPC64/s390x (HMS-8884) (osbuild/images#1681)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * distro: bring per-distro checkOptions back (osbuild/images#1678)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: cleanups in the pkg/distro/generic area (osbuild/images#1686)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * distro: move rhel8 into a generic distro (osbuild/images#1643)
    * Author: Michael Vogt, Reviewers: Nobody
  * distro: small followups for PR#1682 (osbuild/images#1689)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger, Tomáš Hozza
  * distro: unify transform/match into a single concept (osbuild/images#1682)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Tomáš Hozza
  * distros: de-duplicate runner build packages for centos10 (osbuild/images#1680)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * github: disable Go dep updates through dependabot (osbuild/images#1683)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * repos: include almalinux 9.6 (osbuild/images#1677)
    * Author: Simon de Vlieger, Reviewers: Lukáš Zapletal, Tomáš Hozza
  * rhel9: wsl distribution config (osbuild/images#1694)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Sanne Raymaekers
  * test/manifests/all-customizations: don't embed local file via URI (osbuild/images#1684)
    * Author: Tomáš Hozza, Reviewers: Achilleas Koutsou, Brian C. Lane

— Somewhere on the Internet, 2025-07-28

---

tag v0.166.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.166.0

----------------
  * customizations/subscription: conditionally enable semanage call (HMS-8866) (osbuild/images#1673)
    * Author: Sanne Raymaekers, Reviewers: Achilleas Koutsou, Michael Vogt
  * distro/rhel-10: versionlock shim-x64 in the azure-cvm image  (osbuild/images#1697)
    * Author: Achilleas Koutsou, Reviewers: Michael Vogt, Simon de Vlieger
  * manifestmock: move container/pkg/commit mocks into helper (osbuild/images#1700)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * rhel9: `vagrant-libvirt`, `vagrant-virtualbox` (osbuild/images#1693)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Sanne Raymaekers
  * rhel{9,10}: centos WSL refinement (HMS-8922) (osbuild/images#1690)
    * Author: Simon de Vlieger, Reviewers: Ondřej Budai, Sanne Raymaekers, Tomáš Hozza

— Somewhere on the Internet, 2025-07-29

---

tag v0.167.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.167.0

----------------
  * RHEL/Azure: drop obsolete WAAgentConfig keys [RHEL-93894] and remove loglevel kernel option [RHEL-102372] (osbuild/images#1611)
    * Author: Achilleas Koutsou, Reviewers: Michael Vogt, Ondřej Budai, Sanne Raymaekers
  * Update dependencies 2025-07-27 (osbuild/images#1699)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * distro/rhel9: set default_kernel to kernel-uki-virt (osbuild/images#1704)
    * Author: Achilleas Koutsou, Reviewers: Ondřej Budai, Simon de Vlieger
  * distro: drop legacy loaders and update tests (osbuild/images#1687)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Tomáš Hozza
  * distro: fix issues with yaml distro definitions and enable yaml checks (osbuild/images#1702)
    * Author: Achilleas Koutsou, Reviewers: Michael Vogt, Ondřej Budai, Simon de Vlieger

— Somewhere on the Internet, 2025-07-30

---

tag v0.168.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.168.0

----------------
  * distro: fix bug in variable substitution for static distros (osbuild/images#1710)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * rhel{9,10}: azure for non-RHEL (HMS-8949) (osbuild/images#1707)
    * Author: Simon de Vlieger, Reviewers: Achilleas Koutsou, Michael Vogt

— Somewhere on the Internet, 2025-07-30

---
This commit is contained in:
Achilleas Koutsou 2025-07-30 15:46:51 +02:00
parent fad3b35d49
commit 6497b7520d
856 changed files with 72834 additions and 136836 deletions

View file

@ -0,0 +1,66 @@
{
"aarch64": [
{
"name": "baseos",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/BaseOS/aarch64/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
},
{
"name": "appstream",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/AppStream/aarch64/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBGHmnykBEACuIcqcNYTmu2q58XI5NRZowdJGAxxs+6ExX7qsa4vbPp6St7lB\nJmLpwf5p6czIBhLL4b8E7zJpu57tVDo7Ejw6Hv584rbI8vw7pnMTe6XUFhMTL8FT\nlyAmn8xAIlcyM+SzshnxAc5b8E0p/egMonr3J1QnvMSfixMQ59GrmLVyece7Vv3J\n4fREh6k31kg7eQdEkzRQhRdO2KyxWYLR0A6haXSXVaiBOjFF7iUs7anlJSfeD3FO\nafPq0Ix8oWi+mUc4txkABMdsGpdkE/MHOwN90FB8EG5XVrdv3emm3yzKMMzb53Yd\njcf0fovIeRloQyl9+CrVCnkBjFcIFBZZddsB43kM7eTflmAQ+tanOZ8OKBRPMtmI\n56b/vk31ozHUoST/NmjbEI5tu+QYCuFSZ++mC06qJg0Bkw821DTAsM7Kynuj7K2f\nWWQjlDL9ZsFifLqDXRymL+sn6g142hHQOa5KSHtT7cAcrm6L48gEL3fPntVSOU/H\nBlTnODiSSTIsIRNA7kBkbSP3wWoYC1JQPmNYbUtZ7va2uXNb9dGT2k7Ae0465WND\nwqRQJDxsr6TLYFpti+JRaOpSMNclXz4kRSP263Y4ZzQvkMGgSgwqg7JU00Uahk2p\nKTlJAA8AiaMBdShlo/QXvL29Lyg0Y5klq2HCNziJDupWhXto5j5pjixrpwARAQAB\ntCdBbG1hTGludXggT1MgOSA8cGFja2FnZXJAYWxtYWxpbnV4Lm9yZz6JAk4EEwEI\nADgWIQS/GKwodheJCNbnEmfTbLhsuGs3FgUCYeafKQIbAwULCQgHAgYVCgkICwIE\nFgIDAQIeAQIXgAAKCRDTbLhsuGs3FrvnD/9X1wDM/C214t3UVsMVjTLdIJDGG+iU\nE7Uk7QGeyeNif19rRatzXUHBBGjiAwpxe2rkveWBHCHPSUKqsAR9Arv3nMKiaGfA\n0nomzDndLEDIgv35xzaU6OhX95mZzvj+9PThuxDxUnsNoA+7vGkaiRw+cyyDdTJQ\nbKwum8bx1gS8Kbqo9mqrMekQ4NHCodq9bb2hI6pAxlYa472QuwFAXFAzbE3LIMIK\nhzLkew7nxwP0txP/zzqPw4lYN38fg9AlHL2qgf0twCFO4N/ftkw25qwoiBhiwaWT\nCa8Z9wUJx35Z/ufscbNrtRrIGYNXTDFJdGY/WxKDp7QsyOx/sclcsSksKoC/52tL\n2yFLQrMXsqnLjAQajA6adaeCAAwvp2/8VP8R65O4KMuKghMneCGwXVlVVYyRUXJD\nKjg7EvmmMGuh/Lj2A/vj+mQMmlS2kAl0qOsK9DtUIA7Z9m98zI3UmN/5BMb/HdqW\nKADagOW9IPyo6IaSIT+A+7npTN1Y7m1aIrL1vsAKrus4MrCvAs1vYqzqIikv88Di\nEWYVFCWTsTWf7jxBCVTLn1Lr7Mj08i+7OgRgguQGpcnvKsbwq1v2whQrs+YKR9hP\nvVaW5DmGJ5brPykJUaQS6p5Esp1q3HBk0HbBxiiGIwGsKbLp0pKsk5TLzMIJwIG/\nlEolCV+fJ0P4nLkCDQRh5p8pARAAvXTL29arJ5Dl9FXVpE4Km1jJLaK2WfbQARJz\nygQKps9QNqS1yz7C7mYdTtgRxeK2eqcX5oA83w3ppJ0DTsxfAkY3nqAXS8+QRORU\nffSFvhdsU1G/qpvhX0Aq62gr4y1bkIMr9GlLq86uVKIQrNdmto4NDfQc1bDD5e4j\nKaNMmNLXxq/s67AxFW/yLchYYZ7cMqQd6Ab4lacqpGdYFIAkBkVMmj3GUSo+FLpl\n+4c50AZ8O0aB+xkrjch+4PoVyIpIC1IuqNYBYn2wMYFB414QY2iDopzpZXUhpCqx\nNP4Zyhl1noUcOtH/wUfH1JsIcYRn0ixWF6JnE9KmjpkqBuM2/4Ot/bl67iPiN/if\nvf3Z1kYjNPaszoMW3kmJj8MlBCSH9w6nQRG/eikihbeUDBB6rh2O7Dz8ltFqlt8N\nasbngRoNZMnWMnItRV67Fo0pfn/DZA8VvI029apE21sNp6l7MUa8Z2/I/PNq10E8\nrPMQM//k9y2kgxz52i6iCyesobPvun6UC4xuFoYKUTQMgKQgqOhyZ4evkepFhmHg\nGzx+F8EmwN1FtxfNxfLtQZSUT3kxuUDizwpaH/LkSkRXpJOQyHJL6VBINNTjB4j1\n3+0jD+lCV6xIt88NYkGJL9rtKwZLQHSDPiI0ooCJ69GKy8SmSx04AwSsY67In1q8\n+FQjT20AEQEAAYkCNgQYAQgAIBYhBL8YrCh2F4kI1ucSZ9NsuGy4azcWBQJh5p8p\nAhsMAAoJENNsuGy4azcW0KkP/i0YLRv+pDiSC4034oboczAnNrzJnBhqTi9cUEGn\nXpqvf/Zz3opqvRQiqZAgVcCtxfW+P9J3Vb/mBJ6OkR/jywAlY5il2dzK08YfVXmP\ncEf6RF4M0KNtlYJmPlnQCZjMJaisrPmYD3Yy8ER1qJ5JQZ7n0REHZCbBCqH8w+5r\nj4ohEHY7xXbd7+tvWTCk2MkHaide/UV/04WiO064AoZSUze/vaAx8Ll4AyFpxuIk\nktXZXbq7MaVzqYYJptiRB6TljzMwIbblLm9A7T7YTA/1rNe12OhDT8VoR3gG2C/l\nMtf37EmYq3QVqFlbj4+ouQWIiQmp5dQenH5ugf+Bob7IiENpxzF1cIu6wd4p5Y64\n3cdYUoxrjhsCM6W1lSqECoN8yXJnRTxpBwwm65SVk477KS2h77aJfa+v5UnBhpSt\neVlAhs0A8Qp/hX3o7qMO1jWca3zdJwXppLlFEYTVaFUOUrc4Lhlbi0gAnn8aBwSx\nxF1r5GhPGIBzHtRgulwZkmS6VwtDMuC6KlrASu9f93D5gLZqVk22Oar9LpgCEACd\n8Gw/+BFbdANqo9IKmDrWf7k/YuEqZ3h+eoyKI/2z7dKh/fcVEydMTn3LB4nFRvSD\nAZ27tvC0IUXCUNx7iJdrD5kDsMhZRl5/dXbe539G4y2W00QYuJC0DpUvGdtOuaFx\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
}
],
"ppc64le": [
{
"name": "baseos",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/BaseOS/ppc64le/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
},
{
"name": "appstream",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/AppStream/ppc64le/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
}
],
"s390x": [
{
"name": "baseos",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/BaseOS/s390x/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBGHmnykBEACuIcqcNYTmu2q58XI5NRZowdJGAxxs+6ExX7qsa4vbPp6St7lB\nJmLpwf5p6czIBhLL4b8E7zJpu57tVDo7Ejw6Hv584rbI8vw7pnMTe6XUFhMTL8FT\nlyAmn8xAIlcyM+SzshnxAc5b8E0p/egMonr3J1QnvMSfixMQ59GrmLVyece7Vv3J\n4fREh6k31kg7eQdEkzRQhRdO2KyxWYLR0A6haXSXVaiBOjFF7iUs7anlJSfeD3FO\nafPq0Ix8oWi+mUc4txkABMdsGpdkE/MHOwN90FB8EG5XVrdv3emm3yzKMMzb53Yd\njcf0fovIeRloQyl9+CrVCnkBjFcIFBZZddsB43kM7eTflmAQ+tanOZ8OKBRPMtmI\n56b/vk31ozHUoST/NmjbEI5tu+QYCuFSZ++mC06qJg0Bkw821DTAsM7Kynuj7K2f\nWWQjlDL9ZsFifLqDXRymL+sn6g142hHQOa5KSHtT7cAcrm6L48gEL3fPntVSOU/H\nBlTnODiSSTIsIRNA7kBkbSP3wWoYC1JQPmNYbUtZ7va2uXNb9dGT2k7Ae0465WND\nwqRQJDxsr6TLYFpti+JRaOpSMNclXz4kRSP263Y4ZzQvkMGgSgwqg7JU00Uahk2p\nKTlJAA8AiaMBdShlo/QXvL29Lyg0Y5klq2HCNziJDupWhXto5j5pjixrpwARAQAB\ntCdBbG1hTGludXggT1MgOSA8cGFja2FnZXJAYWxtYWxpbnV4Lm9yZz6JAk4EEwEI\nADgWIQS/GKwodheJCNbnEmfTbLhsuGs3FgUCYeafKQIbAwULCQgHAgYVCgkICwIE\nFgIDAQIeAQIXgAAKCRDTbLhsuGs3FrvnD/9X1wDM/C214t3UVsMVjTLdIJDGG+iU\nE7Uk7QGeyeNif19rRatzXUHBBGjiAwpxe2rkveWBHCHPSUKqsAR9Arv3nMKiaGfA\n0nomzDndLEDIgv35xzaU6OhX95mZzvj+9PThuxDxUnsNoA+7vGkaiRw+cyyDdTJQ\nbKwum8bx1gS8Kbqo9mqrMekQ4NHCodq9bb2hI6pAxlYa472QuwFAXFAzbE3LIMIK\nhzLkew7nxwP0txP/zzqPw4lYN38fg9AlHL2qgf0twCFO4N/ftkw25qwoiBhiwaWT\nCa8Z9wUJx35Z/ufscbNrtRrIGYNXTDFJdGY/WxKDp7QsyOx/sclcsSksKoC/52tL\n2yFLQrMXsqnLjAQajA6adaeCAAwvp2/8VP8R65O4KMuKghMneCGwXVlVVYyRUXJD\nKjg7EvmmMGuh/Lj2A/vj+mQMmlS2kAl0qOsK9DtUIA7Z9m98zI3UmN/5BMb/HdqW\nKADagOW9IPyo6IaSIT+A+7npTN1Y7m1aIrL1vsAKrus4MrCvAs1vYqzqIikv88Di\nEWYVFCWTsTWf7jxBCVTLn1Lr7Mj08i+7OgRgguQGpcnvKsbwq1v2whQrs+YKR9hP\nvVaW5DmGJ5brPykJUaQS6p5Esp1q3HBk0HbBxiiGIwGsKbLp0pKsk5TLzMIJwIG/\nlEolCV+fJ0P4nLkCDQRh5p8pARAAvXTL29arJ5Dl9FXVpE4Km1jJLaK2WfbQARJz\nygQKps9QNqS1yz7C7mYdTtgRxeK2eqcX5oA83w3ppJ0DTsxfAkY3nqAXS8+QRORU\nffSFvhdsU1G/qpvhX0Aq62gr4y1bkIMr9GlLq86uVKIQrNdmto4NDfQc1bDD5e4j\nKaNMmNLXxq/s67AxFW/yLchYYZ7cMqQd6Ab4lacqpGdYFIAkBkVMmj3GUSo+FLpl\n+4c50AZ8O0aB+xkrjch+4PoVyIpIC1IuqNYBYn2wMYFB414QY2iDopzpZXUhpCqx\nNP4Zyhl1noUcOtH/wUfH1JsIcYRn0ixWF6JnE9KmjpkqBuM2/4Ot/bl67iPiN/if\nvf3Z1kYjNPaszoMW3kmJj8MlBCSH9w6nQRG/eikihbeUDBB6rh2O7Dz8ltFqlt8N\nasbngRoNZMnWMnItRV67Fo0pfn/DZA8VvI029apE21sNp6l7MUa8Z2/I/PNq10E8\nrPMQM//k9y2kgxz52i6iCyesobPvun6UC4xuFoYKUTQMgKQgqOhyZ4evkepFhmHg\nGzx+F8EmwN1FtxfNxfLtQZSUT3kxuUDizwpaH/LkSkRXpJOQyHJL6VBINNTjB4j1\n3+0jD+lCV6xIt88NYkGJL9rtKwZLQHSDPiI0ooCJ69GKy8SmSx04AwSsY67In1q8\n+FQjT20AEQEAAYkCNgQYAQgAIBYhBL8YrCh2F4kI1ucSZ9NsuGy4azcWBQJh5p8p\nAhsMAAoJENNsuGy4azcW0KkP/i0YLRv+pDiSC4034oboczAnNrzJnBhqTi9cUEGn\nXpqvf/Zz3opqvRQiqZAgVcCtxfW+P9J3Vb/mBJ6OkR/jywAlY5il2dzK08YfVXmP\ncEf6RF4M0KNtlYJmPlnQCZjMJaisrPmYD3Yy8ER1qJ5JQZ7n0REHZCbBCqH8w+5r\nj4ohEHY7xXbd7+tvWTCk2MkHaide/UV/04WiO064AoZSUze/vaAx8Ll4AyFpxuIk\nktXZXbq7MaVzqYYJptiRB6TljzMwIbblLm9A7T7YTA/1rNe12OhDT8VoR3gG2C/l\nMtf37EmYq3QVqFlbj4+ouQWIiQmp5dQenH5ugf+Bob7IiENpxzF1cIu6wd4p5Y64\n3cdYUoxrjhsCM6W1lSqECoN8yXJnRTxpBwwm65SVk477KS2h77aJfa+v5UnBhpSt\neVlAhs0A8Qp/hX3o7qMO1jWca3zdJwXppLlFEYTVaFUOUrc4Lhlbi0gAnn8aBwSx\nxF1r5GhPGIBzHtRgulwZkmS6VwtDMuC6KlrASu9f93D5gLZqVk22Oar9LpgCEACd\n8Gw/+BFbdANqo9IKmDrWf7k/YuEqZ3h+eoyKI/2z7dKh/fcVEydMTn3LB4nFRvSD\nAZ27tvC0IUXCUNx7iJdrD5kDsMhZRl5/dXbe539G4y2W00QYuJC0DpUvGdtOuaFx\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
},
{
"name": "appstream",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/AppStream/s390x/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBGHmnykBEACuIcqcNYTmu2q58XI5NRZowdJGAxxs+6ExX7qsa4vbPp6St7lB\nJmLpwf5p6czIBhLL4b8E7zJpu57tVDo7Ejw6Hv584rbI8vw7pnMTe6XUFhMTL8FT\nlyAmn8xAIlcyM+SzshnxAc5b8E0p/egMonr3J1QnvMSfixMQ59GrmLVyece7Vv3J\n4fREh6k31kg7eQdEkzRQhRdO2KyxWYLR0A6haXSXVaiBOjFF7iUs7anlJSfeD3FO\nafPq0Ix8oWi+mUc4txkABMdsGpdkE/MHOwN90FB8EG5XVrdv3emm3yzKMMzb53Yd\njcf0fovIeRloQyl9+CrVCnkBjFcIFBZZddsB43kM7eTflmAQ+tanOZ8OKBRPMtmI\n56b/vk31ozHUoST/NmjbEI5tu+QYCuFSZ++mC06qJg0Bkw821DTAsM7Kynuj7K2f\nWWQjlDL9ZsFifLqDXRymL+sn6g142hHQOa5KSHtT7cAcrm6L48gEL3fPntVSOU/H\nBlTnODiSSTIsIRNA7kBkbSP3wWoYC1JQPmNYbUtZ7va2uXNb9dGT2k7Ae0465WND\nwqRQJDxsr6TLYFpti+JRaOpSMNclXz4kRSP263Y4ZzQvkMGgSgwqg7JU00Uahk2p\nKTlJAA8AiaMBdShlo/QXvL29Lyg0Y5klq2HCNziJDupWhXto5j5pjixrpwARAQAB\ntCdBbG1hTGludXggT1MgOSA8cGFja2FnZXJAYWxtYWxpbnV4Lm9yZz6JAk4EEwEI\nADgWIQS/GKwodheJCNbnEmfTbLhsuGs3FgUCYeafKQIbAwULCQgHAgYVCgkICwIE\nFgIDAQIeAQIXgAAKCRDTbLhsuGs3FrvnD/9X1wDM/C214t3UVsMVjTLdIJDGG+iU\nE7Uk7QGeyeNif19rRatzXUHBBGjiAwpxe2rkveWBHCHPSUKqsAR9Arv3nMKiaGfA\n0nomzDndLEDIgv35xzaU6OhX95mZzvj+9PThuxDxUnsNoA+7vGkaiRw+cyyDdTJQ\nbKwum8bx1gS8Kbqo9mqrMekQ4NHCodq9bb2hI6pAxlYa472QuwFAXFAzbE3LIMIK\nhzLkew7nxwP0txP/zzqPw4lYN38fg9AlHL2qgf0twCFO4N/ftkw25qwoiBhiwaWT\nCa8Z9wUJx35Z/ufscbNrtRrIGYNXTDFJdGY/WxKDp7QsyOx/sclcsSksKoC/52tL\n2yFLQrMXsqnLjAQajA6adaeCAAwvp2/8VP8R65O4KMuKghMneCGwXVlVVYyRUXJD\nKjg7EvmmMGuh/Lj2A/vj+mQMmlS2kAl0qOsK9DtUIA7Z9m98zI3UmN/5BMb/HdqW\nKADagOW9IPyo6IaSIT+A+7npTN1Y7m1aIrL1vsAKrus4MrCvAs1vYqzqIikv88Di\nEWYVFCWTsTWf7jxBCVTLn1Lr7Mj08i+7OgRgguQGpcnvKsbwq1v2whQrs+YKR9hP\nvVaW5DmGJ5brPykJUaQS6p5Esp1q3HBk0HbBxiiGIwGsKbLp0pKsk5TLzMIJwIG/\nlEolCV+fJ0P4nLkCDQRh5p8pARAAvXTL29arJ5Dl9FXVpE4Km1jJLaK2WfbQARJz\nygQKps9QNqS1yz7C7mYdTtgRxeK2eqcX5oA83w3ppJ0DTsxfAkY3nqAXS8+QRORU\nffSFvhdsU1G/qpvhX0Aq62gr4y1bkIMr9GlLq86uVKIQrNdmto4NDfQc1bDD5e4j\nKaNMmNLXxq/s67AxFW/yLchYYZ7cMqQd6Ab4lacqpGdYFIAkBkVMmj3GUSo+FLpl\n+4c50AZ8O0aB+xkrjch+4PoVyIpIC1IuqNYBYn2wMYFB414QY2iDopzpZXUhpCqx\nNP4Zyhl1noUcOtH/wUfH1JsIcYRn0ixWF6JnE9KmjpkqBuM2/4Ot/bl67iPiN/if\nvf3Z1kYjNPaszoMW3kmJj8MlBCSH9w6nQRG/eikihbeUDBB6rh2O7Dz8ltFqlt8N\nasbngRoNZMnWMnItRV67Fo0pfn/DZA8VvI029apE21sNp6l7MUa8Z2/I/PNq10E8\nrPMQM//k9y2kgxz52i6iCyesobPvun6UC4xuFoYKUTQMgKQgqOhyZ4evkepFhmHg\nGzx+F8EmwN1FtxfNxfLtQZSUT3kxuUDizwpaH/LkSkRXpJOQyHJL6VBINNTjB4j1\n3+0jD+lCV6xIt88NYkGJL9rtKwZLQHSDPiI0ooCJ69GKy8SmSx04AwSsY67In1q8\n+FQjT20AEQEAAYkCNgQYAQgAIBYhBL8YrCh2F4kI1ucSZ9NsuGy4azcWBQJh5p8p\nAhsMAAoJENNsuGy4azcW0KkP/i0YLRv+pDiSC4034oboczAnNrzJnBhqTi9cUEGn\nXpqvf/Zz3opqvRQiqZAgVcCtxfW+P9J3Vb/mBJ6OkR/jywAlY5il2dzK08YfVXmP\ncEf6RF4M0KNtlYJmPlnQCZjMJaisrPmYD3Yy8ER1qJ5JQZ7n0REHZCbBCqH8w+5r\nj4ohEHY7xXbd7+tvWTCk2MkHaide/UV/04WiO064AoZSUze/vaAx8Ll4AyFpxuIk\nktXZXbq7MaVzqYYJptiRB6TljzMwIbblLm9A7T7YTA/1rNe12OhDT8VoR3gG2C/l\nMtf37EmYq3QVqFlbj4+ouQWIiQmp5dQenH5ugf+Bob7IiENpxzF1cIu6wd4p5Y64\n3cdYUoxrjhsCM6W1lSqECoN8yXJnRTxpBwwm65SVk477KS2h77aJfa+v5UnBhpSt\neVlAhs0A8Qp/hX3o7qMO1jWca3zdJwXppLlFEYTVaFUOUrc4Lhlbi0gAnn8aBwSx\nxF1r5GhPGIBzHtRgulwZkmS6VwtDMuC6KlrASu9f93D5gLZqVk22Oar9LpgCEACd\n8Gw/+BFbdANqo9IKmDrWf7k/YuEqZ3h+eoyKI/2z7dKh/fcVEydMTn3LB4nFRvSD\nAZ27tvC0IUXCUNx7iJdrD5kDsMhZRl5/dXbe539G4y2W00QYuJC0DpUvGdtOuaFx\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
}
],
"x86_64": [
{
"name": "baseos",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/BaseOS/x86_64/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n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\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
},
{
"name": "appstream",
"baseurl": "https://repo.almalinux.org/almalinux/9.6/AppStream/x86_64/os/",
"gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBGHmnykBEACuIcqcNYTmu2q58XI5NRZowdJGAxxs+6ExX7qsa4vbPp6St7lB\nJmLpwf5p6czIBhLL4b8E7zJpu57tVDo7Ejw6Hv584rbI8vw7pnMTe6XUFhMTL8FT\nlyAmn8xAIlcyM+SzshnxAc5b8E0p/egMonr3J1QnvMSfixMQ59GrmLVyece7Vv3J\n4fREh6k31kg7eQdEkzRQhRdO2KyxWYLR0A6haXSXVaiBOjFF7iUs7anlJSfeD3FO\nafPq0Ix8oWi+mUc4txkABMdsGpdkE/MHOwN90FB8EG5XVrdv3emm3yzKMMzb53Yd\njcf0fovIeRloQyl9+CrVCnkBjFcIFBZZddsB43kM7eTflmAQ+tanOZ8OKBRPMtmI\n56b/vk31ozHUoST/NmjbEI5tu+QYCuFSZ++mC06qJg0Bkw821DTAsM7Kynuj7K2f\nWWQjlDL9ZsFifLqDXRymL+sn6g142hHQOa5KSHtT7cAcrm6L48gEL3fPntVSOU/H\nBlTnODiSSTIsIRNA7kBkbSP3wWoYC1JQPmNYbUtZ7va2uXNb9dGT2k7Ae0465WND\nwqRQJDxsr6TLYFpti+JRaOpSMNclXz4kRSP263Y4ZzQvkMGgSgwqg7JU00Uahk2p\nKTlJAA8AiaMBdShlo/QXvL29Lyg0Y5klq2HCNziJDupWhXto5j5pjixrpwARAQAB\ntCdBbG1hTGludXggT1MgOSA8cGFja2FnZXJAYWxtYWxpbnV4Lm9yZz6JAk4EEwEI\nADgWIQS/GKwodheJCNbnEmfTbLhsuGs3FgUCYeafKQIbAwULCQgHAgYVCgkICwIE\nFgIDAQIeAQIXgAAKCRDTbLhsuGs3FrvnD/9X1wDM/C214t3UVsMVjTLdIJDGG+iU\nE7Uk7QGeyeNif19rRatzXUHBBGjiAwpxe2rkveWBHCHPSUKqsAR9Arv3nMKiaGfA\n0nomzDndLEDIgv35xzaU6OhX95mZzvj+9PThuxDxUnsNoA+7vGkaiRw+cyyDdTJQ\nbKwum8bx1gS8Kbqo9mqrMekQ4NHCodq9bb2hI6pAxlYa472QuwFAXFAzbE3LIMIK\nhzLkew7nxwP0txP/zzqPw4lYN38fg9AlHL2qgf0twCFO4N/ftkw25qwoiBhiwaWT\nCa8Z9wUJx35Z/ufscbNrtRrIGYNXTDFJdGY/WxKDp7QsyOx/sclcsSksKoC/52tL\n2yFLQrMXsqnLjAQajA6adaeCAAwvp2/8VP8R65O4KMuKghMneCGwXVlVVYyRUXJD\nKjg7EvmmMGuh/Lj2A/vj+mQMmlS2kAl0qOsK9DtUIA7Z9m98zI3UmN/5BMb/HdqW\nKADagOW9IPyo6IaSIT+A+7npTN1Y7m1aIrL1vsAKrus4MrCvAs1vYqzqIikv88Di\nEWYVFCWTsTWf7jxBCVTLn1Lr7Mj08i+7OgRgguQGpcnvKsbwq1v2whQrs+YKR9hP\nvVaW5DmGJ5brPykJUaQS6p5Esp1q3HBk0HbBxiiGIwGsKbLp0pKsk5TLzMIJwIG/\nlEolCV+fJ0P4nLkCDQRh5p8pARAAvXTL29arJ5Dl9FXVpE4Km1jJLaK2WfbQARJz\nygQKps9QNqS1yz7C7mYdTtgRxeK2eqcX5oA83w3ppJ0DTsxfAkY3nqAXS8+QRORU\nffSFvhdsU1G/qpvhX0Aq62gr4y1bkIMr9GlLq86uVKIQrNdmto4NDfQc1bDD5e4j\nKaNMmNLXxq/s67AxFW/yLchYYZ7cMqQd6Ab4lacqpGdYFIAkBkVMmj3GUSo+FLpl\n+4c50AZ8O0aB+xkrjch+4PoVyIpIC1IuqNYBYn2wMYFB414QY2iDopzpZXUhpCqx\nNP4Zyhl1noUcOtH/wUfH1JsIcYRn0ixWF6JnE9KmjpkqBuM2/4Ot/bl67iPiN/if\nvf3Z1kYjNPaszoMW3kmJj8MlBCSH9w6nQRG/eikihbeUDBB6rh2O7Dz8ltFqlt8N\nasbngRoNZMnWMnItRV67Fo0pfn/DZA8VvI029apE21sNp6l7MUa8Z2/I/PNq10E8\nrPMQM//k9y2kgxz52i6iCyesobPvun6UC4xuFoYKUTQMgKQgqOhyZ4evkepFhmHg\nGzx+F8EmwN1FtxfNxfLtQZSUT3kxuUDizwpaH/LkSkRXpJOQyHJL6VBINNTjB4j1\n3+0jD+lCV6xIt88NYkGJL9rtKwZLQHSDPiI0ooCJ69GKy8SmSx04AwSsY67In1q8\n+FQjT20AEQEAAYkCNgQYAQgAIBYhBL8YrCh2F4kI1ucSZ9NsuGy4azcWBQJh5p8p\nAhsMAAoJENNsuGy4azcW0KkP/i0YLRv+pDiSC4034oboczAnNrzJnBhqTi9cUEGn\nXpqvf/Zz3opqvRQiqZAgVcCtxfW+P9J3Vb/mBJ6OkR/jywAlY5il2dzK08YfVXmP\ncEf6RF4M0KNtlYJmPlnQCZjMJaisrPmYD3Yy8ER1qJ5JQZ7n0REHZCbBCqH8w+5r\nj4ohEHY7xXbd7+tvWTCk2MkHaide/UV/04WiO064AoZSUze/vaAx8Ll4AyFpxuIk\nktXZXbq7MaVzqYYJptiRB6TljzMwIbblLm9A7T7YTA/1rNe12OhDT8VoR3gG2C/l\nMtf37EmYq3QVqFlbj4+ouQWIiQmp5dQenH5ugf+Bob7IiENpxzF1cIu6wd4p5Y64\n3cdYUoxrjhsCM6W1lSqECoN8yXJnRTxpBwwm65SVk477KS2h77aJfa+v5UnBhpSt\neVlAhs0A8Qp/hX3o7qMO1jWca3zdJwXppLlFEYTVaFUOUrc4Lhlbi0gAnn8aBwSx\nxF1r5GhPGIBzHtRgulwZkmS6VwtDMuC6KlrASu9f93D5gLZqVk22Oar9LpgCEACd\n8Gw/+BFbdANqo9IKmDrWf7k/YuEqZ3h+eoyKI/2z7dKh/fcVEydMTn3LB4nFRvSD\nAZ27tvC0IUXCUNx7iJdrD5kDsMhZRl5/dXbe539G4y2W00QYuJC0DpUvGdtOuaFx\n1WKL\n=jk2t\n-----END PGP PUBLIC KEY BLOCK-----",
"check_gpg": true,
"rhsm": false
}
]
}

View file

@ -3,3 +3,12 @@ package common
func ToPtr[T any](x T) *T {
return &x
}
// ValueOrEmpty returns the value from a given pointer. If ref is nil,
// a zero value of type T will be returned.
func ValueOrEmpty[T any](ref *T) (value T) {
if ref != nil {
value = *ref
}
return
}

View file

@ -118,6 +118,8 @@ func getPartitionTypeIDfor(ptType PartitionTableType, partTypeName string, archi
return EFISystemPartitionDOSID, nil
case "lvm":
return LVMPartitionDOSID, nil
case "ppc_prep":
return PRepPartitionDOSID, nil
case "swap":
return SwapPartitionDOSID, nil
default:
@ -135,6 +137,8 @@ func getPartitionTypeIDfor(ptType PartitionTableType, partTypeName string, archi
return EFISystemPartitionGUID, nil
case "lvm":
return LVMPartitionGUID, nil
case "ppc_prep":
return PRePartitionGUID, nil
case "swap":
return SwapPartitionGUID, nil
case "root":

View file

@ -1127,7 +1127,26 @@ func hasESP(disk *blueprint.DiskCustomization) bool {
// The function will append the new partitions to the end of the existing
// partition table therefore it is best to call this function early to put them
// near the front (as is conventional).
func addPartitionsForBootMode(pt *PartitionTable, disk *blueprint.DiskCustomization, bootMode platform.BootMode) error {
func addPartitionsForBootMode(pt *PartitionTable, disk *blueprint.DiskCustomization, bootMode platform.BootMode, architecture arch.Arch) error {
if bootMode == platform.BOOT_NONE {
return nil
}
// UEFI is not supported for PPC CPUs so we don't need to
// add an ESP partition there
switch architecture {
case arch.ARCH_PPC64LE:
part, err := mkPPCPrepBoot(pt.Type)
if err != nil {
return err
}
pt.Partitions = append(pt.Partitions, part)
return nil
case arch.ARCH_S390X:
// s390x does not need any special boot partition
return nil
}
switch bootMode {
case platform.BOOT_LEGACY:
// add BIOS boot partition
@ -1162,13 +1181,23 @@ func addPartitionsForBootMode(pt *PartitionTable, disk *blueprint.DiskCustomizat
pt.Partitions = append(pt.Partitions, esp)
}
return nil
case platform.BOOT_NONE:
return nil
default:
return fmt.Errorf("unknown or unsupported boot mode type with enum value %d", bootMode)
}
}
func mkPPCPrepBoot(ptType PartitionTableType) (Partition, error) {
partType, err := getPartitionTypeIDfor(ptType, "ppc_prep", arch.ARCH_UNSET)
if err != nil {
return Partition{}, fmt.Errorf("error creating ppc PReP boot partition: %w", err)
}
return Partition{
Size: 4 * datasizes.MiB,
Bootable: true,
Type: partType,
}, nil
}
func mkBIOSBoot(ptType PartitionTableType) (Partition, error) {
partType, err := getPartitionTypeIDfor(ptType, "bios", arch.ARCH_UNSET)
if err != nil {
@ -1314,7 +1343,7 @@ func NewCustomPartitionTable(customizations *blueprint.DiskCustomization, option
// add any partition(s) that are needed for booting (like /boot/efi)
// if needed
//
if err := addPartitionsForBootMode(pt, customizations, options.BootMode); err != nil {
if err := addPartitionsForBootMode(pt, customizations, options.BootMode, options.Architecture); err != nil {
return nil, fmt.Errorf("%s %w", errPrefix, err)
}
// add the /boot partition (if it is needed)

View file

@ -83,6 +83,12 @@ Conditions can be used and *only* the "append" action is supported,
this means that the packages from the conditions is appended to the
original package sets.
### platforms_override
This can be used to override the platforms for the image type based
on some condition. See the rhel-8 "ami" image type for an example
where the `aarch64` architecture is only available for rhel-8.9+.
### conditions
Conditions are expressed using the following form:
@ -112,11 +118,12 @@ shared and merge via the `<<:` operation.
The `when` part of the condition can contain one or more
of:
- distro_name
- arch
- version_less_than
- version_equal
- version_greater
- `distro_name`
- `not_distro_name`
- `arch`
- `version_less_than`
- `version_equal`
- `version_greater`
If multiple conditions are given under `when` they are
considered logical AND and only if they all match is
the condition executed.

View file

@ -1,3 +1,4 @@
---
distros:
- &fedora_rawhide
name: fedora-43
@ -29,21 +30,23 @@ distros:
# XXX: remove once fedora containers are part of the upstream
# fedora registry (and can be validated via tls)
riscv64: "ghcr.io/mvo5/fedora-buildroot:43"
# XXX: add repos here too, that requires some churn, see
# https://github.com/osbuild/images/compare/main...mvo5:yaml-distroconfig?expand=1
# and we will also need to think about backward compat, as currently
# dropping "$distro-$ver.json" files into
# /etc/osbuild-composer/repositories will define what distros are
# available via images and we will need to provide compatibility for
# that.
#
# Having the repos separated means when a new fedora release is out
# we will need to update two places which is clearly a regression from
# before.
# XXX: add repos here too, that requires some churn, see
# https://github.com/osbuild/images/compare/main...mvo5:yaml-distroconfig?expand=1
# and we will also need to think about backward compat, as currently
# dropping "$distro-$ver.json" files into
# /etc/osbuild-composer/repositories will define what distros are
# available via images and we will need to provide compatibility for
# that.
#
# Having the repos separated means when a new fedora release is out
# we will need to update two places which is clearly a regression from
# before.
- &fedora_stable
<<: *fedora_rawhide
name: "fedora-{{.MajorVersion}}"
match: "fedora-[0-9][0-9]{,[0-9]}"
match: 'fedora-[1-9][0-9]+'
preview: false
os_version: "{{.MajorVersion}}"
release_version: "{{.MajorVersion}}"
@ -63,7 +66,7 @@ distros:
- &rhel10
name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}"
match: "rhel-10.[0-9]{,[0-9]}"
match: 'rhel-10\.[0-9]{1,2}'
distro_like: rhel-10
product: "Red Hat Enterprise Linux"
os_version: "10.{{.MinorVersion}}"
@ -76,7 +79,7 @@ distros:
iso_label_tmpl: "RHEL-{{.Distro.MajorVersion}}-{{.Distro.MinorVersion}}-0-BaseOS-{{.Arch}}"
runner:
name: "org.osbuild.rhel{{.MajorVersion}}{{.MinorVersion}}"
build_packages: &rhel_runner_build_packages
build_packages: &rhel10_runner_build_packages
- "glibc" # ldconfig
- "platform-python" # osbuild
- "systemd" # systemd-tmpfiles and systemd-sysusers
@ -93,10 +96,14 @@ distros:
- ec2
- ec2-sap
- ec2-ha
# rhel9 & cs9 share the same list
# of allowed profiles so a single
# allow list can be used
oscap_profiles_allowlist: &oscap_profile_allowlist_rhel10
"some image types are non-rhel-only":
when:
distro_name: "rhel"
ignore_image_types:
- azure
# rhel & centos share the same list of allowed profiles so a
# single allow list can be used
oscap_profiles_allowlist: &oscap_profile_allowlist_rhel
- "xccdf_org.ssgproject.content_profile_anssi_bp28_enhanced"
- "xccdf_org.ssgproject.content_profile_anssi_bp28_high"
- "xccdf_org.ssgproject.content_profile_anssi_bp28_intermediary"
@ -113,10 +120,15 @@ distros:
- "xccdf_org.ssgproject.content_profile_pci-dss"
- "xccdf_org.ssgproject.content_profile_stig"
- "xccdf_org.ssgproject.content_profile_stig_gui"
bootstrap_containers:
x86_64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
aarch64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
- <<: *rhel10
name: "almalinux-{{.MajorVersion}}.{{.MinorVersion}}"
match: "almalinux-10.[0-9]{,[0-9]}"
match: 'almalinux-10\.[0-9]{1,2}'
product: "AlmaLinux"
vendor: "almalinux"
ostree_ref_tmpl: "almalinux/10/%%s/edge"
@ -137,12 +149,13 @@ distros:
iso_label_tmpl: "CentOS-Stream-{{.Distro.MajorVersion}}-BaseOS-{{.Arch}}"
runner:
name: org.osbuild.centos10
build_packages:
- "glibc" # ldconfig
- "platform-python" # osbuild
- "systemd" # systemd-tmpfiles and systemd-sysusers
- "python3" # osbuild stages
oscap_profiles_allowlist: *oscap_profile_allowlist_rhel10
build_packages: *rhel10_runner_build_packages
oscap_profiles_allowlist: *oscap_profile_allowlist_rhel
bootstrap_containers:
# we need the toolbox container because stock centos has e.g. no
# mount util
x86_64: "quay.io/toolbx-images/centos-toolbox:stream{{.MajorVersion}}"
aarch64: "quay.io/toolbx-images/centos-toolbox:stream{{.MajorVersion}}"
- <<: *centos10
name: "almalinux_kitten-10"
@ -153,9 +166,151 @@ distros:
vendor: "almalinux"
ostree_ref_tmpl: "almalinux/10/%s/edge"
- &rhel9
name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}"
# rhel9 support being named "rhel-91" for "rhel-9.1" or "rhel-910" for "rhel-9.10" etc
match: '(?P<name>rhel)-(?P<major>9)\.?(?P<minor>[0-9]{1,2})'
distro_like: rhel-9
product: "Red Hat Enterprise Linux"
os_version: "9.{{.MinorVersion}}"
release_version: 9
module_platform_id: "platform:el9"
vendor: "redhat"
ostree_ref_tmpl: "rhel/9/%s/edge"
default_fs_type: "xfs"
defs_path: rhel-9
iso_label_tmpl: "RHEL-{{.Distro.MajorVersion}}-{{.Distro.MinorVersion}}-0-BaseOS-{{.Arch}}"
conditions:
"some image types are rhel-only":
when:
not_distro_name: "rhel"
ignore_image_types:
- azure-cvm
- azure-rhui
- azure-sap-rhui
- azure-sapapps-rhui
- ec2
- ec2-sap
- ec2-ha
"some image types are non-rhel-only":
when:
distro_name: "rhel"
ignore_image_types:
- azure
"CVM is only available starting from 9.6":
when:
version_less_than: "9.6"
ignore_image_types:
- "azure-cvm"
runner:
name: "org.osbuild.rhel{{.MajorVersion}}{{.MinorVersion}}"
build_packages: &rhel9_runner_build_packages
- "glibc" # ldconfig
- "systemd" # systemd-tmpfiles and systemd-sysusers
- "platform-python" # osbuild
- "python3"
# rhel9 allow all
oscap_profiles_allowlist: *oscap_profile_allowlist_rhel
bootstrap_containers:
x86_64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
aarch64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
- &centos9
<<: *rhel9
name: centos-9
distro_like: rhel-9
product: "CentOS Stream"
os_version: "9-stream"
vendor: "centos"
ostree_ref_tmpl: "centos/9/%s/edge"
default_fs_type: "xfs"
defs_path: rhel-9
iso_label_tmpl: "CentOS-Stream-{{.Distro.MajorVersion}}-BaseOS-{{.Arch}}"
runner:
name: org.osbuild.centos9
build_packages: *rhel9_runner_build_packages
bootstrap_containers:
# we need the toolbox container because stock centos has e.g. no
# mount util
x86_64: "quay.io/toolbx-images/centos-toolbox:stream{{.MajorVersion}}"
aarch64: "quay.io/toolbx-images/centos-toolbox:stream{{.MajorVersion}}"
- &rhel8
name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}"
# rhel8 support being named "rhel-81" for "rhel-8.1" or "rhel-810" for "rhel-8.10" etc
match: '(?P<name>rhel)-(?P<major>8)\.?(?P<minor>[0-9]{1,2})'
distro_like: rhel-8
product: "Red Hat Enterprise Linux"
os_version: "8.{{.MinorVersion}}"
release_version: 8
module_platform_id: "platform:el8"
vendor: "redhat"
ostree_ref_tmpl: "rhel/8/%s/edge"
default_fs_type: "xfs"
defs_path: rhel-8
iso_label_tmpl: "RHEL-{{.Distro.MajorVersion}}-{{.Distro.MinorVersion}}-0-BaseOS-{{.Arch}}"
conditions:
"edge image types require FDO which aren't available on older versions":
when:
version_less_than: "8.6"
ignore_image_types:
- "edge-simplified-installer"
- "edge-raw-image"
"azure eap7 is only available for rhel8.6+":
when:
version_less_than: "8.6"
ignore_image_types:
- "azure-eap7-rhui"
"Azure image types require hyperv-daemons which isn't available on older versions":
when:
version_less_than: "8.6"
arch: "aarch64"
ignore_image_types:
- "azure-rhui"
- "vhd"
runner:
name: "org.osbuild.rhel{{.MajorVersion}}{{.MinorVersion}}"
build_packages: &rhel8_runner_build_packages
- "glibc" # ldconfig
- "systemd" # systemd-tmpfiles and systemd-sysusers
- "platform-python" # osbuild
# The RHEL 8 runner in osbuild runs with platform-python but
# explicitly symlinks python 3.6 to /etc/alternatives (which in turn
# is the target for /usr/bin/python3) for the stages.
# https://github.com/osbuild/osbuild/blob/ea8261cad6c5c606c00c0f2824c3f483c01a0cc9/runners/org.osbuild.rhel82#L61
# Install python36 explicitly for RHEL 8.
- "python36"
oscap_profiles_allowlist: *oscap_profile_allowlist_rhel
bootstrap_containers:
x86_64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
aarch64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
- &centos8
<<: *rhel8
name: centos-8
distro_like: rhel-8
product: "CentOS Stream"
os_version: "8-stream"
vendor: "centos"
default_fs_type: "xfs"
iso_label_tmpl: "CentOS-Stream-{{.Distro.MajorVersion}}-BaseOS-{{.Arch}}"
runner:
name: org.osbuild.centos8
build_packages: *rhel8_runner_build_packages
oscap_profiles_allowlist: *oscap_profile_allowlist_rhel
bootstrap_containers:
# we need the toolbox container because stock centos has e.g. no
# mount util
x86_64: "quay.io/toolbx-images/centos-toolbox:stream{{.MajorVersion}}"
aarch64: "quay.io/toolbx-images/centos-toolbox:stream{{.MajorVersion}}"
- &rhel7
name: "rhel-{{.MajorVersion}}.{{.MinorVersion}}"
match: "rhel-7.[0-9]{,[0-9]}"
match: 'rhel-7\.[0-9]'
distro_like: rhel-7
product: "Red Hat Enterprise Linux"
codename: "Maipo"
@ -176,3 +331,7 @@ distros:
# https://github.com/osbuild/osbuild/blob/ea8261cad6c5c606c00c0f2824c3f483c01a0cc9/runners/org.osbuild.rhel82#L61
# Install python36 explicitly for RHEL 8.
- "python36"
bootstrap_containers:
x86_64: "registry.access.redhat.com/ubi{{.MajorVersion}}/ub i:latest"
ppc64le: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"
s390x: "registry.access.redhat.com/ubi{{.MajorVersion}}/ubi:latest"

View file

@ -175,6 +175,7 @@
- "org.fedoraproject.Anaconda.Modules.Users"
additional_dracut_modules:
- "net-lib"
- "dbus-broker"
squashfs_rootfs: true
conditions:
"f41 dracut requires ifcfg, rootfs is squashfs":
@ -183,12 +184,14 @@
shallow_merge:
additional_dracut_modules:
- "ifcfg"
- "dbus-broker"
"f40 and lower uses ifcfg in dracut and squashfs+ext4 rootfs":
when:
version_less_than: "41"
shallow_merge:
additional_dracut_modules:
- "ifcfg"
- "dbus-broker"
squashfs_rootfs: false
image_config:
@ -228,6 +231,15 @@
- "zezere_ignition_banner.service"
- "parsec"
- "dbus-parsec"
"f43 uses new greenboot":
when:
version_greater_or_equal: "43"
shallow_merge:
enabled_services:
- "NetworkManager.service"
- "firewalld.service"
- "sshd.service"
- "greenboot-healthcheck"
iot: &image_config_iot
<<: *image_config_iot_enabled_services
keyboard:
@ -770,8 +782,9 @@ image_types:
payload_pipelines: ["os", "ostree-commit", "commit-archive"]
exports: ["commit-archive"]
required_partition_sizes: *default_required_dir_sizes
image_config:
image_config: &image_config_iot_commit
<<: *image_config_iot_enabled_services
install_weak_deps: false
dracut_conf:
- filename: "40-fips.conf"
config:
@ -930,6 +943,9 @@ image_types:
payload_pipelines: ["os", "ostree-commit", "container-tree", "container"]
exports: ["container"]
required_partition_sizes: *default_required_dir_sizes
image_config:
<<: *image_config_iot_commit
install_weak_deps: true
platforms:
- *x86_64_installer_platform
- *aarch64_installer_platform
@ -944,8 +960,8 @@ image_types:
bootable: true
image_func: "iot"
ostree:
name: "fedora"
remote: "fedora-iot"
name: "fedora-iot"
remote_name: "fedora-iot"
build_pipelines: ["build"]
payload_pipelines: ["ostree-deployment", "image", "xz"]
exports: ["xz"]
@ -1023,8 +1039,8 @@ image_types:
bootable: true
image_func: "iot"
ostree:
name: "fedora"
remote: "fedora-iot"
name: "fedora-iot"
remote_name: "fedora-iot"
build_pipelines: ["build"]
payload_pipelines: ["ostree-deployment", "image", "qcow2"]
exports: ["qcow2"]
@ -1488,9 +1504,10 @@ image_types:
boot_iso: true
image_func: "iot_installer"
iso_label: "IoT"
variant: "IoT"
ostree:
name: "fedora-iot"
remote: "fedora-iot"
remote_name: "fedora-iot"
build_pipelines: ["build"]
payload_pipelines:
- "anaconda-tree"
@ -1843,9 +1860,10 @@ image_types:
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
image_func: "iot_simplified_installer"
iso_label: "IoT"
variant: "IoT"
ostree:
name: "fedora"
remote: "fedora-iot"
remote_name: "fedora-iot"
build_pipelines: ["build"]
payload_pipelines:
- "ostree-deployment"

80
vendor/github.com/osbuild/images/pkg/distro/defs/id.go generated vendored Normal file
View file

@ -0,0 +1,80 @@
package defs
import (
"fmt"
"regexp"
"github.com/osbuild/images/pkg/distro"
)
func validateSubexpMatch(re *regexp.Regexp, names ...string) error {
for _, name := range names {
if re.SubexpIndex(name) == -1 {
return fmt.Errorf("cannot find submatch field %q", name)
}
}
return nil
}
// matchAndNormalize() matches and normalizes the given nameVer
// based on the reStr. On match it returns the normalized version
// of the given nameVer.
func matchAndNormalize(reStr, nameVer string) (string, error) {
if reStr == "" {
return "", nil
}
re, err := regexp.Compile(`^` + reStr + `$`)
if err != nil {
return "", fmt.Errorf("cannot use %q: %w", reStr, err)
}
l := re.FindStringSubmatch(nameVer)
switch len(l) {
case 0:
// no match
return "", nil
case 1:
// simple match, no named matching
return nameVer, nil
// handling case 2: is not needed, its an incomplete match, we need at least name,major and
// captured by the "default" below
case 3:
// distro only uses major ver and needs normalizing
if err := validateSubexpMatch(re, "name", "major"); err != nil {
return "", err
}
return fmt.Sprintf("%s-%s", l[re.SubexpIndex("name")], l[re.SubexpIndex("major")]), nil
case 4:
// common case, major/minor and normalizing
if err := validateSubexpMatch(re, "name", "major", "minor"); err != nil {
return "", err
}
return fmt.Sprintf("%s-%s.%s", l[re.SubexpIndex("name")], l[re.SubexpIndex("major")], l[re.SubexpIndex("minor")]), nil
default:
return "", fmt.Errorf("invalid number of submatches for %q %q (%v)", reStr, nameVer, len(l))
}
}
// ParseID parse the given nameVer into a distro.ID. It will also
// apply normalizations from the distros `match` rule. This is needed
// to support distro names like "rhel-810" without dots.
//
// If no match is found it will "nil" and no error (
func ParseID(nameVer string) (*distro.ID, error) {
distros, err := loadDistros()
if err != nil {
return nil, err
}
for _, d := range distros.Distros {
found, err := matchAndNormalize(d.Match, nameVer)
if err != nil {
return nil, err
}
if found != "" {
return distro.ParseID(found)
}
}
return nil, nil
}

View file

@ -13,7 +13,6 @@ import (
"sort"
"text/template"
"github.com/gobwas/glob"
"gopkg.in/yaml.v3"
"github.com/osbuild/images/internal/common"
@ -32,7 +31,6 @@ import (
)
var (
ErrImageTypeNotFound = errors.New("image type not found")
ErrNoPartitionTableForImgType = errors.New("no partition table for image type")
ErrNoPartitionTableForArch = errors.New("no partition table for arch")
)
@ -59,13 +57,11 @@ type distrosYAML struct {
}
type DistroYAML struct {
// Match can be used to match multiple versions via a
// fnmatch/glob style expression. We could also use a
// regex and do something like:
// rhel-(?P<major>[0-9]+)\.(?P<minor>[0-9]+)
// if we need to be more precise in the future, but for
// now every match will be split into "$distroname-$major.$minor"
// (with minor being optional)
// Match can be used to match/transform a given name
// into the canonical <distro>-<major>{,.<minor>} form.
// E.g.
// (?P<distro>rhel)-(?P<major>8)\.?(?P<minor>[0-9]+)
// will support a format like e.g. rhel-810 and rhel-8.10
Match string `yaml:"match"`
// The distro metadata, can contain go text template strings
@ -166,14 +162,7 @@ func (d *DistroYAML) runTemplates(nameVer string) error {
return errors.Join(errs...)
}
// NewDistroYAML return the given distro or nil if the distro is not
// found. This mimics the "distrofactory.GetDistro() interface.
//
// Note that eventually we want something like "Distros()" instead
// that returns all known distros but for now we keep compatibility
// with the way distrofactory/reporegistry work which is by defining
// distros via repository files.
func NewDistroYAML(nameVer string) (*DistroYAML, error) {
func loadDistros() (*distrosYAML, error) {
f, err := dataFS().Open("distros.yaml")
if err != nil {
return nil, err
@ -188,6 +177,27 @@ func NewDistroYAML(nameVer string) (*DistroYAML, error) {
return nil, err
}
return &distros, nil
}
// NewDistroYAML return the given distro or nil if the distro is not
// found. This mimics the "distrofactory.GetDistro() interface.
//
// Note that eventually we want something like "Distros()" instead
// that returns all known distros but for now we keep compatibility
// with the way distrofactory/reporegistry work which is by defining
// distros via repository files.
func NewDistroYAML(nameVer string) (*DistroYAML, error) {
distros, err := loadDistros()
if err != nil {
return nil, err
}
// ParseID will also canonicalize the name
if id, err := ParseID(nameVer); err == nil && id != nil {
nameVer = id.String()
}
var foundDistro *DistroYAML
for _, distro := range distros.Distros {
if distro.Name == nameVer {
@ -195,32 +205,33 @@ func NewDistroYAML(nameVer string) (*DistroYAML, error) {
break
}
pat, err := glob.Compile(distro.Match)
found, err := matchAndNormalize(distro.Match, nameVer)
if err != nil {
return nil, err
}
if pat.Match(nameVer) {
if err := distro.runTemplates(nameVer); err != nil {
return nil, err
}
if found != "" {
foundDistro = &distro
// nameVer must be replaced with normalized name
nameVer = found
break
}
}
if foundDistro == nil {
return nil, nil
}
if err := foundDistro.runTemplates(nameVer); err != nil {
return nil, err
}
// load imageTypes
f, err = dataFS().Open(filepath.Join(foundDistro.DefsPath, "distro.yaml"))
f, err := dataFS().Open(filepath.Join(foundDistro.DefsPath, "distro.yaml"))
if err != nil {
return nil, err
}
defer f.Close()
var toplevel imageTypesYAML
decoder = yaml.NewDecoder(f)
decoder := yaml.NewDecoder(f)
decoder.KnownFields(true)
if err := decoder.Decode(&toplevel); err != nil {
return nil, err
@ -350,7 +361,11 @@ type ImageTypeYAML struct {
Environment environment.EnvironmentConf `yaml:"environment"`
Bootable bool `yaml:"bootable"`
BootISO bool `yaml:"boot_iso"`
BootISO bool `yaml:"boot_iso"`
// XXX merge with BootISO above, controls if grub2 or syslinux are used for ISO boots
UseSyslinux bool `yaml:"use_syslinux"`
UseLegacyAnacondaConfig bool `yaml:"use_legacy_anaconda_config"`
ISOLabel string `yaml:"iso_label"`
// XXX: or iso_variant?
Variant string `yaml:"variant"`
@ -358,9 +373,11 @@ type ImageTypeYAML struct {
RPMOSTree bool `yaml:"rpm_ostree"`
OSTree struct {
Name string `yaml:"name"`
Remote string `yaml:"remote"`
Name string `yaml:"name"`
RemoteName string `yaml:"remote_name"`
} `yaml:"ostree"`
// XXX: rhel-8 uses this
UseOstreeRemotes bool `yaml:"use_ostree_remotes"`
DefaultSize uint64 `yaml:"default_size"`
// the image func name: disk,container,live-installer,...
@ -370,10 +387,13 @@ type ImageTypeYAML struct {
Exports []string `yaml:"exports"`
RequiredPartitionSizes map[string]uint64 `yaml:"required_partition_sizes"`
Platforms []platform.PlatformConf `yaml:"platforms"`
InternalPlatforms []platform.PlatformConf `yaml:"platforms"`
PlatformsOverride *platformsOverride `yaml:"platforms_override"`
NameAliases []string `yaml:"name_aliases"`
InstallWeakDeps *bool `yaml:"install_weak_deps"`
// for RHEL7 compat
// TODO: determine a better place for these options, but for now they are here
DiskImagePartTool *osbuild.PartTool `yaml:"disk_image_part_tool"`
@ -389,6 +409,29 @@ func (it *ImageTypeYAML) Name() string {
return it.name
}
func (it *ImageTypeYAML) PlatformsFor(distroNameVer string) ([]platform.PlatformConf, error) {
pl := it.InternalPlatforms
if it.PlatformsOverride != nil {
id, err := distro.ParseID(distroNameVer)
if err != nil {
return nil, err
}
var nMatches int
for _, cond := range it.PlatformsOverride.Conditions {
// arch does not make sense for platform overrides
arch := ""
if cond.When.Eval(id, arch) {
pl = cond.Override
nMatches++
}
}
if nMatches > 1 {
return nil, fmt.Errorf("platform conditionals for image type %q should match only once but matched %v times", it.Name(), nMatches)
}
}
return pl, nil
}
func (it *ImageTypeYAML) runTemplates(distro *DistroYAML) error {
var data any
// set the DistroVendor in the struct only if its actually
@ -401,22 +444,48 @@ func (it *ImageTypeYAML) runTemplates(distro *DistroYAML) error {
DistroVendor: distro.Vendor,
}
}
for idx := range it.Platforms {
// fill the UEFI vendor string
templ, err := template.New("uefi-vendor").Parse(it.Platforms[idx].UEFIVendor)
subs := func(inp string) (string, error) {
templ, err := template.New("uefi-vendor").Parse(inp)
templ.Option("missingkey=error")
if err != nil {
return fmt.Errorf(`cannot parse template for "vendor" field: %w`, err)
return "", fmt.Errorf(`cannot parse template for "vendor" field: %w`, err)
}
var buf bytes.Buffer
if err := templ.Execute(&buf, data); err != nil {
return fmt.Errorf(`cannot execute template for "vendor" field (is it set?): %w`, err)
return "", fmt.Errorf(`cannot execute template for "vendor" field (is it set?): %w`, err)
}
return buf.String(), nil
}
for idx := range it.InternalPlatforms {
newVendor, err := subs(it.InternalPlatforms[idx].UEFIVendor)
if err != nil {
return err
}
it.InternalPlatforms[idx].UEFIVendor = newVendor
}
if it.PlatformsOverride != nil {
for _, cond := range it.PlatformsOverride.Conditions {
for idx := range cond.Override {
newVendor, err := subs(cond.Override[idx].UEFIVendor)
if err != nil {
return err
}
cond.Override[idx].UEFIVendor = newVendor
}
}
it.Platforms[idx].UEFIVendor = buf.String()
}
return nil
}
type platformsOverride struct {
Conditions map[string]*conditionsPlatforms `yaml:"conditions,omitempty"`
}
type conditionsPlatforms struct {
When whenCondition `yaml:"when,omitempty"`
Override []platform.PlatformConf `yaml:"override"`
}
type imageConfig struct {
*distro.ImageConfig `yaml:",inline"`
Conditions map[string]*conditionsImgConf `yaml:"conditions,omitempty"`

View file

@ -1,199 +0,0 @@
package defs
// this file contains legacy code and it can be removed once
// all of rhel is converted to the "generic" distro
import (
"bytes"
"crypto/sha256"
"fmt"
"io"
"os"
"path/filepath"
"sync"
"gopkg.in/yaml.v3"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/rpmmd"
)
// XXX: compat only, will go away once we move to "generic" distros
// everywhere
func PackageSets(it distro.ImageType) (map[string]rpmmd.PackageSet, error) {
archName := it.Arch().Name()
distroNameVer := it.Arch().Distro().Name()
// each imagetype can have multiple package sets, so that we can
// use yaml aliases/anchors to de-duplicate them
toplevel, err := load(distroNameVer)
if err != nil {
return nil, err
}
imgType, ok := toplevel.ImageTypes[it.Name()]
if !ok {
return nil, fmt.Errorf("%w: %q", ErrImageTypeNotFound, it.Name())
}
return imgType.PackageSets(distroNameVer, archName)
}
// XXX: compat only, will go away once we move to "generic" distros
// everywhere
func PartitionTable(it distro.ImageType) (*disk.PartitionTable, error) {
distroNameVer := it.Arch().Distro().Name()
toplevel, err := load(distroNameVer)
if err != nil {
return nil, err
}
imgType, ok := toplevel.ImageTypes[it.Name()]
if !ok {
return nil, fmt.Errorf("%w: %q", ErrImageTypeNotFound, it.Name())
}
return imgType.PartitionTable(distroNameVer, it.Arch().Name())
}
// XXX: compat only, will go away once we move to "generic" distros
// everywhere
func DistroImageConfig(distroNameVer string) (*distro.ImageConfig, error) {
toplevel, err := load(distroNameVer)
if err != nil {
return nil, err
}
return toplevel.ImageConfig.For(distroNameVer)
}
// XXX: compat only, will go away once we move to "generic" distros
// everywhere
func ImageConfig(distroNameVer, archName, typeName string) (*distro.ImageConfig, error) {
toplevel, err := load(distroNameVer)
if err != nil {
return nil, err
}
imgType, ok := toplevel.ImageTypes[typeName]
if !ok {
return nil, fmt.Errorf("%w: %q", ErrImageTypeNotFound, typeName)
}
return imgType.ImageConfig(distroNameVer, archName)
}
// XXX: compat only, will go away once we move to "generic" distros
// everywhere
func InstallerConfig(distroNameVer, archName, typeName string) (*distro.InstallerConfig, error) {
toplevel, err := load(distroNameVer)
if err != nil {
return nil, err
}
imgType, ok := toplevel.ImageTypes[typeName]
if !ok {
return nil, fmt.Errorf("%w: %q", ErrImageTypeNotFound, typeName)
}
imgType.name = typeName
return imgType.InstallerConfig(distroNameVer, archName)
}
// Cache the toplevel structure, loading/parsing YAML is quite
// expensive. This can all be removed in the future where there
// is a single load for each distroNameVer. Right now the various
// helpers (like ParititonTable(), ImageConfig() are called a
// gazillion times. However once we move into the "generic" distro
// the distro will do a single load/parse of all image types and
// just reuse them and this can go.
type imageTypesCache struct {
cache map[string]*imageTypesYAML
mu sync.Mutex
}
func newImageTypesCache() *imageTypesCache {
return &imageTypesCache{cache: make(map[string]*imageTypesYAML)}
}
func (i *imageTypesCache) Get(hash string) *imageTypesYAML {
i.mu.Lock()
defer i.mu.Unlock()
return i.cache[hash]
}
func (i *imageTypesCache) Set(hash string, ity *imageTypesYAML) {
i.mu.Lock()
defer i.mu.Unlock()
i.cache[hash] = ity
}
var (
itCache = newImageTypesCache()
)
func load(distroNameVer string) (*imageTypesYAML, error) {
id, err := distro.ParseID(distroNameVer)
if err != nil {
return nil, err
}
// XXX: this is only needed temporary until we have a "distros.yaml"
// that describes some high-level properties of each distro
// (like their yaml dirs)
var baseDir string
switch id.Name {
case "rhel", "almalinux", "centos", "almalinux_kitten":
// rhel yaml files are under ./rhel-$majorVer
// almalinux yaml is just rhel, we take only its major version
// centos and kitten yaml is just rhel but we have (sadly) no
// symlinks in "go:embed" so we have to have this slightly ugly
// workaround
baseDir = fmt.Sprintf("rhel-%v", id.MajorVersion)
case "test-distro":
// our other distros just have a single yaml dir per distro
// and use condition.version_gt etc
baseDir = id.Name
}
// take the base path from the distros.yaml
distro, err := NewDistroYAML(distroNameVer)
if err != nil && !os.IsNotExist(err) {
return nil, err
}
if distro != nil && distro.DefsPath != "" {
baseDir = distro.DefsPath
}
f, err := dataFS().Open(filepath.Join(baseDir, "distro.yaml"))
if err != nil {
return nil, err
}
defer f.Close()
// XXX: this is currently needed because rhel distros call
// ImageType() and ParitionTable() a gazillion times and
// each time the full yaml is loaded. Once things move to
// the "generic" distro this will no longer be the case and
// this cache can be removed and below we can decode directly
// from "f" again instead of wasting memory with "buf"
var buf bytes.Buffer
h := sha256.New()
if _, err := io.Copy(io.MultiWriter(&buf, h), f); err != nil {
return nil, fmt.Errorf("cannot read from %s: %w", baseDir, err)
}
inputHash := string(h.Sum(nil))
if cached := itCache.Get(inputHash); cached != nil {
return cached, nil
}
var toplevel imageTypesYAML
decoder := yaml.NewDecoder(&buf)
decoder.KnownFields(true)
if err := decoder.Decode(&toplevel); err != nil {
return nil, err
}
// XXX: remove once we no longer need caching
itCache.Set(inputHash, &toplevel)
return &toplevel, nil
}

View file

@ -282,6 +282,16 @@
- "mdadm"
- "nss-softokn"
wsl_config: &wsl_config
config:
boot_systemd: true
distribution_config: &wsl_distribution_config
shortcut:
enabled: true
icon: /usr/share/pixmaps/fedora-logo.ico
oobe: &wsl_distribution_oobe_config
default_uid: 1000
anaconda_boot_pkgset: &anaconda_boot_pkgset
conditions:
"x86 specific packages for the anaconda boot pkgset":
@ -414,7 +424,7 @@
timeout: 10
timeout_style: "countdown"
azure_image_config: &azure_image_config
azure_image_config_base: &azure_image_config_base
# from CreateAzureDatalossWarningScriptAndUnit
files:
- path: &dataloss_script "/usr/local/sbin/temp-disk-dataloss-warning"
@ -528,8 +538,6 @@
config:
"ResourceDisk.Format": false
"ResourceDisk.EnableSwap": false
"Provisioning.UseCloudInit": true
"Provisioning.Enabled": false
grub2_config:
disable_recovery: true
disable_submenu: true
@ -582,9 +590,24 @@
shallow_merge:
gpgkey_files:
- "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
"x86_64 specific kernel commandline":
"x86_64 specific kernel commandline for rhel-10.1+":
when:
arch: "x86_64"
version_greater_or_equal: "10.1"
shallow_merge:
kernel_options:
# common
- "ro"
- "nvme_core.io_timeout=240"
# x86
- "console=tty1"
- "console=ttyS0"
- "earlyprintk=ttyS0"
- "rootdelay=300"
"x86_64 specific kernel commandline for rhel-10.0":
when:
arch: "x86_64"
version_equal: "10.0"
shallow_merge:
kernel_options:
# common
@ -596,9 +619,21 @@
- "console=ttyS0"
- "earlyprintk=ttyS0"
- "rootdelay=300"
"aarch64 specific kernel commandline":
"aarch64 specific kernel commandline for rhel-10.1+":
when:
arch: "aarch64"
version_greater_or_equal: "10.1"
shallow_merge:
kernel_options:
# common
- "ro"
- "nvme_core.io_timeout=240"
# aarch64
- "console=ttyAMA0"
"aarch64 specific kernel commandline for rhel-10.0":
when:
arch: "aarch64"
version_equal: "10.0"
shallow_merge:
kernel_options:
# common
@ -628,6 +663,7 @@ image_config:
default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml"
install_weak_deps: true
locale: "C.UTF-8"
permissive_rhc: true
sysconfig:
networking: true
no_zero_conf: true
@ -861,7 +897,7 @@ image_types:
image_format: "vhd"
# based on https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/deploying_rhel_9_on_microsoft_azure/assembly_deploying-a-rhel-image-as-a-virtual-machine-on-microsoft-azure_cloud-content-azure#making-configuration-changes_configure-the-image-azure
image_config: &image_config_vhd
<<: *azure_image_config
<<: *azure_image_config_base
time_synchronization:
refclocks:
- driver:
@ -909,7 +945,6 @@ image_types:
- "patch"
- "rng-tools"
- "selinux-policy-targeted"
- "system-reinstall-bootc"
- "uuid"
- "WALinuxAgent"
- "yum-utils"
@ -961,15 +996,21 @@ image_types:
- "rhnlib"
- "rhnsd"
- "usb_modeswitch"
conditions: &conditions_pkgsets_insights_client_on_rhel
conditions:
"add insights client on rhel":
when:
distro_name: "rhel"
append:
include:
- "insights-client"
"add system-reinstall-bootc on rhel":
when:
distro_name: "rhel"
append:
include:
- "system-reinstall-bootc"
"azure-rhui": &azure_rhui
"azure": &azure
<<: *vhd
payload_pipelines: ["os", "image", "vpc", "xz"]
exports: ["xz"]
@ -1067,6 +1108,9 @@ image_types:
- *azure_rhui_part_boot
- *azure_rhui_part_lvm
"azure-rhui": &azure_rhui
<<: *azure
"azure-sap-rhui":
<<: *azure_rhui
platforms:
@ -1290,7 +1334,6 @@ image_types:
- "redhat-release"
- "redhat-release-eula"
- "rsync"
- "system-reinstall-bootc"
- "tuned"
- "tar"
exclude:
@ -1326,7 +1369,18 @@ image_types:
# RHBZ#2075815
- "qemu-guest-agent"
conditions:
<<: *conditions_pkgsets_insights_client_on_rhel
"add insights client on rhel":
when:
distro_name: "rhel"
append:
include:
- "insights-client"
"add system-reinstall-bootc on rhel":
when:
distro_name: "rhel"
append:
include:
- "system-reinstall-bootc"
# RHEL internal-only x86_64 EC2 image type
ec2: &ec2
@ -1395,24 +1449,7 @@ image_types:
- arch: "x86_64"
- arch: "aarch64"
image_config:
cloud_init:
- filename: "99_wsl.cfg"
config:
datasource_list:
- "WSL"
- "None"
network:
config: "disabled"
no_selinux: true
wsl: &wsl_config
config:
boot_systemd: true
distribution_config: &wsl_distribution_config
shortcut:
enabled: true
icon: /usr/share/pixmaps/fedora-logo.ico
oobe: &wsl_distribution_oobe_config
default_uid: 1000
conditions:
"wsl config for rhel":
when:
@ -1425,17 +1462,6 @@ image_types:
oobe:
<<: *wsl_distribution_oobe_config
default_name: RedHatEnterpriseLinux-%s
"wsl config for centos":
when:
distro_name: "centos"
shallow_merge:
wsl:
<<: *wsl_config
distribution_config:
<<: *wsl_distribution_config
oobe:
<<: *wsl_distribution_oobe_config
default_name: CentOS-%s
"wsl config for almalinux":
when:
distro_name: "almalinux"
@ -1453,6 +1479,19 @@ image_types:
shallow_merge:
wsl:
<<: *wsl_distribution_config_almalinux
"cloud-init config for non-centos":
when:
not_distro_name: "centos"
shallow_merge:
cloud_init:
- filename: "99_wsl.cfg"
config:
datasource_list:
- "WSL"
- "None"
network:
config: "disabled"
package_sets:
os:
- include:
@ -1461,7 +1500,6 @@ image_types:
- "basesystem"
- "bash"
- "ca-certificates"
- "cloud-init"
- "coreutils-single"
- "crypto-policies-scripts"
- "curl-minimal"
@ -1486,14 +1524,11 @@ image_types:
- "procps-ng"
- "python3"
- "python3-inotify"
- "redhat-logos"
- "redhat-release"
- "rootfiles"
- "rpm"
- "sed"
- "setup"
- "shadow-utils"
- "subscription-manager"
- "sudo"
- "systemd"
- "tar"
@ -1510,6 +1545,25 @@ image_types:
- "python-unversioned-command"
- "redhat-release-eula"
- "rpm-plugin-systemd-inhibit"
conditions:
"subscription-manager, cloud-init, and redhat-* on rhel-likes except centos":
when:
not_distro_name: "centos"
append:
include:
- "subscription-manager"
- "cloud-init"
- "redhat-logos"
- "redhat-release"
"wsl-setup, and centos-* on centos":
when:
distro_name: "centos"
append:
include:
- "wsl-setup"
- "centos-logos"
- "centos-release"
"image-installer":
filename: "installer.iso"
@ -1846,7 +1900,12 @@ image_types:
# RHBZ#2075815
- "qemu-guest-agent"
conditions:
<<: *conditions_pkgsets_insights_client_on_rhel
"add insights client on rhel":
when:
distro_name: "rhel"
append:
include:
- "insights-client"
"azure-cvm":
<<: *vhd
@ -1867,43 +1926,6 @@ image_types:
- "kernel-uki-virt-addons" # provides useful cmdline utilities for the UKI
- "shim-x64"
- "uki-direct"
image_config:
<<: *azure_image_config
default_kernel: "kernel-uki-virt"
default_kernel_name: "kernel-uki-virt"
no_bls: true
cloud_init:
- filename: "91-azure_datasource.cfg"
config:
datasource:
azure:
apply_network_config: false
datasource_list:
- "Azure"
package_sets:
os:
- include:
- "@minimal-environment"
- "chrony"
- "cloud-init"
- "cloud-utils-growpart"
- "cryptsetup"
- "NetworkManager-cloud-setup"
- "openssh-server"
- "redhat-cloud-client-configuration"
- "redhat-release"
- "tpm2-tools"
- "WALinuxAgent"
- exclude:
- "dracut-config-rescue"
- "grubby"
- "iwl*"
# In EL9 we exclude linux-firmware* (note the asterisk).
# In EL10, packages in the minimal-environment group require
# linux-firmware-whence, so we only exclude the linux-firmware
# package here.
- "linux-firmware"
- "os-prober"
partition_table:
x86_64:
uuid: "D209C89E-EA5E-4FBD-B161-B461CCE297E0"
@ -1931,3 +1953,52 @@ image_types:
fstab_options: "defaults"
fstab_freq: 0
fstab_passno: 0
image_config:
<<: *azure_image_config_base
default_kernel: "kernel-uki-virt"
default_kernel_name: "kernel-uki-virt"
no_bls: true
cloud_init:
- filename: "91-azure_datasource.cfg"
config:
datasource:
azure:
apply_network_config: false
datasource_list:
- "Azure"
conditions:
"x86_64 shim package version lock":
# Lock the shim package to its installed version. This is necessary
# for UKI-based images that can become unbootable if the shim is
# upgraded to one signed by a newer certificate that does not exist
# in the system's database.
# See https://issues.redhat.com/browse/RHEL-93650
when:
arch: "x86_64"
shallow_merge:
versionlock_packages:
- "shim-x64"
package_sets:
os:
- include:
- "@minimal-environment"
- "chrony"
- "cloud-init"
- "cloud-utils-growpart"
- "cryptsetup"
- "NetworkManager-cloud-setup"
- "openssh-server"
- "redhat-cloud-client-configuration"
- "redhat-release"
- "tpm2-tools"
- "WALinuxAgent"
- exclude:
- "dracut-config-rescue"
- "grubby"
- "iwl*"
# In EL9 we exclude linux-firmware* (note the asterisk).
# In EL10, packages in the minimal-environment group require
# linux-firmware-whence, so we only exclude the linux-firmware
# package here.
- "linux-firmware"
- "os-prober"

View file

@ -765,6 +765,104 @@
- "insights-client"
- "subscription-manager-cockpit"
disk_sizes:
default_required_partition_sizes: &default_required_dir_sizes
"/": 1_073_741_824 # 1 * datasizes.GiB
"/usr": 2_147_483_648 # 2 * datasizes.GiB
platforms:
x86_64_uefi_platform: &x86_64_uefi_platform
arch: "x86_64"
bootloader: "grub2"
uefi_vendor: "{{.DistroVendor}}"
packages: &x86_64_uefi_platform_packages
uefi:
- "dracut-config-generic"
- "efibootmgr"
- "grub2-efi-x64"
- "shim-x64"
x86_64_bios_platform: &x86_64_bios_platform
<<: *x86_64_uefi_platform
bios_platform: "i386-pc"
uefi_vendor: "{{.DistroVendor}}"
packages: &x86_64_bios_platform_packages
<<: *x86_64_uefi_platform_packages
bios:
- "dracut-config-generic"
- "grub2-pc"
build_packages:
bios:
- "grub2-pc"
x86_64_bios_only_platform: &x86_64_bios_only_platform
arch: "x86_64"
bios_platform: "i386-pc"
bootloader: "grub2"
image_format: "raw"
packages:
bios:
- "grub2-pc"
build_packages:
bios:
- "grub2-pc"
# XXX: rename to bareMetalX86Platform?
x86_64_installer_platform: &x86_64_installer_platform
<<: *x86_64_bios_platform
image_format: "raw"
packages:
<<: *x86_64_bios_platform_packages
firmware:
- "microcode_ctl" # ??
- "iwl1000-firmware"
- "iwl100-firmware"
- "iwl105-firmware"
- "iwl135-firmware"
- "iwl2000-firmware"
- "iwl2030-firmware"
- "iwl3160-firmware"
- "iwl5000-firmware"
- "iwl5150-firmware"
- "iwl6050-firmware"
aarch64_platform: &aarch64_platform
arch: "aarch64"
bootloader: "grub2"
uefi_vendor: "{{.DistroVendor}}"
image_format: "qcow2"
packages: &aarch64_uefi_platform_packages
uefi:
- "dracut-config-generic"
- "efibootmgr"
- "grub2-efi-aa64"
- "grub2-tools"
- "shim-aa64"
ppc64le_bios_platform: &ppc64le_bios_platform
arch: "ppc64le"
bootloader: "grub2"
bios_platform: "powerpc-ieee1275"
image_format: "qcow2"
packages:
bios:
- "dracut-config-generic"
- "powerpc-utils"
- "grub2-ppc64le"
- "grub2-ppc64le-modules"
build_packages:
bios:
- "grub2-ppc64le"
- "grub2-ppc64le-modules"
s390x_zipl_platform: &s390x_zipl_platform
arch: "s390x"
bootloader: "zipl"
zipl_support: true
image_format: "qcow2"
packages:
zipl:
- "dracut-config-generic"
- "s390utils-base"
- "s390utils-core"
build_packages:
zipl:
- "s390utils-base"
partitioning:
ids:
- &prep_partition_dosid "41"
@ -1000,7 +1098,6 @@
- *ec2_partition_table_part_root
aarch64:
<<: *ec2_partition_table_aarch64_8_9
azure_rhui_partition_tables: &azure_rhui_partition_tables
x86_64:
uuid: "D209C89E-EA5E-4FBD-B161-B461CCE297E0"
@ -1099,6 +1196,7 @@ image_config:
install_weak_deps: true
kernel_options_bootloader: true
locale: "en_US.UTF-8"
permissive_rhc: false
sysconfig:
networking: true
no_zero_conf: true
@ -1165,6 +1263,34 @@ image_types:
<<: *condition_rhel_insights_clinet_subman
ami: &ami
filename: "image.raw"
mime_type: "application/octet-stream"
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image"]
exports: ["image"]
bootable: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
platforms_override:
conditions:
"Keep the RHEL EC2 x86_64 images before 8.9 BIOS-only":
when:
# Keep the RHEL EC2 x86_64 images before 8.9 BIOS-only for backward compatibility.
# RHEL-internal EC2 images and RHEL AMI images are kept intentionally in sync
# with regard to not supporting hybrid boot mode before RHEL version 8.9.
# The partitioning table for these reflects that and is also intentionally in sync.
distro_name: "rhel"
version_less_than: "8.9"
override:
- *x86_64_bios_only_platform
- <<: *aarch64_platform
image_format: "raw"
package_sets:
os:
- *ec2_common_pkgset
@ -1176,6 +1302,11 @@ image_types:
ec2: &ec2
<<: *ami
filename: "image.raw.xz"
mime_type: "application/xz"
compression: "xz"
payload_pipelines: ["os", "image", "xz"]
exports: ["xz"]
image_config:
<<: *ec2_image_config
package_sets:
@ -1195,6 +1326,19 @@ image_types:
"ec2-ha":
<<: *ec2
platforms:
- <<: *x86_64_bios_platform
image_format: "raw"
platforms_override:
conditions:
# XXX: duplicated with "ami" but drops "aarch64", I cannot
# find a better way to express this complex condition in YAML
"Keep the RHEL EC2 x86_64 images before 8.9 BIOS-only":
when:
distro_name: "rhel"
version_less_than: "8.9"
override:
- *x86_64_bios_only_platform
package_sets:
os:
- *ec2_common_pkgset
@ -1210,6 +1354,19 @@ image_types:
"ec2-sap":
<<: *ec2
platforms:
- <<: *x86_64_bios_platform
image_format: "raw"
platforms_override:
conditions:
# XXX: duplicated with "ami" but drops "aarch64", I cannot
# find a better way to express this complex condition in YAML
"Keep the RHEL EC2 x86_64 images before 8.9 BIOS-only":
when:
distro_name: "rhel"
version_less_than: "8.9"
override:
- *x86_64_bios_only_platform
image_config:
<<: [*ec2_image_config, *sap_image_config]
conditions:
@ -1251,6 +1408,30 @@ image_types:
- "rh-amazon-rhui-client-sap-bundle"
qcow2: &qcow2
filename: "disk.qcow2"
mime_type: "application/x-qemu-disk"
# note that unlike fedora rhel does not use the environment.KVM
# for unknown reasons
bootable: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "qcow2"]
exports: ["qcow2"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
qcow2_compat: "0.10"
- <<: *aarch64_platform
image_format: "qcow2"
qcow2_compat: "0.10"
- <<: *ppc64le_bios_platform
image_format: "qcow2"
qcow2_compat: "0.10"
- <<: *s390x_zipl_platform
image_format: "qcow2"
qcow2_compat: "0.10"
image_config:
default_target: "multi-user.target"
kernel_options:
@ -1278,6 +1459,21 @@ image_types:
- *qcow2_common_pkgset
vhd:
filename: "disk.vhd"
mime_type: "application/x-vhd"
image_func: "disk"
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "vpc"]
exports: ["vpc"]
bootable: true
# note that unlike fedora no "environment.Azure" is used here for
# unknown reasons
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
- <<: *aarch64_platform
image_format: "vhd"
# yamllint disable rule:line-length
# based on https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/deploying_rhel_8_on_microsoft_azure/assembly_deploying-a-rhel-image-as-a-virtual-machine-on-microsoft-azure_cloud-content-azure#making-configuration-changes_configure-the-image-azure
# yamllint enable rule:line-length
@ -1424,6 +1620,20 @@ image_types:
- "alsa-lib"
"azure-rhui": &azure_rhui
filename: "disk.vhd.xz"
mime_type: "application/xz"
image_func: "disk"
default_size: 68_719_476_736 # 64 * datasizes.GibiByte
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "vpc", "xz"]
exports: ["xz"]
compression: "xz"
bootable: true
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
- <<: *aarch64_platform
image_format: "vhd"
image_config: &azure_rhui_image_config
<<: *vhd_image_config
rhsm_config:
@ -1463,6 +1673,9 @@ image_types:
"azure-sap-rhui":
<<: *azure_rhui
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
image_config:
<<: [*azure_rhui_image_config, *sap_image_config]
conditions:
@ -1489,6 +1702,9 @@ image_types:
"azure-eap7-rhui":
<<: *azure_rhui
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
image_config:
<<: *azure_rhui_image_config
enabled_services:
@ -1556,13 +1772,42 @@ image_types:
- "python3-html5lib"
"image-installer":
filename: "installer.iso"
mime_type: "application/x-iso9660-image"
bootable: true
boot_iso: true
# XXX: merge with boot_iso above
use_syslinux: true
# NOTE: RHEL 8 only supports the older Anaconda configs
use_legacy_anaconda_config: true
image_func: "image_installer"
# We don't know the variant of the OS pipeline being installed
iso_label: "Unknown"
build_pipelines: ["build"]
payload_pipelines:
- "anaconda-tree"
- "efiboot-tree"
- "os"
- "bootiso-tree"
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
image_config:
iso_rootfs_type: "squashfs-ext4"
conditions:
"x86_64 uses syslinux":
when:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
installer_config:
# see commit c6bfb22f54, controls the kickstart location
iso_root_kickstart: true
additional_dracut_modules:
- "ifcfg"
platforms:
- *x86_64_installer_platform
- *aarch64_platform
package_sets:
<<: *bare_metal_pkgset
installer:
@ -1591,7 +1836,19 @@ image_types:
- "rng-tools"
"edge-commit": &edge_commit
name_aliases: ["rhel-edge-commit"]
filename: "commit.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "iot_commit"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "commit-archive"]
exports: ["commit-archive"]
platforms:
- *x86_64_bios_platform
- *aarch64_platform
image_config: &edge_commit_image_config
install_weak_deps: true
enabled_services: &enabled_services_edge
- "NetworkManager.service"
- "firewalld.service"
@ -1758,6 +2015,28 @@ image_types:
- "sos"
"edge-installer":
name_aliases: ["rhel-edge-installer"]
filename: "installer.iso"
mime_type: "application/x-iso9660-image"
rpm_ostree: true
boot_iso: true
# XXX: merge with boot_iso above
use_syslinux: true
# NOTE: RHEL 8 only supports the older Anaconda configs
use_legacy_anaconda_config: true
image_func: "iot_installer"
iso_label: "edge"
variant: "edge"
ostree:
name: "rhel-edge"
build_pipelines: ["build"]
payload_pipelines:
- "anaconda-tree"
- "efiboot-tree"
- "bootiso-tree"
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
image_config:
iso_rootfs_type: "squashfs-ext4"
conditions:
@ -1766,6 +2045,12 @@ image_types:
arch: "x86_64"
shallow_merge:
iso_boot_type: "syslinux"
installer_config:
additional_dracut_modules:
- "ifcfg"
platforms:
- *x86_64_uefi_platform
- *aarch64_platform
package_sets:
installer:
# TODO: non-arch-specific package set handling for installers
@ -1781,6 +2066,26 @@ image_types:
# XXX: only available for rhel-8.6+, this is not possible to limit right now
"edge-raw-image":
name_aliases: ["rhel-edge-raw-image"]
filename: "image.raw.xz"
compression: "xz"
mime_type: "application/xz"
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
rpm_ostree: true
bootable: true
image_func: "iot"
ostree:
name: "rhel-edge"
remote_name: "rhel-edge"
use_ostree_remotes: true
build_pipelines: ["build"]
payload_pipelines: ["ostree-deployment", "image", "xz"]
exports: ["xz"]
platforms:
- <<: *x86_64_installer_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
image_config:
keyboard:
keymap: "us"
@ -1789,10 +2094,52 @@ image_types:
kernel_options: ["modprobe.blacklist=vc4"]
partition_table:
<<: *edge_base_partition_tables
supported_partitioning_modes:
- "" # default partitioning mode is supported (in original go based code)
- "raw"
"edge-simplified-installer":
filename: "simplified-installer.iso"
mime_type: "application/x-iso9660-image"
rpm_ostree: true
bootable: true
boot_iso: true
# XXX: merge with boot_iso above
use_syslinux: true
# NOTE: RHEL 8 only supports the older Anaconda configs
use_legacy_anaconda_config: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
image_func: "iot_simplified_installer"
iso_label: "edge"
variant: "edge"
ostree:
name: "rhel-edge"
remote_name: "rhel-edge"
# XXX: find better name
use_ostree_remotes: true
build_pipelines: ["build"]
payload_pipelines:
- "ostree-deployment"
- "image"
- "xz"
- "coi-tree"
- "efiboot-tree"
- "bootiso-tree"
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
installer_config:
additional_dracut_modules:
- "prefixdevname"
- "prefixdevname-tools"
platforms:
- <<: *x86_64_uefi_platform
- <<: *aarch64_platform
partition_table:
<<: *edge_base_partition_tables
supported_partitioning_modes:
- "" # default partitioning mode is supported (in original go based code)
- "raw"
image_config:
enabled_services: *enabled_services_edge
keyboard:
@ -1862,6 +2209,18 @@ image_types:
<<: *edge_commit_aarch64_pkgset
"edge-container":
name_aliases: ["rhel-edge-container"]
filename: "container.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "iot_container"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "container-tree", "container"]
exports: ["container"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- *x86_64_bios_platform
- *aarch64_platform
image_config:
<<: *edge_commit_image_config
package_sets:
@ -1869,6 +2228,18 @@ image_types:
- *edge_commit_pkgset
vmdk: &vmdk
filename: "disk.vmdk"
mime_type: "application/x-vmdk"
bootable: true
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "vmdk"]
exports: ["vmdk"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "vmdk"
image_config:
kernel_options:
- "ro"
@ -1891,12 +2262,28 @@ image_types:
ova:
<<: *vmdk
filename: "image.ova"
mime_type: "application/ovf"
payload_pipelines: ["os", "image", "vmdk", "ovf", "archive"]
exports: ["archive"]
platforms:
- <<: *x86_64_bios_platform
image_format: "ova"
gce: &gce
filename: "image.tar.gz"
mime_type: "application/gzip"
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "archive"]
exports: ["archive"]
bootable: true
default_size: 21_474_836_480 # 20 * datasizes.GibiByte
# The configuration for non-RHUI images does not touch the RHSM configuration at all.
# https://issues.redhat.com/browse/COMPOSER-2157
image_config: &gce_image_config
timezone: "UTC"
kernel_options: ["net.ifnames=0", "biosdevname=0", "scsi_mod.use_blk_mq=Y", "crashkernel=auto", "console=ttyS0,38400n8d"]
time_synchronization:
servers:
- hostname: "metadata.google.internal"
@ -1959,7 +2346,6 @@ image_types:
config:
"InstanceSetup":
set_boto_config: false
kernel_options: ["net.ifnames=0", "biosdevname=0", "scsi_mod.use_blk_mq=Y", "crashkernel=auto", "console=ttyS0,38400n8d"]
conditions:
"rhel-8.4 needs special handling":
# NOTE(akoutsou): these are enabled in the package preset, but for
@ -1977,6 +2363,9 @@ image_types:
- "google-shutdown-scripts.service"
- "google-startup-scripts.service"
- "google-osconfig-agent.service"
platforms:
- <<: *x86_64_uefi_platform
image_format: "gce"
partition_table:
<<: *default_partition_tables
package_sets:
@ -2008,14 +2397,25 @@ image_types:
oci:
<<: *qcow2
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
qcow2_compat: "0.10"
openstack:
<<: *qcow2
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
image_config:
kernel_options:
- "ro"
- "net.ifnames=0"
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
- <<: *aarch64_platform
image_format: "qcow2"
partition_table:
<<: *default_partition_tables
package_sets:
os:
- include:
@ -2031,6 +2431,16 @@ image_types:
- "rng-tools"
wsl:
filename: "image.wsl"
mime_type: "application/x-tar"
image_func: "tar"
build_pipelines: ["build"]
payload_pipelines: ["os", "archive", "xz"]
exports: ["xz"]
compression: "xz"
platforms:
- arch: "x86_64"
- arch: "aarch64"
image_config:
no_selinux: true
wsl:
@ -2144,6 +2554,16 @@ image_types:
- "xz"
"minimal-raw":
filename: "disk.raw.xz"
mime_type: "application/xz"
compression: "xz"
bootable: true
default_size: 2_147_483_648 # 2 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "xz"]
exports: ["xz"]
required_partition_sizes: *default_required_dir_sizes
image_config:
enabled_services:
- "NetworkManager.service"
@ -2162,6 +2582,11 @@ image_types:
firstboot --reconfig
lang en_US.UTF-8
kernel_options: ["ro"]
platforms:
- <<: *x86_64_uefi_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
partition_table:
<<: *default_partition_tables
package_sets:

View file

@ -32,6 +32,108 @@
- "grub2-ppc64le"
- "grub2-ppc64le-modules"
disk_sizes:
default_required_partition_sizes: &default_required_dir_sizes
"/": 1_073_741_824 # 1 * datasizes.GiB
"/usr": 2_147_483_648 # 2 * datasizes.GiB
platforms:
x86_64_uefi_platform: &x86_64_uefi_platform
arch: "x86_64"
bootloader: "grub2"
uefi_vendor: "{{.DistroVendor}}"
qcow2_compat: "1.1"
packages: &x86_64_uefi_platform_packages
uefi:
- "dracut-config-generic"
- "efibootmgr"
- "grub2-efi-x64"
- "shim-x64"
x86_64_bios_platform: &x86_64_bios_platform
<<: *x86_64_uefi_platform
bios_platform: "i386-pc"
uefi_vendor: "{{.DistroVendor}}"
packages: &x86_64_bios_platform_packages
<<: *x86_64_uefi_platform_packages
bios:
- "dracut-config-generic"
- "grub2-pc"
build_packages:
bios:
- "grub2-pc"
x86_64_bios_only_platform: &x86_64_bios_only_platform
arch: "x86_64"
bios_platform: "i386-pc"
bootloader: "grub2"
image_format: "raw"
packages:
bios:
- "grub2-pc"
build_packages:
bios:
- "grub2-pc"
x86_64_installer_platform: &x86_64_installer_platform
<<: *x86_64_bios_platform
image_format: "raw"
packages:
<<: *x86_64_bios_platform_packages
firmware:
- "microcode_ctl" # ??
- "iwl1000-firmware"
- "iwl100-firmware"
- "iwl105-firmware"
- "iwl135-firmware"
- "iwl2000-firmware"
- "iwl2030-firmware"
- "iwl3160-firmware"
- "iwl5000-firmware"
- "iwl5150-firmware"
- "iwl6050-firmware"
aarch64_platform: &aarch64_platform
arch: "aarch64"
bootloader: "grub2"
uefi_vendor: "{{.DistroVendor}}"
image_format: "qcow2"
qcow2_compat: "1.1"
packages: &aarch64_uefi_platform_packages
uefi:
- "dracut-config-generic"
- "efibootmgr"
- "grub2-efi-aa64"
- "grub2-tools"
- "shim-aa64"
ppc64le_bios_platform: &ppc64le_bios_platform
arch: "ppc64le"
bootloader: "grub2"
bios_platform: "powerpc-ieee1275"
image_format: "qcow2"
qcow2_compat: "1.1"
packages:
bios:
- "dracut-config-generic"
- "powerpc-utils"
- "grub2-ppc64le"
- "grub2-ppc64le-modules"
build_packages:
bios:
- "grub2-ppc64le"
- "grub2-ppc64le-modules"
s390x_zipl_platform: &s390x_zipl_platform
arch: "s390x"
# XXX: merge zipl_support/bootloader
bootloader: "zipl"
zipl_support: true
image_format: "qcow2"
qcow2_compat: "1.1"
packages:
zipl:
- "dracut-config-generic"
- "s390utils-base"
- "s390utils-core"
build_packages:
zipl:
- "s390utils-base"
common_conditions:
conditions: &conditions_pkgsets_insights_client_on_rhel
"add insights client on rhel":
@ -267,6 +369,16 @@
include:
- "biosdevname"
wsl: &wsl_config
config:
boot_systemd: true
distribution_config: &wsl_distribution_config
shortcut:
enabled: true
icon: /usr/share/pixmaps/fedora-logo.ico
oobe: &wsl_distribution_oobe_config
default_uid: 1000
anaconda_boot_pkgset: &anaconda_boot_pkgset
conditions:
"x86 specific packages for the anaconda boot pkgset":
@ -771,10 +883,22 @@
shallow_merge:
gpgkey_files:
- "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
"x86_64 specific kernel commandline for rhel-9.6+":
"x86_64 specific kernel commandline for rhel-9.7+":
when:
arch: "x86_64"
version_greater_or_equal: "9.6"
version_greater_or_equal: "9.7"
shallow_merge:
kernel_options:
- "ro"
- "console=tty1"
- "console=ttyS0"
- "earlyprintk=ttyS0"
- "rootdelay=300"
- "nvme_core.io_timeout=240"
"x86_64 specific kernel commandline for rhel-9.6":
when:
arch: "x86_64"
version_equal: "9.6"
shallow_merge:
kernel_options:
- "ro"
@ -784,16 +908,25 @@
- "earlyprintk=ttyS0"
- "rootdelay=300"
- "nvme_core.io_timeout=240"
"aarch64 specific kernel options for rhel 9.6+":
"aarch64 specific kernel options for rhel 9.6":
when:
arch: "aarch64"
version_greater_or_equal: "9.6"
version_equal: "9.6"
shallow_merge:
kernel_options:
- "ro"
- "loglevel=3"
- "console=ttyAMA0"
- "nvme_core.io_timeout=240"
"aarch64 specific kernel options for rhel 9.7+":
when:
arch: "aarch64"
version_greater_or_equal: "9.7"
shallow_merge:
kernel_options:
- "ro"
- "console=ttyAMA0"
- "nvme_core.io_timeout=240"
"x86_64 specific kernel options rhel-9.5 or below":
when:
arch: "x86_64"
@ -921,8 +1054,6 @@
config:
"ResourceDisk.Format": false
"ResourceDisk.EnableSwap": false
"Provisioning.UseCloudInit": true
"Provisioning.Enabled": false
"x86_64 grub2 config terminal=serial":
when:
arch: "x86_64"
@ -938,6 +1069,16 @@
<<: *azure_common_grub2_config
terminal: ["console"]
default_installer_config: &default_installer_config
# see commit c6bfb22f54, controls the kickstart location
iso_root_kickstart: true
additional_dracut_modules:
- "nvdimm" # non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)
- "ifcfg"
additional_drivers:
- "cuse"
- "ipmi_devintf"
- "ipmi_msghandler"
image_config:
default:
@ -945,6 +1086,7 @@ image_config:
default_oscap_datastream: "/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml"
install_weak_deps: true
locale: "C.UTF-8"
permissive_rhc: true
sysconfig:
networking: true
no_zero_conf: true
@ -1013,7 +1155,27 @@ image_types:
- "subscription-manager-cockpit"
qcow2: &qcow2
image_config:
filename: "disk.qcow2"
mime_type: "application/x-qemu-disk"
# note that unlike fedora rhel does not use the environment.KVM
# for unknown reasons
bootable: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "qcow2"]
exports: ["qcow2"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
- <<: *aarch64_platform
image_format: "qcow2"
- <<: *ppc64le_bios_platform
image_format: "qcow2"
- <<: *s390x_zipl_platform
image_format: "qcow2"
image_config: &qcow2_image_config
default_target: "multi-user.target"
kernel_options:
- "console=tty0"
@ -1103,10 +1265,64 @@ image_types:
- "insights-client"
- "subscription-manager-cockpit"
"vagrant-libvirt": &vagrant_libvirt
<<: *qcow2
filename: "vagrant-libvirt.box"
mime_type: "application/x-tar"
bootable: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "vagrant", "archive"]
exports: ["archive"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "vagrant_libvirt"
- <<: *aarch64_platform
image_format: "vagrant_libvirt"
image_config:
<<: *qcow2_image_config
users:
- name: "vagrant"
# yamllint disable rule:line-length
key: |
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN1YdxBpNlzxDqfJyw/QKow1F+wvG9hXGoqiysfJOn5Y vagrant insecure public key
# yamllint enable rule:line-length
files:
- path: "/etc/sudoers.d/vagrant"
user: "root"
group: "root"
mode: 440
data: |
vagrant ALL=(ALL) NOPASSWD: ALL
"vagrant-virtualbox":
<<: *vagrant_libvirt
filename: "vagrant-virtualbox.box"
platforms:
- <<: *x86_64_bios_platform
image_format: "vagrant_virtualbox"
oci:
<<: *qcow2
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
vhd: &vhd
<<: *qcow2
filename: "disk.vhd"
mime_type: "application/x-vhd"
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
payload_pipelines: ["os", "image", "vpc"]
exports: ["vpc"]
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
- <<: *aarch64_platform
image_format: "vhd"
# based on https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/deploying_rhel_9_on_microsoft_azure/assembly_deploying-a-rhel-image-as-a-virtual-machine-on-microsoft-azure_cloud-content-azure#making-configuration-changes_configure-the-image-azure
image_config: &image_config_vhd
<<: *azure_image_config_base
@ -1225,8 +1441,13 @@ image_types:
exclude:
- "microcode_ctl"
"azure-rhui": &azure_rhui
"azure": &azure
<<: *vhd
mime_type: "application/xz"
payload_pipelines: ["os", "image", "vpc", "xz"]
exports: ["xz"]
compression: "xz"
filename: "disk.vhd.xz"
partition_table: &partition_table_azure_internal
x86_64: &azure_rhui_partition_table_x86_64
uuid: "D209C89E-EA5E-4FBD-B161-B461CCE297E0"
@ -1376,8 +1597,14 @@ image_types:
- *azure_rhui_part_boot_600
- *azure_rhui_part_lvm
"azure-rhui": &azure_rhui
<<: *azure
"azure-sap-rhui":
<<: *azure_rhui
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
image_config:
<<: [*image_config_vhd, *sap_image_config]
package_sets:
@ -1388,6 +1615,9 @@ image_types:
azure-sapapps-rhui:
<<: *azure_rhui
platforms:
- <<: *x86_64_bios_platform
image_format: "vhd"
image_config:
<<: [*image_config_vhd, *sapapps_image_config]
package_sets:
@ -1396,6 +1626,17 @@ image_types:
- *sap_base_pkgset
tar:
filename: "root.tar.xz"
mime_type: "application/x-tar"
image_func: "tar"
build_pipelines: ["build"]
payload_pipelines: ["os", "archive"]
exports: ["archive"]
platforms:
- arch: "x86_64"
- arch: "aarch64"
- arch: "ppc64le"
- arch: "s390x"
package_sets:
os:
- include:
@ -1405,6 +1646,18 @@ image_types:
- "rng-tools"
vmdk: &vmdk
filename: "disk.vmdk"
mime_type: "application/x-vmdk"
bootable: true
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "vmdk"]
exports: ["vmdk"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "vmdk"
image_config:
locale: "en_US.UTF-8"
kernel_options: ["ro", "net.ifnames=0"]
@ -1424,9 +1677,42 @@ image_types:
- "dracut-config-rescue"
- "rng-tools"
ova: *vmdk
ova:
<<: *vmdk
filename: "image.ova"
mime_type: "application/ovf"
payload_pipelines: ["os", "image", "vmdk", "ovf", "archive"]
exports: ["archive"]
platforms:
- <<: *x86_64_bios_platform
image_format: "ova"
ec2: &ec2
filename: "image.raw.xz"
mime_type: "application/xz"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "xz"]
exports: ["xz"]
compression: "xz"
image_func: "disk"
bootable: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_bios_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
platforms_override:
conditions:
"Keep the RHEL EC2 x86_64 images before 9.3 BIOS-only":
when:
distro_name: "rhel"
version_less_than: "9.3"
override:
- *x86_64_bios_only_platform
- <<: *aarch64_platform
image_format: "raw"
image_config: &ec2_image_config
locale: "en_US.UTF-8"
timezone: "UTC"
@ -1550,9 +1836,27 @@ image_types:
ami:
<<: *ec2
mime_type: "application/octet-stream"
filename: "image.raw"
payload_pipelines: ["os", "image"]
exports: ["image"]
compression: ""
"ec2-ha":
<<: *ec2
platforms:
- <<: *x86_64_bios_platform
image_format: "raw"
platforms_override:
conditions:
# XXX: duplicated with "ec2" but drops "aarch64", I cannot
# find a better way to express this complex condition in YAML
"Keep the RHEL EC2 x86_64 images before 9.3 BIOS-only":
when:
distro_name: "rhel"
version_less_than: "9.3"
override:
- *x86_64_bios_only_platform
package_sets:
os:
- *ec2_base_pkgset
@ -1565,6 +1869,19 @@ image_types:
"ec2-sap":
<<: *ec2
platforms:
- <<: *x86_64_bios_platform
image_format: "raw"
platforms_override:
conditions:
# XXX: duplicated with "ec2" but drops "aarch64", I cannot
# find a better way to express this complex condition in YAML
"Keep the RHEL EC2 x86_64 images before 9.3 BIOS-only":
when:
distro_name: "rhel"
version_less_than: "9.3"
override:
- *x86_64_bios_only_platform
image_config:
<<: [*ec2_image_config, *sap_image_config]
conditions:
@ -1597,20 +1914,54 @@ image_types:
- "firewalld"
wsl: &wsl
filename: "image.wsl"
mime_type: "application/x-tar"
image_func: "tar"
build_pipelines: ["build"]
payload_pipelines: ["os", "archive"]
exports: ["xz"]
compression: "xz"
platforms:
- arch: "x86_64"
- arch: "aarch64"
image_config:
cloud_init:
- filename: "99_wsl.cfg"
config:
datasource_list:
- "WSL"
- "None"
network:
config: "disabled"
locale: "en_US.UTF-8"
no_selinux: true
wsl:
config:
boot_systemd: true
conditions:
"wsl config for rhel":
when:
distro_name: "rhel"
shallow_merge:
wsl:
<<: *wsl_config
distribution_config:
<<: *wsl_distribution_config
oobe:
<<: *wsl_distribution_oobe_config
default_name: RedHatEnterpriseLinux-%s
"wsl config for almalinux":
when:
distro_name: "almalinux"
shallow_merge:
wsl: &wsl_distribution_config_almalinux
<<: *wsl_config
distribution_config:
<<: *wsl_distribution_config
oobe:
<<: *wsl_distribution_oobe_config
default_name: AlmaLinux-%s
"cloud-init config for non-centos":
when:
not_distro_name: "centos"
shallow_merge:
cloud_init:
- filename: "99_wsl.cfg"
config:
datasource_list:
- "WSL"
- "None"
network:
config: "disabled"
package_sets:
os:
- include:
@ -1619,7 +1970,6 @@ image_types:
- "basesystem"
- "bash"
- "ca-certificates"
- "cloud-init"
- "coreutils-single"
- "crypto-policies-scripts"
- "curl-minimal"
@ -1644,13 +1994,11 @@ image_types:
- "procps-ng"
- "python3"
- "python3-inotify"
- "redhat-release"
- "rootfiles"
- "rpm"
- "sed"
- "setup"
- "shadow-utils"
- "subscription-manager"
- "sudo"
- "systemd"
- "tar"
@ -1667,8 +2015,49 @@ image_types:
- "python-unversioned-command"
- "redhat-release-eula"
- "rpm-plugin-systemd-inhibit"
conditions:
"subscription-manager, cloud-init, and redhat-* on rhel-likes except centos":
when:
not_distro_name: "centos"
append:
include:
- "subscription-manager"
- "cloud-init"
- "redhat-logos"
- "redhat-release"
"wsl-setup, and centos-* on centos":
when:
distro_name: "centos"
append:
include:
- "wsl-setup"
- "centos-logos"
- "centos-release"
"image-installer":
filename: "installer.iso"
mime_type: "application/x-iso9660-image"
bootable: true
boot_iso: true
# XXX: merge with boot_iso above
use_syslinux: true
image_func: "image_installer"
# We don't know the variant of the OS pipeline being installed
iso_label: "Unknown"
build_pipelines: ["build"]
payload_pipelines:
- "anaconda-tree"
- "efiboot-tree"
- "os"
- "bootiso-tree"
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- *x86_64_installer_platform
- *aarch64_platform
installer_config: *default_installer_config
image_config:
locale: "C.UTF-8"
conditions:
@ -1684,6 +2073,19 @@ image_types:
- *anaconda_pkgset
gce:
name_aliases: ["gce-rhui"]
filename: "image.tar.gz"
mime_type: "application/gzip"
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "archive"]
exports: ["archive"]
bootable: true
default_size: 21_474_836_480 # 20 * datasizes.GibiByte
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_uefi_platform
image_format: "gce"
image_config:
timezone: "UTC"
time_synchronization:
@ -1829,6 +2231,21 @@ image_types:
<<: *conditions_pkgsets_insights_client_on_rhel
"minimal-raw":
filename: "disk.raw.xz"
mime_type: "application/xz"
compression: "xz"
bootable: true
default_size: 2_147_483_648 # 2 * datasizes.GibiByte
image_func: "disk"
build_pipelines: ["build"]
payload_pipelines: ["os", "image", "xz"]
exports: ["xz"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- <<: *x86_64_uefi_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
partition_table:
x86_64: &partition_table_minimal_raw_x86_64
uuid: "D209C89E-EA5E-4FBD-B161-B461CCE297E0"
@ -1853,25 +2270,15 @@ image_types:
type: *xboot_ldr_partition_guid
uuid: *data_partition_uuid
payload_type: "filesystem"
payload: &default_partition_table_part_boot_payload
type: "xfs"
mountpoint: "/boot"
label: "boot"
fstab_options: "defaults"
fstab_freq: 0
fstab_passno: 0
payload:
<<: *default_partition_table_part_boot_payload
- &minimal_raw_partition_table_part_root
size: "2 GiB"
type: *filesystem_data_guid
uuid: *root_partition_uuid
payload_type: "filesystem"
payload: &default_partition_table_part_root_payload
type: "xfs"
label: "root"
mountpoint: "/"
fstab_options: "defaults"
fstab_freq: 0
fstab_passno: 0
payload:
<<: *default_partition_table_part_root_payload
aarch64: &partition_table_minimal_raw_aarch64
<<: *partition_table_minimal_raw_x86_64
partition_tables_override:
@ -1930,6 +2337,15 @@ image_types:
- "iwl3160-firmware"
openstack:
<<: *qcow2
default_size: 4_294_967_296 # 4 * datasizes.GibiByte
platforms:
- <<: *x86_64_bios_platform
image_format: "qcow2"
qcow2_compat: ""
- <<: *aarch64_platform
image_format: "qcow2"
qcow2_compat: ""
image_config:
locale: "en_US.UTF-8"
kernel_options: ["ro", "net.ifnames=0"]
@ -1950,6 +2366,17 @@ image_types:
- "rng-tools"
"edge-commit": &edge_commit
name_aliases: ["rhel-edge-commit"]
filename: "commit.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "iot_commit"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "commit-archive"]
exports: ["commit-archive"]
platforms:
- *x86_64_bios_platform
- *aarch64_platform
partition_table:
*edge_base_partition_tables
image_config: &edge_commit_image_config
@ -2112,9 +2539,37 @@ image_types:
- "dnsmasq"
"edge-container":
name_aliases: ["rhel-edge-container"]
filename: "container.tar"
mime_type: "application/x-tar"
rpm_ostree: true
image_func: "iot_container"
build_pipelines: ["build"]
payload_pipelines: ["os", "ostree-commit", "container-tree", "container"]
exports: ["container"]
<<: *edge_commit
"edge-raw-image":
name_aliases: ["rhel-edge-raw-image"]
filename: "image.raw.xz"
compression: "xz"
mime_type: "application/xz"
build_pipelines: ["build"]
payload_pipelines: ["ostree-deployment", "image", "xz"]
exports: ["xz"]
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
rpm_ostree: true
bootable: true
image_func: "iot"
ostree:
name: "rhel-edge"
remote_name: "rhel-edge"
use_ostree_remotes: true
platforms:
- <<: *x86_64_installer_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
partition_table:
*edge_base_partition_tables
image_config:
@ -2147,6 +2602,30 @@ image_types:
- "nginx"
"edge-installer":
name_aliases: ["rhel-edge-installer"]
filename: "installer.iso"
mime_type: "application/x-iso9660-image"
rpm_ostree: true
boot_iso: true
# XXX: merge with boot_iso above
use_syslinux: true
image_func: "iot_installer"
iso_label: "edge"
variant: "edge"
ostree:
name: "rhel-edge"
build_pipelines: ["build"]
payload_pipelines:
- "anaconda-tree"
- "efiboot-tree"
- "bootiso-tree"
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
platforms:
- *x86_64_uefi_platform
- *aarch64_platform
installer_config: *default_installer_config
image_config:
enabled_services: *enabled_services_edge
locale: "en_US.UTF-8"
@ -2162,6 +2641,43 @@ image_types:
- *anaconda_pkgset
"edge-simplified-installer":
name_aliases: ["rhel-edge-simplified-installer"]
filename: "simplified-installer.iso"
mime_type: "application/x-iso9660-image"
rpm_ostree: true
bootable: true
boot_iso: true
# XXX: merge with boot_iso above
use_syslinux: true
# NOTE: RHEL 8 only supports the older Anaconda configs
use_legacy_anaconda_config: true
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
image_func: "iot_simplified_installer"
iso_label: "edge"
variant: "edge"
ostree:
name: "rhel-edge"
remote_name: "rhel-edge"
# XXX: find better name
use_ostree_remotes: true
build_pipelines: ["build"]
payload_pipelines:
- "ostree-deployment"
- "image"
- "xz"
- "coi-tree"
- "efiboot-tree"
- "bootiso-tree"
- "bootiso"
exports: ["bootiso"]
required_partition_sizes: *default_required_dir_sizes
installer_config:
additional_dracut_modules:
- "prefixdevname"
- "prefixdevname-tools"
platforms:
- <<: *x86_64_uefi_platform
- <<: *aarch64_platform
partition_table:
*edge_base_partition_tables
image_config:
@ -2241,6 +2757,24 @@ image_types:
<<: *edge_commit_aarch64_pkgset
"edge-ami": &edge_ami
filename: "image.raw"
mime_type: "application/octet-stream"
default_size: 10_737_418_240 # 10 * datasizes.GibiByte
build_pipelines: ["build"]
payload_pipelines: ["ostree-deployment", "image"]
exports: ["image"]
rpm_ostree: true
bootable: true
image_func: "iot"
ostree:
name: "rhel-edge"
remote_name: "rhel-edge"
use_ostree_remotes: true
platforms:
- <<: *x86_64_installer_platform
image_format: "raw"
- <<: *aarch64_platform
image_format: "raw"
partition_table:
*edge_base_partition_tables
image_config: &image_config_edge_ami
@ -2280,6 +2814,15 @@ image_types:
"edge-vsphere":
<<: *edge_ami
filename: "image.vmdk"
mime_type: "application/x-vmdk"
payload_pipelines: ["ostree-deployment", "image", "vmdk"]
exports: ["vmdk"]
platforms:
- <<: *x86_64_bios_platform
image_format: "vmdk"
- <<: *aarch64_platform
image_format: "vmdk"
image_config:
<<: *image_config_edge_ami
kernel_options:
@ -2297,6 +2840,24 @@ image_types:
- "modprobe.blacklist=vc4"
"azure-cvm":
<<: *vhd
filename: "disk.vhd.xz"
mime_type: "application/xz"
payload_pipelines: ["os", "image", "vpc", "xz"]
exports: ["xz"]
compression: "xz"
default_size: 34_359_738_368 # 32 * datasizes.GibiByte
platforms:
- arch: "x86_64"
bootloader: "uki"
image_format: "vhd"
uefi_vendor: "{{.DistroVendor}}"
packages:
uki:
- "efibootmgr"
- "kernel-uki-virt-addons" # provides useful cmdline utilities for the UKI
- "shim-x64"
- "uki-direct"
partition_table:
x86_64:
uuid: "D209C89E-EA5E-4FBD-B161-B461CCE297E0"
@ -2326,6 +2887,7 @@ image_types:
fstab_passno: 0
image_config:
<<: *azure_image_config_base
default_kernel: "kernel-uki-virt"
default_kernel_name: "kernel-uki-virt"
no_bls: true
cloud_init:

View file

@ -40,12 +40,6 @@ type distribution struct {
defs.DistroYAML
arches map[string]*architecture
// XXX: move into defs.DistroYAML? the downside of doing this
// is that we would have to duplicate the default image config
// accross the centos/alma/rhel distros.yaml, otherwise we
// just load it from the imagetypes file/dir and it is natually
// "in-sync"
defaultImageConfig *distro.ImageConfig
}
func (d *distribution) getISOLabelFunc(isoLabel string) isoLabelFunc {
@ -85,9 +79,7 @@ func newDistro(nameVer string) (distro.Distro, error) {
rd := &distribution{
DistroYAML: *distroYAML,
defaultImageConfig: distroYAML.ImageConfig(),
arches: make(map[string]*architecture),
arches: make(map[string]*architecture),
}
for _, imgTypeYAML := range distroYAML.ImageTypes() {
@ -96,7 +88,11 @@ func newDistro(nameVer string) (distro.Distro, error) {
if imgTypeYAML.Filename == "" {
continue
}
for _, pl := range imgTypeYAML.Platforms {
platforms, err := imgTypeYAML.PlatformsFor(nameVer)
if err != nil {
return nil, err
}
for _, pl := range platforms {
ar, ok := rd.arches[pl.Arch.String()]
if !ok {
ar = newArchitecture(rd, pl.Arch.String())

View file

@ -1,47 +0,0 @@
package generic
import (
"fmt"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/distro/defs"
)
func newImageTypeFrom(d *distribution, ar *architecture, imgYAML defs.ImageTypeYAML) imageType {
it := imageType{
ImageTypeYAML: imgYAML,
isoLabel: d.getISOLabelFunc(imgYAML.ISOLabel),
}
it.defaultImageConfig = common.Must(it.ImageConfig(d.Name(), ar.name))
it.defaultInstallerConfig = common.Must(it.InstallerConfig(d.Name(), ar.name))
switch imgYAML.Image {
case "disk":
it.image = diskImage
case "container":
it.image = containerImage
case "image_installer":
it.image = imageInstallerImage
case "live_installer":
it.image = liveInstallerImage
case "bootable_container":
it.image = bootableContainerImage
case "iot":
it.image = iotImage
case "iot_commit":
it.image = iotCommitImage
case "iot_container":
it.image = iotContainerImage
case "iot_installer":
it.image = iotInstallerImage
case "iot_simplified_installer":
it.image = iotSimplifiedInstallerImage
case "tar":
it.image = tarImage
default:
err := fmt.Errorf("unknown image func: %v for %v", imgYAML.Image, imgYAML.Name())
panic(err)
}
return it
}

View file

@ -42,11 +42,8 @@ func osCustomizations(t *imageType, osPackageSet rpmmd.PackageSet, options distr
osc.KernelName = *imageConfig.DefaultKernelName
}
var kernelOptions []string
// XXX: keep in sync with the identical copy in rhel/images.go
if t.defaultImageConfig != nil && len(t.defaultImageConfig.KernelOptions) > 0 {
kernelOptions = append(kernelOptions, t.defaultImageConfig.KernelOptions...)
}
kernelOptions := imageConfig.KernelOptions
if bpKernel := c.GetKernel(); bpKernel.Append != "" {
kernelOptions = append(kernelOptions, bpKernel.Append)
}
@ -246,6 +243,7 @@ func osCustomizations(t *imageType, osPackageSet rpmmd.PackageSet, options distr
if options.Subscription.Proxy != "" {
osc.InsightsClientConfig = &osbuild.InsightsClientConfigStageOptions{Config: osbuild.InsightsClientConfig{Proxy: options.Subscription.Proxy}}
}
osc.PermissiveRHC = imageConfig.PermissiveRHC
} else {
subscriptionStatus = subscription.RHSMConfigNoSubscription
}
@ -332,10 +330,7 @@ func ostreeDeploymentCustomizations(
imageConfig := t.getDefaultImageConfig()
deploymentConf := manifest.OSTreeDeploymentCustomizations{}
var kernelOptions []string
if len(t.defaultImageConfig.KernelOptions) > 0 {
kernelOptions = append(kernelOptions, t.defaultImageConfig.KernelOptions...)
}
kernelOptions := imageConfig.KernelOptions
if bpKernel := c.GetKernel(); bpKernel != nil && bpKernel.Append != "" {
kernelOptions = append(kernelOptions, bpKernel.Append)
}
@ -571,6 +566,8 @@ func imageInstallerImage(workload workload.Workload,
return nil, err
}
img.UseLegacyAnacondaConfig = t.ImageTypeYAML.UseLegacyAnacondaConfig
img.Kickstart, err = kickstart.New(customizations)
if err != nil {
return nil, err
@ -666,9 +663,13 @@ func iotCommitImage(workload workload.Workload,
if err != nil {
return nil, err
}
imgConfig := t.getDefaultImageConfig()
if imgConfig != nil {
img.OSCustomizations.Presets = imgConfig.Presets
if imgConfig.InstallWeakDeps != nil {
img.InstallWeakDeps = *imgConfig.InstallWeakDeps
}
}
img.Environment = &t.ImageTypeYAML.Environment
@ -676,7 +677,6 @@ func iotCommitImage(workload workload.Workload,
img.OSTreeParent = parentCommit
img.OSVersion = d.OsVersion()
img.Filename = t.Filename()
img.InstallWeakDeps = false
return img, nil
}
@ -743,6 +743,9 @@ func iotContainerImage(workload workload.Workload,
imgConfig := t.getDefaultImageConfig()
if imgConfig != nil {
img.OSCustomizations.Presets = imgConfig.Presets
if imgConfig.InstallWeakDeps != nil {
img.OSCustomizations.InstallWeakDeps = *imgConfig.InstallWeakDeps
}
}
img.ContainerLanguage = img.OSCustomizations.Language
@ -777,6 +780,7 @@ func iotInstallerImage(workload workload.Workload,
img.FIPS = customizations.GetFIPS()
img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey]
img.UseLegacyAnacondaConfig = t.ImageTypeYAML.UseLegacyAnacondaConfig
img.Kickstart, err = kickstart.New(customizations)
if err != nil {
@ -784,7 +788,7 @@ func iotInstallerImage(workload workload.Workload,
}
img.Kickstart.OSTree = &kickstart.OSTree{
OSName: t.OSTree.Name,
Remote: t.OSTree.Remote,
Remote: t.OSTree.RemoteName,
}
img.Kickstart.Path = osbuild.KickstartPathOSBuild
img.Kickstart.Language, img.Kickstart.Keyboard = customizations.GetPrimaryLocale()
@ -814,12 +818,13 @@ func iotInstallerImage(workload workload.Workload,
img.RootfsType = manifest.SquashfsRootfs
}
}
// On Fedora anaconda needs dbus-broker, but isn't added when dracut runs.
img.AdditionalDracutModules = append(img.AdditionalDracutModules, "dbus-broker")
if len(img.Kickstart.Users)+len(img.Kickstart.Groups) > 0 {
// only enable the users module if needed
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, anaconda.ModuleUsers)
}
img.Product = d.Product()
img.Variant = "IoT"
img.Variant = t.ImageTypeYAML.Variant
img.OSVersion = d.OsVersion()
img.Release = fmt.Sprintf("%s %s", d.Product(), d.OsVersion())
img.Preview = d.DistroYAML.Preview
@ -870,9 +875,15 @@ func iotImage(workload workload.Workload,
img.Workload = workload
img.Remote = ostree.Remote{
Name: t.OSTree.Remote,
Name: t.ImageTypeYAML.OSTree.RemoteName,
}
img.OSName = t.OSTree.Remote
// XXX: can we do better?
if t.ImageTypeYAML.UseOstreeRemotes {
img.Remote.URL = options.OSTree.URL
img.Remote.ContentURL = options.OSTree.ContentURL
}
img.OSName = t.ImageTypeYAML.OSTree.Name
// TODO: move generation into LiveImage
pt, err := t.getPartitionTable(customizations, options, rng)
@ -911,7 +922,11 @@ func iotSimplifiedInstallerImage(workload workload.Workload,
rawImg.Platform = t.platform
rawImg.Workload = workload
rawImg.Remote = ostree.Remote{
Name: t.OSTree.Remote,
Name: t.OSTree.RemoteName,
}
if t.ImageTypeYAML.UseOstreeRemotes {
rawImg.Remote.URL = options.OSTree.URL
rawImg.Remote.ContentURL = options.OSTree.ContentURL
}
rawImg.OSName = t.OSTree.Name
@ -953,11 +968,9 @@ func iotSimplifiedInstallerImage(workload workload.Workload,
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
}
img.AdditionalDracutModules = append(img.AdditionalDracutModules, "dbus-broker")
d := t.arch.distro
img.Product = d.Product()
img.Variant = "IoT"
img.Variant = t.ImageTypeYAML.Variant
img.OSName = t.OSTree.Name
img.OSVersion = d.OsVersion()

View file

@ -4,8 +4,6 @@ import (
"errors"
"fmt"
"math/rand"
"strings"
"slices"
"github.com/osbuild/images/internal/common"
@ -13,7 +11,6 @@ import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro"
@ -22,7 +19,6 @@ import (
"github.com/osbuild/images/pkg/image"
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/platform"
"github.com/osbuild/images/pkg/policies"
"github.com/osbuild/images/pkg/rpmmd"
)
@ -39,15 +35,47 @@ type imageType struct {
arch *architecture
platform platform.Platform
// XXX: make definable via YAML
workload workload.Workload
defaultImageConfig *distro.ImageConfig
defaultInstallerConfig *distro.InstallerConfig
image imageFunc
isoLabel isoLabelFunc
}
func newImageTypeFrom(d *distribution, ar *architecture, imgYAML defs.ImageTypeYAML) imageType {
it := imageType{
ImageTypeYAML: imgYAML,
isoLabel: d.getISOLabelFunc(imgYAML.ISOLabel),
}
switch imgYAML.Image {
case "disk":
it.image = diskImage
case "container":
it.image = containerImage
case "image_installer":
it.image = imageInstallerImage
case "live_installer":
it.image = liveInstallerImage
case "bootable_container":
it.image = bootableContainerImage
case "iot":
it.image = iotImage
case "iot_commit":
it.image = iotCommitImage
case "iot_container":
it.image = iotContainerImage
case "iot_installer":
it.image = iotInstallerImage
case "iot_simplified_installer":
it.image = iotSimplifiedInstallerImage
case "tar":
it.image = tarImage
default:
err := fmt.Errorf("unknown image func: %v for %v", imgYAML.Image, imgYAML.Name())
panic(err)
}
return it
}
func (t *imageType) Name() string {
return t.ImageTypeYAML.Name()
}
@ -76,12 +104,11 @@ func (t *imageType) ISOLabel() (string, error) {
if !t.ImageTypeYAML.BootISO {
return "", fmt.Errorf("image type %q is not an ISO", t.Name())
}
if t.isoLabel != nil {
return t.isoLabel(t), nil
if t.isoLabel == nil {
return "", fmt.Errorf("no iso label function for %q", t.Name())
}
return "", nil
return t.isoLabel(t), nil
}
func (t *imageType) Size(size uint64) uint64 {
@ -164,12 +191,8 @@ func (t *imageType) getPartitionTable(customizations *blueprint.Customizations,
}
func (t *imageType) getDefaultImageConfig() *distro.ImageConfig {
// ensure that image always returns non-nil default config
imageConfig := t.defaultImageConfig
if imageConfig == nil {
imageConfig = &distro.ImageConfig{}
}
return imageConfig.InheritFrom(t.arch.distro.defaultImageConfig)
imageConfig := common.Must(t.ImageConfig(t.arch.distro.Name(), t.arch.name))
return imageConfig.InheritFrom(t.arch.distro.ImageConfig())
}
@ -177,8 +200,7 @@ func (t *imageType) getDefaultInstallerConfig() (*distro.InstallerConfig, error)
if !t.ImageTypeYAML.BootISO {
return nil, fmt.Errorf("image type %q is not an ISO", t.Name())
}
return t.defaultInstallerConfig, nil
return t.InstallerConfig(t.arch.distro.Name(), t.arch.name)
}
func (t *imageType) PartitionType() disk.PartitionTableType {
@ -235,41 +257,31 @@ func (t *imageType) Manifest(bp *blueprint.Blueprint,
}
}
w := t.workload
if w == nil {
// XXX: this needs to get duplicaed in exactly the same
// way in rhel/imagetype.go
workloadRepos := payloadRepos
customRepos, err := bp.Customizations.GetRepositories()
if err != nil {
return nil, nil, err
}
installFromRepos := blueprint.RepoCustomizationsInstallFromOnly(customRepos)
workloadRepos = append(workloadRepos, installFromRepos...)
customRepos, err := bp.Customizations.GetRepositories()
if err != nil {
return nil, nil, err
}
installFromRepos := blueprint.RepoCustomizationsInstallFromOnly(customRepos)
payloadRepos = append(payloadRepos, installFromRepos...)
cw := &workload.Custom{
BaseWorkload: workload.BaseWorkload{
Repos: workloadRepos,
},
Packages: bp.GetPackagesEx(false),
EnabledModules: bp.GetEnabledModules(),
}
if services := bp.Customizations.GetServices(); services != nil {
cw.Services = services.Enabled
cw.DisabledServices = services.Disabled
cw.MaskedServices = services.Masked
}
w = cw
cw := &workload.Custom{
BaseWorkload: workload.BaseWorkload{
Repos: payloadRepos,
},
Packages: bp.GetPackagesEx(false),
EnabledModules: bp.GetEnabledModules(),
}
if services := bp.Customizations.GetServices(); services != nil {
cw.Services = services.Enabled
cw.DisabledServices = services.Disabled
cw.MaskedServices = services.Masked
}
if experimentalflags.Bool("no-fstab") {
if t.defaultImageConfig == nil {
t.defaultImageConfig = &distro.ImageConfig{
MountUnits: common.ToPtr(true),
}
} else {
t.defaultImageConfig.MountUnits = common.ToPtr(true)
if t.ImageConfigYAML.ImageConfig != nil {
t.ImageConfigYAML.ImageConfig = &distro.ImageConfig{}
}
t.ImageConfigYAML.ImageConfig.MountUnits = common.ToPtr(true)
}
containerSources := make([]container.SourceSpec, len(bp.Containers))
@ -287,7 +299,7 @@ func (t *imageType) Manifest(bp *blueprint.Blueprint,
/* #nosec G404 */
rng := rand.New(source)
img, err := t.image(w, t, bp, options, staticPackageSets, containerSources, rng)
img, err := t.image(cw, t, bp, options, staticPackageSets, containerSources, rng)
if err != nil {
return nil, nil, err
}
@ -313,198 +325,25 @@ func (t *imageType) Manifest(bp *blueprint.Blueprint,
// checkOptions checks the validity and compatibility of options and customizations for the image type.
// Returns ([]string, error) where []string, if non-nil, will hold any generated warnings (e.g. deprecation notices).
func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
var warnings []string
if !t.ImageTypeYAML.RPMOSTree && options.OSTree != nil {
return warnings, fmt.Errorf("OSTree is not supported for %q", t.Name())
}
if len(t.ImageTypeYAML.SupportedPartitioningModes) > 0 && !slices.Contains(t.ImageTypeYAML.SupportedPartitioningModes, options.PartitioningMode) {
return warnings, fmt.Errorf("partitioning mode %s not supported for %q on %q", options.PartitioningMode, t.Name(), t.arch.distro.Name())
}
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.ImageTypeYAML.RPMOSTree && (t.Name() != "iot-commit" && t.Name() != "iot-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.arch.distro.Name())
}
if options.OSTree != nil {
if err := options.OSTree.Validate(); err != nil {
return warnings, err
}
}
if t.ImageTypeYAML.BootISO && t.ImageTypeYAML.RPMOSTree {
// ostree-based ISOs require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.Name())
}
}
if t.Name() == "iot-raw-xz" || t.Name() == "iot-qcow2" {
allowed := []string{"User", "Group", "Directories", "Files", "Services", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
// TODO: consider additional checks, such as those in "edge-simplified-installer" in RHEL distros
}
// BootISOs have limited support for customizations.
// TODO: Support kernel name selection for image-installer
if t.ImageTypeYAML.BootISO {
if t.Name() == "iot-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO", "Ignition", "Kernel", "User", "Group", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.Name())
}
// FDO is optional, but when specified has some restrictions
if customizations.GetFDO() != nil {
if customizations.GetFDO().ManufacturingServerURL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to when using FDO", t.Name())
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to when using FDO", t.Name())
}
}
// ignition is optional, we might be using FDO
if customizations.GetIgnition() != nil {
if customizations.GetIgnition().Embedded != nil && customizations.GetIgnition().FirstBoot != nil {
return warnings, fmt.Errorf("both ignition embedded and firstboot configurations found")
}
if customizations.GetIgnition().FirstBoot != nil && customizations.GetIgnition().FirstBoot.ProvisioningURL == "" {
return warnings, fmt.Errorf("ignition.firstboot requires a provisioning url")
}
}
} else if t.Name() == "iot-installer" || t.Name() == "minimal-installer" {
// "Installer" is actually not allowed for image-installer right now, but this is checked at the end
allowed := []string{"User", "Group", "FIPS", "Installer", "Timezone", "Locale"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
} else if t.Name() == "workstation-live-installer" {
allowed := []string{"Installer"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.NoCustomizationsAllowedError, t.Name())
}
}
}
if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.ImageTypeYAML.RPMOSTree {
return warnings, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return warnings, err
}
if (len(mountpoints) > 0 || partitioning != nil) && t.ImageTypeYAML.RPMOSTree {
return warnings, fmt.Errorf("Custom mountpoints and partitioning are not supported for ostree types")
}
if len(mountpoints) > 0 && partitioning != nil {
return warnings, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)")
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return nil, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
supported := oscap.IsProfileAllowed(osc.ProfileID, t.arch.distro.DistroYAML.OscapProfilesAllowList)
if !supported {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if t.ImageTypeYAML.RPMOSTree {
return warnings, fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
if warnings, err := checkOptionsCommon(t, bp, options); err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.ImageTypeYAML.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
switch idLike := t.arch.distro.DistroYAML.DistroLike; idLike {
case manifest.DISTRO_FEDORA:
return checkOptionsFedora(t, bp, options)
case manifest.DISTRO_EL7:
return checkOptionsRhel7(t, bp, options)
case manifest.DISTRO_EL8:
return checkOptionsRhel8(t, bp, options)
case manifest.DISTRO_EL9:
return checkOptionsRhel9(t, bp, options)
case manifest.DISTRO_EL10:
return checkOptionsRhel10(t, bp, options)
default:
return nil, fmt.Errorf("checkOptions called with unknown distro-like %v", idLike)
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
warnings = append(warnings, fmt.Sprintln(common.FIPSEnabledImageWarning))
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if !slices.Contains([]string{"image-installer", "edge-installer", "live-installer", "iot-installer"}, t.Name()) {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
// NOTE: the image type check is redundant with the check above, but
// let's keep it explicit in case one of the two changes.
// The kickstart contents is incompatible with the users and groups
// customization only for the iot-installer.
if t.Name() == "iot-installer" &&
instCust.Kickstart != nil &&
len(instCust.Kickstart.Contents) > 0 &&
(customizations.GetUsers() != nil || customizations.GetGroups() != nil) {
return warnings, fmt.Errorf("iot-installer installer.kickstart.contents are not supported in combination with users or groups")
}
}
return warnings, nil
}
func bootstrapContainerFor(t *imageType) string {

View file

@ -0,0 +1,713 @@
package generic
import (
"fmt"
"slices"
"strings"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/policies"
)
func checkOptionsCommon(t *imageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
if !t.RPMOSTree && options.OSTree != nil {
return nil, fmt.Errorf("OSTree is not supported for %q", t.Name())
}
if len(t.ImageTypeYAML.SupportedPartitioningModes) > 0 && !slices.Contains(t.ImageTypeYAML.SupportedPartitioningModes, options.PartitioningMode) {
return nil, fmt.Errorf("partitioning mode %s not supported for %q", options.PartitioningMode, t.Name())
}
return nil, nil
}
func checkOptionsRhel10(t *imageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
// holds warnings (e.g. deprecation notices)
var warnings []string
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if len(mountpoints) > 0 && partitioning != nil {
return nil, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)")
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
if !oscap.IsProfileAllowed(osc.ProfileID, t.arch.distro.DistroYAML.OscapProfilesAllowList) {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
warnings = append(warnings, fmt.Sprintln(common.FIPSEnabledImageWarning))
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if slices.Index([]string{"image-installer", "edge-installer", "live-installer"}, t.Name()) == -1 {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
}
return warnings, nil
}
func checkOptionsRhel9(t *imageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
// holds warnings (e.g. deprecation notices)
var warnings []string
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.RPMOSTree && (t.Name() != "edge-commit" && t.Name() != "edge-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.Arch().Distro().Name())
}
if options.OSTree != nil {
if err := options.OSTree.Validate(); err != nil {
return warnings, err
}
}
if t.BootISO && t.RPMOSTree {
// ostree-based ISOs require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.Name())
}
if t.Name() == "edge-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO", "Ignition", "Kernel", "User", "Group", "FIPS", "Filesystem"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.Name())
}
// FDO is optional, but when specified has some restrictions
if customizations.GetFDO() != nil {
if customizations.GetFDO().ManufacturingServerURL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to when using FDO", t.Name())
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to when using FDO", t.Name())
}
}
// ignition is optional, we might be using FDO
if customizations.GetIgnition() != nil {
if customizations.GetIgnition().Embedded != nil && customizations.GetIgnition().FirstBoot != nil {
return warnings, fmt.Errorf("both ignition embedded and firstboot configurations found")
}
if customizations.GetIgnition().FirstBoot != nil && customizations.GetIgnition().FirstBoot.ProvisioningURL == "" {
return warnings, fmt.Errorf("ignition.firstboot requires a provisioning url")
}
}
} else if t.Name() == "edge-installer" {
allowed := []string{"User", "Group", "FIPS", "Installer", "Timezone", "Locale"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
}
}
if t.Name() == "edge-raw-image" || t.Name() == "edge-ami" || t.Name() == "edge-vsphere" {
// ostree-based bootable images require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("%q images require specifying a URL from which to retrieve the OSTree commit", t.Name())
}
allowed := []string{"Ignition", "Kernel", "User", "Group", "FIPS", "Filesystem"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
// TODO: consider additional checks, such as those in "edge-simplified-installer"
}
if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.RPMOSTree && t.Name() != "edge-raw-image" && t.Name() != "edge-simplified-installer" {
return warnings, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if (mountpoints != nil || partitioning != nil) && t.RPMOSTree && (t.Name() == "edge-container" || t.Name() == "edge-commit") {
return warnings, fmt.Errorf("custom mountpoints and partitioning are not supported for ostree types")
} else if (mountpoints != nil || partitioning != nil) && t.RPMOSTree && !(t.Name() == "edge-container" || t.Name() == "edge-commit") {
//customization allowed for edge-raw-image,edge-ami,edge-vsphere,edge-simplified-installer
err := blueprint.CheckMountpointsPolicy(mountpoints, policies.OstreeMountpointPolicies)
if err != nil {
return warnings, err
}
}
if len(mountpoints) > 0 && partitioning != nil {
return nil, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)")
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
if t.Arch().Distro().OsVersion() == "9.0" {
return warnings, fmt.Errorf("OpenSCAP unsupported os version: %s", t.Arch().Distro().OsVersion())
}
if !oscap.IsProfileAllowed(osc.ProfileID, t.arch.distro.DistroYAML.OscapProfilesAllowList) {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if t.RPMOSTree {
return warnings, fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
warnings = append(warnings, fmt.Sprintln(common.FIPSEnabledImageWarning))
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if slices.Index([]string{"image-installer", "edge-installer", "live-installer"}, t.Name()) == -1 {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
if t.Name() == "edge-installer" &&
instCust.Kickstart != nil &&
len(instCust.Kickstart.Contents) > 0 &&
(customizations.GetUsers() != nil || customizations.GetGroups() != nil) {
return warnings, fmt.Errorf("edge-installer installer.kickstart.contents are not supported in combination with users or groups")
}
}
// don't support setting any kernel customizations for image types with
// UKIs
// NOTE: this is very ugly and stupid, it should not be based on the image
// type name, but we want to redo this whole function anyway
// NOTE: we can't use customizations.GetKernel() because it returns
// 'Name: "kernel"' when unset.
if t.Name() == "azure-cvm" && customizations != nil && customizations.Kernel != nil {
return warnings, fmt.Errorf("kernel customizations are not supported for %q", t.Name())
}
return warnings, nil
}
func checkOptionsRhel8(t *imageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
// holds warnings (e.g. deprecation notices)
var warnings []string
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.RPMOSTree && (t.Name() != "edge-commit" && t.Name() != "edge-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.Arch().Distro().Name())
}
if options.OSTree != nil {
if err := options.OSTree.Validate(); err != nil {
return warnings, err
}
}
if t.BootISO && t.RPMOSTree {
// ostree-based ISOs require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.Name())
}
if t.Name() == "edge-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO", "User", "Group", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.Name())
}
//making fdo optional so that simplified installer can be composed w/o the FDO section in the blueprint
if customizations.GetFDO() != nil {
if customizations.GetFDO().ManufacturingServerURL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.Name())
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.Name())
}
}
} else if t.Name() == "edge-installer" {
allowed := []string{"User", "Group", "FIPS", "Installer", "Timezone", "Locale"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
}
}
if t.Name() == "edge-raw-image" {
// ostree-based bootable images require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("%q images require specifying a URL from which to retrieve the OSTree commit", t.Name())
}
allowed := []string{"User", "Group", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
// TODO: consider additional checks, such as those in "edge-simplified-installer"
}
if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.RPMOSTree && t.Name() != "edge-raw-image" && t.Name() != "edge-simplified-installer" {
return warnings, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if partitioning != nil {
for _, partition := range partitioning.Partitions {
if t.Arch().Name() == arch.ARCH_AARCH64.String() {
if partition.FSType == "swap" {
return warnings, fmt.Errorf("swap partition creation is not supported on %s %s", t.Arch().Distro().Name(), t.Arch().Name())
}
for _, lv := range partition.LogicalVolumes {
if lv.FSType == "swap" {
return warnings, fmt.Errorf("swap partition creation is not supported on %s %s", t.Arch().Distro().Name(), t.Arch().Name())
}
}
}
}
}
if mountpoints != nil && t.RPMOSTree {
return warnings, fmt.Errorf("Custom mountpoints and partitioning are not supported for ostree types")
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
if t.Arch().Distro().OsVersion() == "9.0" {
return warnings, fmt.Errorf("OpenSCAP unsupported os version: %s", t.Arch().Distro().OsVersion())
}
if !oscap.IsProfileAllowed(osc.ProfileID, t.arch.distro.DistroYAML.OscapProfilesAllowList) {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if t.RPMOSTree {
return warnings, fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
w := fmt.Sprintln(common.FIPSEnabledImageWarning)
warnings = append(warnings, w)
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if slices.Index([]string{"image-installer", "edge-installer", "live-installer"}, t.Name()) == -1 {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
if t.Name() == "edge-installer" &&
instCust.Kickstart != nil &&
len(instCust.Kickstart.Contents) > 0 &&
(customizations.GetUsers() != nil || customizations.GetGroups() != nil) {
return warnings, fmt.Errorf("edge-installer installer.kickstart.contents are not supported in combination with users or groups")
}
}
return warnings, nil
}
func checkOptionsRhel7(t *imageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
// holds warnings (e.g. deprecation notices)
var warnings []string
if len(bp.Containers) > 0 {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.Arch().Distro().Name())
}
mountpoints := customizations.GetFilesystems()
err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies)
if err != nil {
return warnings, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
return warnings, fmt.Errorf("OpenSCAP unsupported os version: %s", t.Arch().Distro().OsVersion())
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
return warnings, nil
}
func checkOptionsFedora(t *imageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
var warnings []string
if !t.RPMOSTree && options.OSTree != nil {
return warnings, fmt.Errorf("OSTree is not supported for %q", t.Name())
}
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.RPMOSTree && (t.Name() != "iot-commit" && t.Name() != "iot-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.arch.distro.Name())
}
if options.OSTree != nil {
if err := options.OSTree.Validate(); err != nil {
return warnings, err
}
}
if t.BootISO && t.RPMOSTree {
// ostree-based ISOs require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.Name())
}
}
if t.Name() == "iot-raw-xz" || t.Name() == "iot-qcow2" {
allowed := []string{"User", "Group", "Directories", "Files", "Services", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
// TODO: consider additional checks, such as those in "edge-simplified-installer" in RHEL distros
}
// BootISOs have limited support for customizations.
// TODO: Support kernel name selection for image-installer
if t.BootISO {
if t.Name() == "iot-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO", "Ignition", "Kernel", "User", "Group", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.Name())
}
// FDO is optional, but when specified has some restrictions
if customizations.GetFDO() != nil {
if customizations.GetFDO().ManufacturingServerURL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to when using FDO", t.Name())
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to when using FDO", t.Name())
}
}
// ignition is optional, we might be using FDO
if customizations.GetIgnition() != nil {
if customizations.GetIgnition().Embedded != nil && customizations.GetIgnition().FirstBoot != nil {
return warnings, fmt.Errorf("both ignition embedded and firstboot configurations found")
}
if customizations.GetIgnition().FirstBoot != nil && customizations.GetIgnition().FirstBoot.ProvisioningURL == "" {
return warnings, fmt.Errorf("ignition.firstboot requires a provisioning url")
}
}
} else if t.Name() == "iot-installer" || t.Name() == "minimal-installer" {
// "Installer" is actually not allowed for image-installer right now, but this is checked at the end
allowed := []string{"User", "Group", "FIPS", "Installer", "Timezone", "Locale"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
} else if t.Name() == "workstation-live-installer" {
allowed := []string{"Installer"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.NoCustomizationsAllowedError, t.Name())
}
}
}
if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.RPMOSTree {
return warnings, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return warnings, err
}
if (len(mountpoints) > 0 || partitioning != nil) && t.RPMOSTree {
return warnings, fmt.Errorf("Custom mountpoints and partitioning are not supported for ostree types")
}
if len(mountpoints) > 0 && partitioning != nil {
return warnings, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)")
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return nil, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
supported := oscap.IsProfileAllowed(osc.ProfileID, t.arch.distro.DistroYAML.OscapProfilesAllowList)
if !supported {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if t.RPMOSTree {
return warnings, fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
warnings = append(warnings, fmt.Sprintln(common.FIPSEnabledImageWarning))
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if slices.Index([]string{"iot-installer"}, t.Name()) == -1 {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
// NOTE: the image type check is redundant with the check above, but
// let's keep it explicit in case one of the two changes.
// The kickstart contents is incompatible with the users and groups
// customization only for the iot-installer.
if t.Name() == "iot-installer" &&
instCust.Kickstart != nil &&
len(instCust.Kickstart.Contents) > 0 &&
(customizations.GetUsers() != nil || customizations.GetGroups() != nil) {
return warnings, fmt.Errorf("iot-installer installer.kickstart.contents are not supported in combination with users or groups")
}
}
return warnings, nil
}

View file

@ -142,6 +142,9 @@ type ImageConfig struct {
// ISOBootType defines what type of bootloader is used for the iso
ISOBootType *manifest.ISOBootType `yaml:"iso_boot_type,omitempty"`
// Indicates if rhc should be set to permissive when creating the registration script
PermissiveRHC *bool `yaml:"permissive_rhc,omitempty"`
// VersionlockPackges uses dnf versionlock to lock a package to the version
// that is installed during image build, preventing it from being updated.
// This is only supported for distributions that use dnf4, because osbuild
@ -186,6 +189,9 @@ type DNFConfig struct {
// InheritFrom inherits unset values from the provided parent configuration and
// returns a new structure instance, which is a result of the inheritance.
func (c *ImageConfig) InheritFrom(parentConfig *ImageConfig) *ImageConfig {
if c == nil {
c = &ImageConfig{}
}
return shallowMerge(c, parentConfig)
}

View file

@ -1,78 +0,0 @@
package rhel
import (
"errors"
"fmt"
"sort"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/platform"
)
type Architecture struct {
distro *Distribution
arch arch.Arch
imageTypes map[string]distro.ImageType
imageTypeAliases map[string]string
}
func (a *Architecture) Name() string {
return a.arch.String()
}
func (a *Architecture) Distro() distro.Distro {
return a.distro
}
func (a *Architecture) ListImageTypes() []string {
itNames := make([]string, 0, len(a.imageTypes))
for name := range a.imageTypes {
itNames = append(itNames, name)
}
sort.Strings(itNames)
return itNames
}
func (a *Architecture) GetImageType(name string) (distro.ImageType, error) {
t, exists := a.imageTypes[name]
if !exists {
aliasForName, exists := a.imageTypeAliases[name]
if !exists {
return nil, errors.New("invalid image type: " + name)
}
t, exists = a.imageTypes[aliasForName]
if !exists {
panic(fmt.Sprintf("image type '%s' is an alias to a non-existing image type '%s'", name, aliasForName))
}
}
return t, nil
}
func (a *Architecture) AddImageTypes(platform platform.Platform, imageTypes ...*ImageType) {
if a.imageTypes == nil {
a.imageTypes = map[string]distro.ImageType{}
}
for idx := range imageTypes {
it := imageTypes[idx]
it.arch = a
it.platform = platform
a.imageTypes[it.name] = it
for _, alias := range it.NameAliases {
if a.imageTypeAliases == nil {
a.imageTypeAliases = map[string]string{}
}
if existingAliasFor, exists := a.imageTypeAliases[alias]; exists {
panic(fmt.Sprintf("image type alias '%s' for '%s' is already defined for another image type '%s'", alias, it.name, existingAliasFor))
}
a.imageTypeAliases[alias] = it.name
}
}
}
func NewArchitecture(distro *Distribution, arch arch.Arch) *Architecture {
return &Architecture{
distro: distro,
arch: arch,
}
}

View file

@ -1,52 +0,0 @@
package rhel
import (
_ "embed"
"fmt"
"os"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/osbuild"
)
// Dataloss warning script for Azure images.
//
//go:embed temp-disk-dataloss-warning.sh
var azureDatalossWarningScriptContent string
// Returns a filenode that embeds a script and a systemd unit to run it on
// every boot.
// The script writes a file named DATALOSS_WARNING_README.txt to the root of an
// Azure ephemeral resource disk, if one is mounted, as a warning against using
// the disk for data storage.
// https://docs.microsoft.com/en-us/azure/virtual-machines/linux/managed-disks-overview#temporary-disk
func CreateAzureDatalossWarningScriptAndUnit() (*fsnode.File, *osbuild.SystemdUnitCreateStageOptions, error) {
datalossWarningScriptPath := "/usr/local/sbin/temp-disk-dataloss-warning"
datalossWarningScript, err := fsnode.NewFile(datalossWarningScriptPath, common.ToPtr(os.FileMode(0755)), nil, nil, []byte(azureDatalossWarningScriptContent))
if err != nil {
return nil, nil, fmt.Errorf("rhel/azure: error creating file node for dataloss warning script: %w", err)
}
systemdUnit := &osbuild.SystemdUnitCreateStageOptions{
Filename: "temp-disk-dataloss-warning.service",
UnitType: osbuild.SystemUnitType,
UnitPath: osbuild.EtcUnitPath,
Config: osbuild.SystemdUnit{
Unit: &osbuild.UnitSection{
Description: "Azure temporary resource disk dataloss warning file creation",
After: []string{"multi-user.target", "cloud-final.service"},
},
Service: &osbuild.ServiceSection{
Type: osbuild.OneshotServiceType,
ExecStart: []string{datalossWarningScriptPath},
StandardOutput: "journal+console",
},
Install: &osbuild.InstallSection{
WantedBy: []string{"default.target"},
},
},
}
return datalossWarningScript, systemdUnit, nil
}

View file

@ -1,5 +0,0 @@
package rhel
const (
UEFIVendor = "redhat"
)

View file

@ -1,192 +0,0 @@
package rhel
import (
"errors"
"fmt"
"sort"
"strings"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/runner"
)
// DefaultDistroImageConfigFunc is a function that returns the default image
// configuration for a distribution.
type DefaultDistroImageConfigFunc func(d *Distribution) *distro.ImageConfig
type Distribution struct {
name string
DistCodename string
product string
osVersion string
releaseVersion string
modulePlatformID string
vendor string
ostreeRefTmpl string
runner runner.Runner
arches map[string]distro.Arch
DefaultImageConfig DefaultDistroImageConfigFunc
// distro specific function to check options per image type
CheckOptions CheckOptionsFunc
}
func (d *Distribution) Name() string {
return d.name
}
func (d *Distribution) Codename() string {
return d.DistCodename
}
func (d *Distribution) Releasever() string {
return d.releaseVersion
}
func (d *Distribution) OsVersion() string {
return d.osVersion
}
func (d *Distribution) Product() string {
return d.product
}
func (d *Distribution) ModulePlatformID() string {
return d.modulePlatformID
}
func (d *Distribution) OSTreeRef() string {
return d.ostreeRefTmpl
}
func (d *Distribution) Vendor() string {
return d.vendor
}
func (d *Distribution) ListArches() []string {
archNames := make([]string, 0, len(d.arches))
for name := range d.arches {
archNames = append(archNames, name)
}
sort.Strings(archNames)
return archNames
}
func (d *Distribution) GetArch(name string) (distro.Arch, error) {
arch, exists := d.arches[name]
if !exists {
return nil, errors.New("invalid architecture: " + name)
}
return arch, nil
}
func (d *Distribution) AddArches(arches ...*Architecture) {
if d.arches == nil {
d.arches = map[string]distro.Arch{}
}
// Do not make copies of architectures, as opposed to image types,
// because architecture definitions are not used by more than a single
// distro definition.
for idx := range arches {
d.arches[arches[idx].Name()] = arches[idx]
}
}
func (d *Distribution) IsRHEL() bool {
return strings.HasPrefix(d.name, "rhel")
}
func (d *Distribution) IsAlmaLinux() bool {
return strings.HasPrefix(d.name, "almalinux")
}
func (d *Distribution) IsAlmaLinuxKitten() bool {
return strings.HasPrefix(d.name, "almalinux_kitten")
}
func (d *Distribution) GetDefaultImageConfig() *distro.ImageConfig {
if d.DefaultImageConfig == nil {
return nil
}
return d.DefaultImageConfig(d)
}
func NewDistribution(name string, major, minor int) (*Distribution, error) {
var rd *Distribution
switch name {
case "rhel":
if major < 0 {
return nil, errors.New("Invalid RHEL major version (must be positive)")
}
if minor < 0 {
return nil, errors.New("RHEL requires a minor version")
}
rd = &Distribution{
name: fmt.Sprintf("rhel-%d.%d", major, minor),
product: "Red Hat Enterprise Linux",
osVersion: fmt.Sprintf("%d.%d", major, minor),
releaseVersion: fmt.Sprintf("%d", major),
modulePlatformID: fmt.Sprintf("platform:el%d", major),
vendor: "redhat",
ostreeRefTmpl: fmt.Sprintf("rhel/%d/%%s/edge", major),
runner: &runner.RHEL{Major: uint64(major), Minor: uint64(minor)},
}
case "centos":
if minor != -1 {
return nil, fmt.Errorf("CentOS does not have minor versions, but got %d", minor)
}
rd = &Distribution{
name: fmt.Sprintf("centos-%d", major),
product: "CentOS Stream",
osVersion: fmt.Sprintf("%d-stream", major),
releaseVersion: fmt.Sprintf("%d", major),
modulePlatformID: fmt.Sprintf("platform:el%d", major),
vendor: "centos",
ostreeRefTmpl: fmt.Sprintf("centos/%d/%%s/edge", major),
runner: &runner.CentOS{Version: uint64(major)},
}
case "almalinux":
if major < 0 {
return nil, errors.New("Invalid AlmaLinux major version (must be positive)")
}
if minor < 0 {
return nil, errors.New("AlmaLinux requires a minor version")
}
rd = &Distribution{
name: fmt.Sprintf("almalinux-%d.%d", major, minor),
product: "AlmaLinux",
osVersion: fmt.Sprintf("%d.%d", major, minor),
releaseVersion: fmt.Sprintf("%d", major),
modulePlatformID: fmt.Sprintf("platform:el%d", major),
vendor: "almalinux",
ostreeRefTmpl: fmt.Sprintf("almalinux/%d/%%s/edge", major),
runner: &runner.RHEL{Major: uint64(major), Minor: uint64(minor)},
}
case "almalinux_kitten":
if minor != -1 {
return nil, fmt.Errorf("AlmaLinux Kitten does not have minor versions, but got %d", minor)
}
rd = &Distribution{
name: fmt.Sprintf("almalinux_kitten-%d", major),
product: "AlmaLinux Kitten",
osVersion: fmt.Sprintf("%d-kitten", major),
releaseVersion: fmt.Sprintf("%d", major),
modulePlatformID: fmt.Sprintf("platform:el%d", major),
vendor: "almalinux",
ostreeRefTmpl: fmt.Sprintf("almalinux/%d/%%s/edge", major),
runner: &runner.CentOS{Version: uint64(major)},
}
default:
return nil, fmt.Errorf("unknown distro name: %s", name)
}
return rd, nil
}

View file

@ -1,874 +0,0 @@
package rhel
import (
"fmt"
"math/rand"
"github.com/osbuild/images/internal/workload"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/customizations/anaconda"
"github.com/osbuild/images/pkg/customizations/fdo"
"github.com/osbuild/images/pkg/customizations/fsnode"
"github.com/osbuild/images/pkg/customizations/ignition"
"github.com/osbuild/images/pkg/customizations/kickstart"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/customizations/subscription"
"github.com/osbuild/images/pkg/customizations/users"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/image"
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/ostree"
"github.com/osbuild/images/pkg/rpmmd"
)
func osCustomizations(
t *ImageType,
osPackageSet rpmmd.PackageSet,
options distro.ImageOptions,
containers []container.SourceSpec,
c *blueprint.Customizations,
) (manifest.OSCustomizations, error) {
imageConfig := t.getDefaultImageConfig()
osc := manifest.OSCustomizations{}
if t.Bootable || t.RPMOSTree {
// TODO: for now the only image types that define a default kernel are
// ones that use UKIs and don't allow overriding, so this works.
// However, if we ever need to specify default kernels for image types
// that allow overriding, we will need to change c.GetKernel() to take
// an argument as fallback or make it not return the standard "kernel"
// when it's unset.
osc.KernelName = c.GetKernel().Name
if imageConfig.DefaultKernelName != nil {
osc.KernelName = *imageConfig.DefaultKernelName
}
var kernelOptions []string
// XXX: keep in sync with the identical copy in fedora/images.go
if t.DefaultImageConfig != nil && len(t.DefaultImageConfig.KernelOptions) > 0 {
kernelOptions = append(kernelOptions, t.DefaultImageConfig.KernelOptions...)
}
if bpKernel := c.GetKernel(); bpKernel.Append != "" {
kernelOptions = append(kernelOptions, bpKernel.Append)
}
osc.KernelOptionsAppend = kernelOptions
if imageConfig.KernelOptionsBootloader != nil {
osc.KernelOptionsBootloader = *imageConfig.KernelOptionsBootloader
}
}
osc.FIPS = c.GetFIPS()
osc.BasePackages = osPackageSet.Include
osc.ExcludeBasePackages = osPackageSet.Exclude
osc.ExtraBaseRepos = osPackageSet.Repositories
osc.Containers = containers
osc.GPGKeyFiles = imageConfig.GPGKeyFiles
if rpm := c.GetRPM(); rpm != nil && rpm.ImportKeys != nil {
osc.GPGKeyFiles = append(osc.GPGKeyFiles, rpm.ImportKeys.Files...)
}
if imageConfig.ExcludeDocs != nil {
osc.ExcludeDocs = *imageConfig.ExcludeDocs
}
if !t.BootISO {
// don't put users and groups in the payload of an installer
// add them via kickstart instead
osc.Groups = users.GroupsFromBP(c.GetGroups())
osc.Users = users.UsersFromBP(c.GetUsers())
osc.Users = append(osc.Users, imageConfig.Users...)
}
osc.EnabledServices = imageConfig.EnabledServices
osc.DisabledServices = imageConfig.DisabledServices
osc.MaskedServices = imageConfig.MaskedServices
if imageConfig.DefaultTarget != nil {
osc.DefaultTarget = *imageConfig.DefaultTarget
}
osc.Firewall = imageConfig.Firewall
if fw := c.GetFirewall(); fw != nil {
options := osbuild.FirewallStageOptions{
Ports: fw.Ports,
}
if fw.Services != nil {
options.EnabledServices = fw.Services.Enabled
options.DisabledServices = fw.Services.Disabled
}
if fw.Zones != nil {
for _, z := range fw.Zones {
options.Zones = append(options.Zones, osbuild.FirewallZone{
Name: *z.Name,
Sources: z.Sources,
})
}
}
osc.Firewall = &options
}
language, keyboard := c.GetPrimaryLocale()
if language != nil {
osc.Language = *language
} else if imageConfig.Locale != nil {
osc.Language = *imageConfig.Locale
}
if keyboard != nil {
osc.Keyboard = keyboard
} else if imageConfig.Keyboard != nil {
osc.Keyboard = &imageConfig.Keyboard.Keymap
if imageConfig.Keyboard.X11Keymap != nil {
osc.X11KeymapLayouts = imageConfig.Keyboard.X11Keymap.Layouts
}
}
if hostname := c.GetHostname(); hostname != nil {
osc.Hostname = *hostname
}
timezone, ntpServers := c.GetTimezoneSettings()
if timezone != nil {
osc.Timezone = *timezone
} else if imageConfig.Timezone != nil {
osc.Timezone = *imageConfig.Timezone
}
if len(ntpServers) > 0 {
chronyServers := make([]osbuild.ChronyConfigServer, 0, len(ntpServers))
for _, server := range ntpServers {
chronyServers = append(chronyServers, osbuild.ChronyConfigServer{Hostname: server})
}
osc.ChronyConfig = &osbuild.ChronyStageOptions{
Servers: chronyServers,
}
} else if imageConfig.TimeSynchronization != nil {
osc.ChronyConfig = imageConfig.TimeSynchronization
}
// Relabel the tree, unless the `NoSELinux` flag is explicitly set to `true`
if imageConfig.NoSELinux == nil || imageConfig.NoSELinux != nil && !*imageConfig.NoSELinux {
osc.SELinux = "targeted"
osc.SELinuxForceRelabel = imageConfig.SELinuxForceRelabel
}
if t.IsRHEL() && options.Facts != nil {
osc.RHSMFacts = options.Facts
}
var err error
osc.Directories, err = blueprint.DirectoryCustomizationsToFsNodeDirectories(c.GetDirectories())
if err != nil {
// In theory this should never happen, because the blueprint directory customizations
// should have been validated before this point.
panic(fmt.Sprintf("failed to convert directory customizations to fs node directories: %v", err))
}
osc.Files, err = blueprint.FileCustomizationsToFsNodeFiles(c.GetFiles())
if err != nil {
// In theory this should never happen, because the blueprint file customizations
// should have been validated before this point.
panic(fmt.Sprintf("failed to convert file customizations to fs node files: %v", err))
}
// OSTree commits do not include data in `/var` since that is tied to the
// deployment, rather than the commit. Therefore the containers need to be
// stored in a different location, like `/usr/share`, and the container
// storage engine configured accordingly.
if t.RPMOSTree && len(containers) > 0 {
storagePath := "/usr/share/containers/storage"
osc.ContainersStorage = &storagePath
}
if containerStorage := c.GetContainerStorage(); containerStorage != nil {
osc.ContainersStorage = containerStorage.StoragePath
}
// set yum repos first, so it doesn't get overridden by
// imageConfig.YUMRepos
osc.YUMRepos = imageConfig.YUMRepos
customRepos, err := c.GetRepositories()
if err != nil {
// This shouldn't happen and since the repos
// should have already been validated
panic(fmt.Sprintf("failed to get custom repos: %v", err))
}
// This function returns a map of filename and corresponding yum repos
// and a list of fs node files for the inline gpg keys so we can save
// them to disk. This step also swaps the inline gpg key with the path
// to the file in the os file tree
yumRepos, gpgKeyFiles, err := blueprint.RepoCustomizationsToRepoConfigAndGPGKeyFiles(customRepos)
if err != nil {
panic(fmt.Sprintf("failed to convert inline gpgkeys to fs node files: %v", err))
}
// add the gpg key files to the list of files to be added to the tree
if len(gpgKeyFiles) > 0 {
osc.Files = append(osc.Files, gpgKeyFiles...)
}
for filename, repos := range yumRepos {
osc.YUMRepos = append(osc.YUMRepos, osbuild.NewYumReposStageOptions(filename, repos))
}
if oscapConfig := c.GetOpenSCAP(); oscapConfig != nil {
if t.RPMOSTree {
panic("unexpected oscap options for ostree image type")
}
oscapDataNode, err := fsnode.NewDirectory(oscap.DataDir, nil, nil, nil, true)
if err != nil {
panic(fmt.Sprintf("unexpected error creating required OpenSCAP directory: %s", oscap.DataDir))
}
osc.Directories = append(osc.Directories, oscapDataNode)
remediationConfig, err := oscap.NewConfigs(*oscapConfig, imageConfig.DefaultOSCAPDatastream)
if err != nil {
panic(fmt.Errorf("error creating OpenSCAP configs: %w", err))
}
osc.OpenSCAPRemediationConfig = remediationConfig
}
var subscriptionStatus subscription.RHSMStatus
if options.Subscription != nil {
subscriptionStatus = subscription.RHSMConfigWithSubscription
if options.Subscription.Proxy != "" {
osc.InsightsClientConfig = &osbuild.InsightsClientConfigStageOptions{Config: osbuild.InsightsClientConfig{Proxy: options.Subscription.Proxy}}
}
} else {
subscriptionStatus = subscription.RHSMConfigNoSubscription
}
if rhsmConfig, exists := imageConfig.RHSMConfig[subscriptionStatus]; exists {
osc.RHSMConfig = rhsmConfig
}
if bpRhsmConfig := subscription.RHSMConfigFromBP(c.GetRHSM()); bpRhsmConfig != nil {
osc.RHSMConfig = osc.RHSMConfig.Update(bpRhsmConfig)
}
osc.ShellInit = imageConfig.ShellInit
osc.Grub2Config = imageConfig.Grub2Config
osc.Sysconfig = imageConfig.SysconfigStageOptions()
osc.SystemdLogind = imageConfig.SystemdLogind
osc.CloudInit = imageConfig.CloudInit
osc.Modprobe = imageConfig.Modprobe
osc.DracutConf = imageConfig.DracutConf
osc.SystemdDropin = imageConfig.SystemdDropin
osc.SystemdUnit = imageConfig.SystemdUnit
osc.Authselect = imageConfig.Authselect
osc.SELinuxConfig = imageConfig.SELinuxConfig
osc.Tuned = imageConfig.Tuned
osc.Tmpfilesd = imageConfig.Tmpfilesd
osc.PamLimitsConf = imageConfig.PamLimitsConf
osc.Sysctld = imageConfig.Sysctld
osc.DNFConfig = imageConfig.DNFConfigOptions(t.arch.distro.osVersion)
osc.DNFAutomaticConfig = imageConfig.DNFAutomaticConfig
osc.YUMConfig = imageConfig.YumConfig
osc.SshdConfig = imageConfig.SshdConfig
osc.AuthConfig = imageConfig.Authconfig
osc.PwQuality = imageConfig.PwQuality
osc.Subscription = options.Subscription
osc.WAAgentConfig = imageConfig.WAAgentConfig
osc.UdevRules = imageConfig.UdevRules
osc.GCPGuestAgentConfig = imageConfig.GCPGuestAgentConfig
osc.NetworkManager = imageConfig.NetworkManager
if imageConfig.WSL != nil {
osc.WSLConfig = osbuild.NewWSLConfStageOptions(imageConfig.WSL.Config)
osc.WSLDistributionConfig = osbuild.NewWSLDistributionConfStageOptions(imageConfig.WSL.DistributionConfig)
}
osc.Files = append(osc.Files, imageConfig.Files...)
osc.Directories = append(osc.Directories, imageConfig.Directories...)
if imageConfig.NoBLS != nil {
osc.NoBLS = *imageConfig.NoBLS
}
ca, err := c.GetCACerts()
if err != nil {
panic(fmt.Sprintf("unexpected error checking CA certs: %v", err))
}
if ca != nil {
osc.CACerts = ca.PEMCerts
}
if imageConfig.InstallWeakDeps != nil {
osc.InstallWeakDeps = *imageConfig.InstallWeakDeps
}
if imageConfig.MountUnits != nil {
osc.MountUnits = *imageConfig.MountUnits
}
osc.VersionlockPackages = imageConfig.VersionlockPackages
return osc, nil
}
func ostreeDeploymentCustomizations(
t *ImageType,
c *blueprint.Customizations) (manifest.OSTreeDeploymentCustomizations, error) {
if !t.RPMOSTree || !t.Bootable {
return manifest.OSTreeDeploymentCustomizations{}, fmt.Errorf("ostree deployment customizations are only supported for bootable rpm-ostree images")
}
imageConfig := t.getDefaultImageConfig()
deploymentConf := manifest.OSTreeDeploymentCustomizations{}
var kernelOptions []string
if len(t.DefaultImageConfig.KernelOptions) > 0 {
kernelOptions = append(kernelOptions, t.DefaultImageConfig.KernelOptions...)
}
if bpKernel := c.GetKernel(); bpKernel != nil && bpKernel.Append != "" {
kernelOptions = append(kernelOptions, bpKernel.Append)
}
if imageConfig.IgnitionPlatform != nil {
deploymentConf.IgnitionPlatform = *imageConfig.IgnitionPlatform
}
switch deploymentConf.IgnitionPlatform {
case "metal":
if bpIgnition := c.GetIgnition(); bpIgnition != nil && bpIgnition.FirstBoot != nil && bpIgnition.FirstBoot.ProvisioningURL != "" {
kernelOptions = append(kernelOptions, "ignition.config.url="+bpIgnition.FirstBoot.ProvisioningURL)
}
}
deploymentConf.KernelOptionsAppend = kernelOptions
deploymentConf.FIPS = c.GetFIPS()
deploymentConf.Users = users.UsersFromBP(c.GetUsers())
deploymentConf.Groups = users.GroupsFromBP(c.GetGroups())
var err error
deploymentConf.Directories, err = blueprint.DirectoryCustomizationsToFsNodeDirectories(c.GetDirectories())
if err != nil {
return manifest.OSTreeDeploymentCustomizations{}, err
}
deploymentConf.Files, err = blueprint.FileCustomizationsToFsNodeFiles(c.GetFiles())
if err != nil {
return manifest.OSTreeDeploymentCustomizations{}, err
}
language, keyboard := c.GetPrimaryLocale()
if language != nil {
deploymentConf.Locale = *language
} else if imageConfig.Locale != nil {
deploymentConf.Locale = *imageConfig.Locale
}
if keyboard != nil {
deploymentConf.Keyboard = *keyboard
} else if imageConfig.Keyboard != nil {
deploymentConf.Keyboard = imageConfig.Keyboard.Keymap
}
if imageConfig.OSTreeConfSysrootReadOnly != nil {
deploymentConf.SysrootReadOnly = *imageConfig.OSTreeConfSysrootReadOnly
}
if imageConfig.LockRootUser != nil {
deploymentConf.LockRoot = *imageConfig.LockRootUser
}
for _, fs := range c.GetFilesystems() {
deploymentConf.CustomFileSystems = append(deploymentConf.CustomFileSystems, fs.Mountpoint)
}
if imageConfig.MountUnits != nil {
deploymentConf.MountUnits = *imageConfig.MountUnits
}
return deploymentConf, nil
}
func DiskImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewDiskImage()
img.Platform = t.platform
var err error
img.OSCustomizations, err = osCustomizations(t, packageSets[OSPkgsKey], options, containers, customizations)
if err != nil {
return nil, err
}
img.Environment = t.Environment
img.Workload = workload
img.Compression = t.Compression
// TODO: move generation into LiveImage
pt, err := t.GetPartitionTable(customizations, options, rng)
if err != nil {
return nil, err
}
img.PartitionTable = pt
img.Filename = t.Filename()
img.VPCForceSize = t.DiskImageVPCForceSize
if img.OSCustomizations.NoBLS {
img.OSProduct = t.Arch().Distro().Product()
img.OSVersion = t.Arch().Distro().OsVersion()
img.OSNick = t.Arch().Distro().Codename()
}
if t.DiskImagePartTool != nil {
img.PartTool = *t.DiskImagePartTool
}
return img, nil
}
func EdgeCommitImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeArchive(commitRef)
img.Platform = t.platform
var err error
img.OSCustomizations, err = osCustomizations(t, packageSets[OSPkgsKey], options, containers, customizations)
if err != nil {
return nil, err
}
img.Environment = t.Environment
img.Workload = workload
img.OSTreeParent = parentCommit
img.OSVersion = t.Arch().Distro().OsVersion()
img.Filename = t.Filename()
return img, nil
}
func EdgeContainerImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
parentCommit, commitRef := makeOSTreeParentCommit(options.OSTree, t.OSTreeRef())
img := image.NewOSTreeContainer(commitRef)
img.Platform = t.platform
var err error
img.OSCustomizations, err = osCustomizations(t, packageSets[OSPkgsKey], options, containers, customizations)
if err != nil {
return nil, err
}
img.ContainerLanguage = img.OSCustomizations.Language
img.Environment = t.Environment
img.Workload = workload
img.OSTreeParent = parentCommit
img.OSVersion = t.Arch().Distro().OsVersion()
img.ExtraContainerPackages = packageSets[ContainerPkgsKey]
img.Filename = t.Filename()
return img, nil
}
func EdgeInstallerImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform
img.ExtraBasePackages = packageSets[InstallerPkgsKey]
img.Subscription = options.Subscription
if t.Arch().Distro().Releasever() == "8" {
// NOTE: RHEL 8 only supports the older Anaconda configs
img.UseLegacyAnacondaConfig = true
}
img.Kickstart, err = kickstart.New(customizations)
if err != nil {
return nil, err
}
img.Kickstart.OSTree = &kickstart.OSTree{
OSName: "rhel-edge",
}
img.Kickstart.Path = osbuild.KickstartPathOSBuild
img.Kickstart.Language, img.Kickstart.Keyboard = customizations.GetPrimaryLocale()
// ignore ntp servers - we don't currently support setting these in the
// kickstart though kickstart does support setting them
img.Kickstart.Timezone, _ = customizations.GetTimezoneSettings()
img.RootfsCompression = "xz"
if t.Arch().Distro().Releasever() == "10" {
img.RootfsType = manifest.SquashfsRootfs
}
if locale := t.getDefaultImageConfig().Locale; locale != nil {
img.Locale = *locale
}
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
installerConfig, err := t.getDefaultInstallerConfig()
if err != nil {
return nil, err
}
if installerConfig != nil {
img.AdditionalDracutModules = append(img.AdditionalDracutModules, installerConfig.AdditionalDracutModules...)
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
}
instCust, err := customizations.GetInstaller()
if err != nil {
return nil, err
}
if instCust != nil && instCust.Modules != nil {
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, instCust.Modules.Enable...)
img.DisabledAnacondaModules = append(img.DisabledAnacondaModules, instCust.Modules.Disable...)
}
if len(img.Kickstart.Users)+len(img.Kickstart.Groups) > 0 {
// only enable the users module if needed
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, anaconda.ModuleUsers)
}
img.ISOLabel, err = t.ISOLabel()
if err != nil {
return nil, err
}
img.Product = t.Arch().Distro().Product()
img.Variant = "edge"
img.OSVersion = t.Arch().Distro().OsVersion()
img.Release = fmt.Sprintf("%s %s", t.Arch().Distro().Product(), t.Arch().Distro().OsVersion())
img.FIPS = customizations.GetFIPS()
img.Filename = t.Filename()
return img, nil
}
func EdgeRawImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeDiskImageFromCommit(commit)
deploymentConfig, err := ostreeDeploymentCustomizations(t, customizations)
if err != nil {
return nil, err
}
img.OSTreeDeploymentCustomizations = deploymentConfig
img.Platform = t.platform
img.Workload = workload
img.Remote = ostree.Remote{
Name: "rhel-edge",
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
img.OSName = "rhel-edge"
// TODO: move generation into LiveImage
pt, err := t.GetPartitionTable(customizations, options, rng)
if err != nil {
return nil, err
}
img.PartitionTable = pt
img.Filename = t.Filename()
img.Compression = t.Compression
return img, nil
}
func EdgeSimplifiedInstallerImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
commit, err := makeOSTreePayloadCommit(options.OSTree, t.OSTreeRef())
if err != nil {
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
rawImg := image.NewOSTreeDiskImageFromCommit(commit)
deploymentConfig, err := ostreeDeploymentCustomizations(t, customizations)
if err != nil {
return nil, err
}
rawImg.OSTreeDeploymentCustomizations = deploymentConfig
rawImg.Platform = t.platform
rawImg.Workload = workload
rawImg.Remote = ostree.Remote{
Name: "rhel-edge",
URL: options.OSTree.URL,
ContentURL: options.OSTree.ContentURL,
}
rawImg.OSName = "rhel-edge"
// TODO: move generation into LiveImage
pt, err := t.GetPartitionTable(customizations, options, rng)
if err != nil {
return nil, err
}
rawImg.PartitionTable = pt
rawImg.Filename = t.Filename()
img := image.NewOSTreeSimplifiedInstaller(rawImg, customizations.InstallationDevice)
img.ExtraBasePackages = packageSets[InstallerPkgsKey]
// img.Workload = workload
img.Platform = t.platform
img.Filename = t.Filename()
if bpFDO := customizations.GetFDO(); bpFDO != nil {
img.FDO = fdo.FromBP(*bpFDO)
}
// ignition configs from blueprint
if bpIgnition := customizations.GetIgnition(); bpIgnition != nil {
if bpIgnition.Embedded != nil {
var err error
img.IgnitionEmbedded, err = ignition.EmbeddedOptionsFromBP(*bpIgnition.Embedded)
if err != nil {
return nil, err
}
}
}
img.ISOLabel, err = t.ISOLabel()
if err != nil {
return nil, err
}
d := t.arch.distro
img.Product = d.product
img.Variant = "edge"
img.OSName = "rhel-edge"
img.OSVersion = d.osVersion
installerConfig, err := t.getDefaultInstallerConfig()
if err != nil {
return nil, err
}
if installerConfig != nil {
img.AdditionalDracutModules = append(img.AdditionalDracutModules, installerConfig.AdditionalDracutModules...)
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
}
return img, nil
}
func ImageInstallerImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewAnacondaTarInstaller()
img.Platform = t.platform
img.Workload = workload
var err error
img.OSCustomizations, err = osCustomizations(t, packageSets[OSPkgsKey], options, containers, customizations)
if err != nil {
return nil, err
}
img.ExtraBasePackages = packageSets[InstallerPkgsKey]
if t.Arch().Distro().Releasever() == "8" {
// NOTE: RHEL 8 only supports the older Anaconda configs
img.UseLegacyAnacondaConfig = true
}
img.Kickstart, err = kickstart.New(customizations)
if err != nil {
return nil, err
}
img.Kickstart.Language = &img.OSCustomizations.Language
img.Kickstart.Keyboard = img.OSCustomizations.Keyboard
img.Kickstart.Timezone = &img.OSCustomizations.Timezone
installerConfig, err := t.getDefaultInstallerConfig()
if err != nil {
return nil, err
}
if installerConfig != nil {
img.AdditionalDracutModules = append(img.AdditionalDracutModules, installerConfig.AdditionalDracutModules...)
img.AdditionalDrivers = append(img.AdditionalDrivers, installerConfig.AdditionalDrivers...)
}
instCust, err := customizations.GetInstaller()
if err != nil {
return nil, err
}
if instCust != nil && instCust.Modules != nil {
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, instCust.Modules.Enable...)
img.DisabledAnacondaModules = append(img.DisabledAnacondaModules, instCust.Modules.Disable...)
}
img.AdditionalAnacondaModules = append(img.AdditionalAnacondaModules, anaconda.ModuleUsers)
img.RootfsCompression = "xz"
if t.Arch().Distro().Releasever() == "10" {
img.RootfsType = manifest.SquashfsRootfs
}
if isoboot := t.getDefaultImageConfig().ISOBootType; isoboot != nil {
img.ISOBoot = *isoboot
}
// put the kickstart file in the root of the iso
img.ISORootKickstart = true
img.ISOLabel, err = t.ISOLabel()
if err != nil {
return nil, err
}
d := t.arch.distro
img.Product = d.product
img.OSVersion = d.osVersion
img.Release = fmt.Sprintf("%s %s", d.product, d.osVersion)
img.Filename = t.Filename()
return img, nil
}
func TarImage(workload workload.Workload,
t *ImageType,
customizations *blueprint.Customizations,
options distro.ImageOptions,
packageSets map[string]rpmmd.PackageSet,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewArchive()
img.Platform = t.platform
var err error
img.OSCustomizations, err = osCustomizations(t, packageSets[OSPkgsKey], options, containers, customizations)
if err != nil {
return nil, err
}
img.Environment = t.Environment
img.Workload = workload
img.Compression = t.Compression
img.OSVersion = t.Arch().Distro().OsVersion()
img.Filename = t.Filename()
return img, nil
}
// Create an ostree SourceSpec to define an ostree parent commit using the user
// options and the default ref for the image type. Additionally returns the
// ref to be used for the new commit to be created.
func makeOSTreeParentCommit(options *ostree.ImageOptions, defaultRef string) (*ostree.SourceSpec, string) {
commitRef := defaultRef
if options == nil {
// nothing to do
return nil, commitRef
}
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
var parentCommit *ostree.SourceSpec
if options.URL == "" {
// no parent
return nil, commitRef
}
// ostree URL specified: set source spec for parent commit
parentRef := options.ParentRef
if parentRef == "" {
// parent ref not set: use image ref
parentRef = commitRef
}
parentCommit = &ostree.SourceSpec{
URL: options.URL,
Ref: parentRef,
RHSM: options.RHSM,
}
return parentCommit, commitRef
}
// Create an ostree SourceSpec to define an ostree payload using the user options and the default ref for the image type.
func makeOSTreePayloadCommit(options *ostree.ImageOptions, defaultRef string) (ostree.SourceSpec, error) {
if options == nil || options.URL == "" {
// this should be caught by checkOptions() in distro, but it's good
// to guard against it here as well
return ostree.SourceSpec{}, fmt.Errorf("ostree commit URL required")
}
commitRef := defaultRef
if options.ImageRef != "" {
// user option overrides default commit ref
commitRef = options.ImageRef
}
return ostree.SourceSpec{
URL: options.URL,
Ref: commitRef,
RHSM: options.RHSM,
}, nil
}

View file

@ -1,461 +0,0 @@
package rhel
import (
"fmt"
"math/rand"
"slices"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/internal/environment"
"github.com/osbuild/images/internal/workload"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/container"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/experimentalflags"
"github.com/osbuild/images/pkg/image"
"github.com/osbuild/images/pkg/manifest"
"github.com/osbuild/images/pkg/osbuild"
"github.com/osbuild/images/pkg/platform"
"github.com/osbuild/images/pkg/rpmmd"
)
const (
// package set names
// build package set name
BuildPkgsKey = "build"
// main/common os image package set name
OSPkgsKey = "os"
// container package set name
ContainerPkgsKey = "container"
// installer package set name
InstallerPkgsKey = "installer"
// blueprint package set name
BlueprintPkgsKey = "blueprint"
)
// Default directory size minimums for all image types.
var requiredDirectorySizes = map[string]uint64{
"/": 1 * datasizes.GiB,
"/usr": 2 * datasizes.GiB,
}
type ImageFunc func(workload workload.Workload, t *ImageType, customizations *blueprint.Customizations, options distro.ImageOptions, packageSets map[string]rpmmd.PackageSet, containers []container.SourceSpec, rng *rand.Rand) (image.ImageKind, error)
type PackageSetFunc func(t *ImageType) (map[string]rpmmd.PackageSet, error)
type BasePartitionTableFunc func(t *ImageType) (disk.PartitionTable, bool)
type ISOLabelFunc func(t *ImageType) string
type CheckOptionsFunc func(t *ImageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error)
type ImageType struct {
// properties, which are part of the distro.ImageType interface or are used by all images
name string
filename string
mimeType string
packageSets PackageSetFunc
buildPipelines []string
payloadPipelines []string
exports []string
image ImageFunc
// properties which can't be set when defining the image type
arch *Architecture
platform platform.Platform
Environment environment.Environment
Workload workload.Workload
NameAliases []string
Compression string // TODO: remove from image definition and make it a transport option
DefaultImageConfig *distro.ImageConfig
DefaultInstallerConfig *distro.InstallerConfig
DefaultSize uint64
// bootISO: installable ISO
BootISO bool
// rpmOstree: edge/ostree
RPMOSTree bool
// bootable image
Bootable bool
// List of valid arches for the image type
BasePartitionTables BasePartitionTableFunc
// Optional list of unsupported partitioning modes
UnsupportedPartitioningModes []disk.PartitioningMode
ISOLabelFn ISOLabelFunc
// TODO: determine a better place for these options, but for now they are here
DiskImagePartTool *osbuild.PartTool
DiskImageVPCForceSize *bool
}
func (t *ImageType) Name() string {
return t.name
}
func (t *ImageType) Arch() distro.Arch {
return t.arch
}
func (t *ImageType) Filename() string {
return t.filename
}
func (t *ImageType) MIMEType() string {
return t.mimeType
}
func (t *ImageType) OSTreeRef() string {
d := t.arch.distro
if t.RPMOSTree {
return fmt.Sprintf(d.ostreeRefTmpl, t.Arch().Name())
}
return ""
}
// IsRHEL returns true if the image type is part of a RHEL distribution
//
// This is a convenience method, because external packages can't get the
// information from t.Arch().Distro(), since the distro.Distro interface
// does not have this method. And since the distro.Distro interface is
// distro-agnostic, it does not make much sense to have a method like this
// in the interface.
func (t *ImageType) IsRHEL() bool {
return t.arch.distro.IsRHEL()
}
func (t *ImageType) IsAlmaLinux() bool {
return t.arch.distro.IsAlmaLinux()
}
func (t *ImageType) IsAlmaLinuxKitten() bool {
return t.arch.distro.IsAlmaLinuxKitten()
}
func (t *ImageType) ISOLabel() (string, error) {
if !t.BootISO {
return "", fmt.Errorf("image type %q is not an ISO", t.name)
}
if t.ISOLabelFn != nil {
return t.ISOLabelFn(t), nil
}
return "", nil
}
func (t *ImageType) Size(size uint64) uint64 {
// Microsoft Azure requires vhd images to be rounded up to the nearest MB
if t.name == "vhd" && size%datasizes.MebiByte != 0 {
size = (size/datasizes.MebiByte + 1) * datasizes.MebiByte
}
if size == 0 {
size = t.DefaultSize
}
return size
}
func (t *ImageType) BuildPipelines() []string {
return t.buildPipelines
}
func (t *ImageType) PayloadPipelines() []string {
return t.payloadPipelines
}
func (t *ImageType) PayloadPackageSets() []string {
return []string{BlueprintPkgsKey}
}
func (t *ImageType) Exports() []string {
if len(t.exports) > 0 {
return t.exports
}
return []string{"assembler"}
}
func (t *ImageType) BootMode() platform.BootMode {
if t.platform.GetUEFIVendor() != "" && t.platform.GetBIOSPlatform() != "" {
return platform.BOOT_HYBRID
} else if t.platform.GetUEFIVendor() != "" {
return platform.BOOT_UEFI
} else if t.platform.GetBIOSPlatform() != "" || t.platform.GetZiplSupport() {
return platform.BOOT_LEGACY
}
return platform.BOOT_NONE
}
func (t *ImageType) BasePartitionTable() (*disk.PartitionTable, error) {
// XXX: simplify once https://github.com/osbuild/images/pull/1372
// (or something similar) went in, see pkg/distro/fedora, once
// the yaml based loading is in we can drop from ImageType
// "BasePartitionTables BasePartitionTableFunc"
if t.BasePartitionTables == nil {
return nil, nil
}
basePartitionTable, exists := t.BasePartitionTables(t)
if !exists {
return nil, nil
}
return &basePartitionTable, nil
}
func (t *ImageType) GetPartitionTable(
customizations *blueprint.Customizations,
options distro.ImageOptions,
rng *rand.Rand,
) (*disk.PartitionTable, error) {
archName := t.arch.Name()
basePartitionTable, exists := t.BasePartitionTables(t)
if !exists {
return nil, fmt.Errorf("no partition table defined for architecture %q for image type %q", archName, t.Name())
}
imageSize := t.Size(options.Size)
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if partitioning != nil {
// Use the new custom partition table to create a PT fully based on the user's customizations.
// This overrides FilesystemCustomizations, but we should never have both defined.
if options.Size > 0 {
// user specified a size on the command line, so let's override the
// customization with the calculated/rounded imageSize
partitioning.MinSize = imageSize
}
partOptions := &disk.CustomPartitionTableOptions{
PartitionTableType: basePartitionTable.Type, // PT type is not customizable, it is determined by the base PT for an image type or architecture
BootMode: t.BootMode(),
DefaultFSType: disk.FS_XFS, // default fs type for RHEL
RequiredMinSizes: requiredDirectorySizes,
Architecture: t.platform.GetArch(),
}
return disk.NewCustomPartitionTable(partitioning, partOptions, rng)
}
return disk.NewPartitionTable(&basePartitionTable, customizations.GetFilesystems(), imageSize, options.PartitioningMode, t.platform.GetArch(), nil, rng)
}
func (t *ImageType) getDefaultImageConfig() *distro.ImageConfig {
// ensure that image always returns non-nil default config
imageConfig := t.DefaultImageConfig
if imageConfig == nil {
imageConfig = &distro.ImageConfig{}
}
return imageConfig.InheritFrom(t.arch.distro.GetDefaultImageConfig())
}
func (t *ImageType) getDefaultInstallerConfig() (*distro.InstallerConfig, error) {
if !t.BootISO {
return nil, fmt.Errorf("image type %q is not an ISO", t.name)
}
return t.DefaultInstallerConfig, nil
}
func (t *ImageType) PartitionType() disk.PartitionTableType {
if t.BasePartitionTables == nil {
return disk.PT_NONE
}
basePartitionTable, exists := t.BasePartitionTables(t)
if !exists {
return disk.PT_NONE
}
return basePartitionTable.Type
}
func (t *ImageType) Manifest(bp *blueprint.Blueprint,
options distro.ImageOptions,
repos []rpmmd.RepoConfig,
seedp *int64) (*manifest.Manifest, []string, error) {
seed := distro.SeedFrom(seedp)
if t.Workload != nil {
// For now, if an image type defines its own workload, don't allow any
// user customizations.
// Soon we will have more workflows and each will define its allowed
// set of customizations. The current set of customizations defined in
// the blueprint spec corresponds to the Custom workflow.
if bp.Customizations != nil {
return nil, nil, fmt.Errorf(distro.NoCustomizationsAllowedError, t.Name())
}
}
warnings, err := t.checkOptions(bp, options)
if err != nil {
return nil, nil, err
}
// merge package sets that appear in the image type with the package sets
// of the same name from the distro and arch
staticPackageSets := make(map[string]rpmmd.PackageSet)
if t.packageSets != nil {
pkgSets, err := t.packageSets(t)
if err != nil {
return nil, nil, err
}
for name, pkgSet := range pkgSets {
staticPackageSets[name] = pkgSet
}
}
// amend with repository information and collect payload repos
payloadRepos := make([]rpmmd.RepoConfig, 0)
for _, repo := range repos {
if len(repo.PackageSets) > 0 {
// only apply the repo to the listed package sets
for _, psName := range repo.PackageSets {
if slices.Contains(t.PayloadPackageSets(), psName) {
payloadRepos = append(payloadRepos, repo)
}
ps := staticPackageSets[psName]
ps.Repositories = append(ps.Repositories, repo)
staticPackageSets[psName] = ps
}
}
}
w := t.Workload
if w == nil {
// XXX: this needs to get duplicaed in exactly the same
// way in fedora/imagetype.go
workloadRepos := payloadRepos
customRepos, err := bp.Customizations.GetRepositories()
if err != nil {
return nil, nil, err
}
installFromRepos := blueprint.RepoCustomizationsInstallFromOnly(customRepos)
workloadRepos = append(workloadRepos, installFromRepos...)
cw := &workload.Custom{
BaseWorkload: workload.BaseWorkload{
Repos: workloadRepos,
},
Packages: bp.GetPackagesEx(false),
EnabledModules: bp.GetEnabledModules(),
}
if services := bp.Customizations.GetServices(); services != nil {
cw.Services = services.Enabled
cw.DisabledServices = services.Disabled
cw.MaskedServices = services.Masked
}
w = cw
}
containerSources := make([]container.SourceSpec, len(bp.Containers))
for idx, cont := range bp.Containers {
containerSources[idx] = container.SourceSpec{
Source: cont.Source,
Name: cont.Name,
TLSVerify: cont.TLSVerify,
Local: cont.LocalStorage,
}
}
if experimentalflags.Bool("no-fstab") {
if t.DefaultImageConfig == nil {
t.DefaultImageConfig = &distro.ImageConfig{
MountUnits: common.ToPtr(true),
}
} else {
t.DefaultImageConfig.MountUnits = common.ToPtr(true)
}
}
source := rand.NewSource(seed)
// math/rand is good enough in this case
/* #nosec G404 */
rng := rand.New(source)
img, err := t.image(w, t, bp.Customizations, options, staticPackageSets, containerSources, rng)
if err != nil {
return nil, nil, err
}
mf := manifest.New()
switch t.Arch().Distro().Releasever() {
case "7":
mf.Distro = manifest.DISTRO_EL7
case "8":
mf.Distro = manifest.DISTRO_EL8
case "9":
mf.Distro = manifest.DISTRO_EL9
case "10":
mf.Distro = manifest.DISTRO_EL10
default:
return nil, nil, fmt.Errorf("unsupported distro release version: %s", t.Arch().Distro().Releasever())
}
if options.UseBootstrapContainer {
mf.DistroBootstrapRef = bootstrapContainerFor(t)
}
_, err = img.InstantiateManifest(&mf, repos, t.arch.distro.runner, rng)
if err != nil {
return nil, nil, err
}
return &mf, warnings, err
}
// checkOptions checks the validity and compatibility of options and customizations for the image type.
// Returns ([]string, error) where []string, if non-nil, will hold any generated warnings (e.g. deprecation notices).
func (t *ImageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
if !t.RPMOSTree && options.OSTree != nil {
return nil, fmt.Errorf("OSTree is not supported for %q", t.Name())
}
if t.arch.distro.CheckOptions != nil {
return t.arch.distro.CheckOptions(t, bp, options)
}
return nil, nil
}
func NewImageType(
name, filename, mimeType string,
pkgSets PackageSetFunc,
imgFunc ImageFunc,
buildPipelines, payloadPipelines, exports []string,
) *ImageType {
return &ImageType{
name: name,
filename: filename,
mimeType: mimeType,
packageSets: pkgSets,
image: imgFunc,
buildPipelines: buildPipelines,
payloadPipelines: payloadPipelines,
exports: exports,
}
}
// XXX: this will become part of the yaml distro definitions, i.e.
// the yaml will have a "bootstrap_ref" key for each distro/arch
func bootstrapContainerFor(t *ImageType) string {
distro := t.arch.distro
if distro.IsRHEL() {
return fmt.Sprintf("registry.access.redhat.com/ubi%s/ubi:latest", distro.Releasever())
} else {
// we need the toolbox container because stock centos has
// e.g. no mount util
return "quay.io/toolbx-images/centos-toolbox:stream" + distro.Releasever()
}
}

View file

@ -1,130 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkAmiImgTypeX86_64(d *rhel.Distribution) *rhel.ImageType {
it := rhel.NewImageType(
"ami",
"image.raw",
"application/octet-stream",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image"},
[]string{"image"},
)
it.DefaultImageConfig = imageConfig(d, "x86_64", "ami")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkEc2ImgTypeX86_64(rd *rhel.Distribution) *rhel.ImageType {
it := rhel.NewImageType(
"ec2",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, "x86_64", "ec2")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkEc2HaImgTypeX86_64(rd *rhel.Distribution) *rhel.ImageType {
it := rhel.NewImageType(
"ec2-ha",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, "x86_64", "ec2-ha")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkAmiImgTypeAarch64(rd *rhel.Distribution) *rhel.ImageType {
it := rhel.NewImageType(
"ami",
"image.raw",
"application/octet-stream",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image"},
[]string{"image"},
)
it.DefaultImageConfig = imageConfig(rd, "aarch64", "ami")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkEc2ImgTypeAarch64(rd *rhel.Distribution) *rhel.ImageType {
it := rhel.NewImageType(
"ec2",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, "aarch64", "ec2")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkEc2SapImgTypeX86_64(rd *rhel.Distribution) *rhel.ImageType {
it := rhel.NewImageType(
"ec2-sap",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, "x86_64", "ec2-sap")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}

View file

@ -1,111 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkAzureRhuiImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-rhui",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-rhui")
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkAzureSapRhuiImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-sap-rhui",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-sap-rhui")
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkAzureByosImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"vhd",
"disk.vhd",
"application/x-vhd",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc"},
[]string{"vpc"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "vhd")
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
// Azure non-RHEL image type
func mkAzureImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"vhd",
"disk.vhd",
"application/x-vhd",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc"},
[]string{"vpc"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "vhd")
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkAzureEap7RhuiImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-eap7-rhui",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-eap7-rhui")
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}

View file

@ -1,48 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkImageInstaller(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"image-installer",
"installer.iso",
"application/x-iso9660-image",
packageSetLoader,
rhel.ImageInstallerImage,
[]string{"build"},
[]string{"anaconda-tree", "rootfs-image", "efiboot-tree", "os", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.BootISO = true
it.Bootable = true
it.ISOLabelFn = distroISOLabelFunc
it.DefaultImageConfig = imageConfig(rd, a.String(), "image-installer")
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"ifcfg",
},
}
return it
}
func mkTarImgType() *rhel.ImageType {
it := rhel.NewImageType(
"tar",
"root.tar.xz",
"application/x-tar",
packageSetLoader,
rhel.TarImage,
[]string{"build"},
[]string{"os", "archive"},
[]string{"archive"},
)
return it
}

View file

@ -1,455 +0,0 @@
package rhel8
import (
"fmt"
"strings"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/platform"
)
var (
// rhel8 allow all
oscapProfileAllowList = []oscap.Profile{
oscap.AnssiBp28Enhanced,
oscap.AnssiBp28High,
oscap.AnssiBp28Intermediary,
oscap.AnssiBp28Minimal,
oscap.Cis,
oscap.CisServerL1,
oscap.CisWorkstationL1,
oscap.CisWorkstationL2,
oscap.Cui,
oscap.E8,
oscap.Hippa,
oscap.IsmO,
oscap.Ospp,
oscap.PciDss,
oscap.Stig,
oscap.StigGui,
}
)
// RHEL-based OS image configuration defaults
func defaultDistroImageConfig(d *rhel.Distribution) *distro.ImageConfig {
return common.Must(defs.DistroImageConfig(d.Name()))
}
func distroISOLabelFunc(t *rhel.ImageType) string {
const RHEL_ISO_LABEL = "RHEL-%s-%s-0-BaseOS-%s"
const CS_ISO_LABEL = "CentOS-Stream-%s-%s-dvd"
const ALMALINUX_ISO_LABEL = "AlmaLinux-%s-%s-%s-dvd"
if t.IsRHEL() {
osVer := strings.Split(t.Arch().Distro().OsVersion(), ".")
return fmt.Sprintf(RHEL_ISO_LABEL, osVer[0], osVer[1], t.Arch().Name())
} else if t.IsAlmaLinux() {
osVer := strings.Split(t.Arch().Distro().OsVersion(), ".")
return fmt.Sprintf(ALMALINUX_ISO_LABEL, osVer[0], osVer[1], t.Arch().Name())
} else {
return fmt.Sprintf(CS_ISO_LABEL, t.Arch().Distro().Releasever(), t.Arch().Name())
}
}
func newDistro(name string, minor int) *rhel.Distribution {
rd, err := rhel.NewDistribution(name, 8, minor)
if err != nil {
panic(err)
}
rd.CheckOptions = checkOptions
rd.DefaultImageConfig = defaultDistroImageConfig
// Architecture definitions
x86_64 := rhel.NewArchitecture(rd, arch.ARCH_X86_64)
aarch64 := rhel.NewArchitecture(rd, arch.ARCH_AARCH64)
ppc64le := rhel.NewArchitecture(rd, arch.ARCH_PPC64LE)
s390x := rhel.NewArchitecture(rd, arch.ARCH_S390X)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "0.10",
},
},
mkQcow2ImgType(rd, arch.ARCH_X86_64),
mkOCIImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
},
},
mkOpenstackImgType(rd, arch.ARCH_X86_64),
)
ec2X86Platform := &platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
}
// Keep the RHEL EC2 x86_64 images before 8.9 BIOS-only for backward compatibility.
// RHEL-internal EC2 images and RHEL AMI images are kept intentionally in sync
// with regard to not supporting hybrid boot mode before RHEL version 8.9.
// The partitioning table for these reflects that and is also intentionally in sync.
if rd.IsRHEL() && common.VersionLessThan(rd.OsVersion(), "8.9") {
ec2X86Platform.UEFIVendor = ""
}
x86_64.AddImageTypes(
ec2X86Platform,
mkAmiImgTypeX86_64(rd),
)
bareMetalX86Platform := &platform.X86{
BasePlatform: platform.BasePlatform{
FirmwarePackages: []string{
"microcode_ctl", // ??
"iwl1000-firmware",
"iwl100-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6050-firmware",
},
},
BIOS: true,
UEFIVendor: rd.Vendor(),
}
x86_64.AddImageTypes(
bareMetalX86Platform,
mkEdgeOCIImgType(rd, arch.ARCH_X86_64),
mkEdgeCommitImgType(rd, arch.ARCH_X86_64),
mkEdgeInstallerImgType(rd, arch.ARCH_X86_64),
mkImageInstaller(rd, arch.ARCH_X86_64),
)
gceX86Platform := &platform.X86{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_GCE,
},
}
x86_64.AddImageTypes(
gceX86Platform,
mkGceImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VMDK,
},
},
mkVmdkImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_OVA,
},
},
mkOvaImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{},
mkTarImgType(),
mkWslImgType(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "0.10",
},
},
mkQcow2ImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
},
},
mkOpenstackImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
&platform.Aarch64{},
mkTarImgType(),
mkWslImgType(rd, arch.ARCH_AARCH64),
)
bareMetalAarch64Platform := &platform.Aarch64{
BasePlatform: platform.BasePlatform{},
UEFIVendor: rd.Vendor(),
}
aarch64.AddImageTypes(
bareMetalAarch64Platform,
mkEdgeOCIImgType(rd, arch.ARCH_AARCH64),
mkEdgeCommitImgType(rd, arch.ARCH_AARCH64),
mkEdgeInstallerImgType(rd, arch.ARCH_AARCH64),
mkImageInstaller(rd, arch.ARCH_AARCH64),
)
rawAarch64Platform := &platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
}
aarch64.AddImageTypes(
rawAarch64Platform,
mkAmiImgTypeAarch64(rd),
mkMinimalRawImgType(rd, arch.ARCH_AARCH64),
)
ppc64le.AddImageTypes(
&platform.PPC64LE{
BIOS: true,
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "0.10",
},
},
mkQcow2ImgType(rd, arch.ARCH_PPC64LE),
)
ppc64le.AddImageTypes(
&platform.PPC64LE{},
mkTarImgType(),
)
s390x.AddImageTypes(
&platform.S390X{
Zipl: true,
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "0.10",
},
},
mkQcow2ImgType(rd, arch.ARCH_S390X),
)
s390x.AddImageTypes(
&platform.S390X{},
mkTarImgType(),
)
azureX64Platform := &platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VHD,
},
}
azureAarch64Platform := &platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VHD,
},
}
rawUEFIx86Platform := &platform.X86{
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
BIOS: false,
UEFIVendor: rd.Vendor(),
}
x86_64.AddImageTypes(
rawUEFIx86Platform,
mkMinimalRawImgType(rd, arch.ARCH_X86_64),
)
// XXX: note that this is reduandant and the else part can be dropped,
// we have only rhel8 based images, no centos or others
if rd.IsRHEL() {
if common.VersionGreaterThanOrEqual(rd.OsVersion(), "8.6") {
// image types only available on 8.6 and later on RHEL
// These edge image types require FDO which aren't available on older versions
x86_64.AddImageTypes(
bareMetalX86Platform,
mkEdgeRawImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
rawUEFIx86Platform,
mkEdgeSimplifiedInstallerImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
azureX64Platform,
mkAzureEap7RhuiImgType(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
rawAarch64Platform,
mkEdgeRawImgType(rd, arch.ARCH_AARCH64),
mkEdgeSimplifiedInstallerImgType(rd, arch.ARCH_AARCH64),
)
// The Azure image types require hyperv-daemons which isn't available on older versions
aarch64.AddImageTypes(
azureAarch64Platform,
mkAzureRhuiImgType(rd, arch.ARCH_AARCH64),
mkAzureByosImgType(rd, arch.ARCH_AARCH64),
)
}
// add azure to RHEL distro only
x86_64.AddImageTypes(
azureX64Platform,
mkAzureRhuiImgType(rd, arch.ARCH_X86_64),
mkAzureByosImgType(rd, arch.ARCH_X86_64),
mkAzureSapRhuiImgType(rd, arch.ARCH_X86_64),
)
// add ec2 image types to RHEL distro only
x86_64.AddImageTypes(
ec2X86Platform,
mkEc2ImgTypeX86_64(rd),
mkEc2HaImgTypeX86_64(rd),
)
aarch64.AddImageTypes(
rawAarch64Platform,
mkEc2ImgTypeAarch64(rd),
)
if rd.OsVersion() != "8.5" {
// NOTE: RHEL 8.5 is going away and these image types require some
// work to get working, so we just disable them here until the
// whole distro gets deleted
x86_64.AddImageTypes(
ec2X86Platform,
mkEc2SapImgTypeX86_64(rd),
)
}
// add GCE RHUI image to RHEL only
x86_64.AddImageTypes(
gceX86Platform,
mkGceRhuiImgType(rd, arch.ARCH_X86_64),
)
// add s390x to RHEL distro only
rd.AddArches(s390x)
} else {
x86_64.AddImageTypes(
bareMetalX86Platform,
mkEdgeRawImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
rawUEFIx86Platform,
mkEdgeSimplifiedInstallerImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
azureX64Platform,
mkAzureImgType(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
rawAarch64Platform,
mkEdgeRawImgType(rd, arch.ARCH_AARCH64),
mkEdgeSimplifiedInstallerImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
azureAarch64Platform,
mkAzureImgType(rd, arch.ARCH_AARCH64),
)
}
rd.AddArches(x86_64, aarch64, ppc64le)
return rd
}
func ParseID(idStr string) (*distro.ID, error) {
id, err := distro.ParseID(idStr)
if err != nil {
return nil, err
}
if id.Name != "rhel" && id.Name != "centos" && id.Name != "almalinux" {
return nil, fmt.Errorf("invalid distro name: %s", id.Name)
}
// Backward compatibility layer for "rhel-84" or "rhel-810"
if id.Name == "rhel" && id.MinorVersion == -1 {
if id.MajorVersion/10 == 8 {
// handle single digit minor version
id.MinorVersion = id.MajorVersion % 10
id.MajorVersion = 8
} else if id.MajorVersion/100 == 8 {
// handle two digit minor version
id.MinorVersion = id.MajorVersion % 100
id.MajorVersion = 8
}
}
if id.MajorVersion != 8 {
return nil, fmt.Errorf("invalid distro major version: %d", id.MajorVersion)
}
// CentOS does not use minor version
if id.Name == "centos" && id.MinorVersion != -1 {
return nil, fmt.Errorf("centos does not use minor version, but got: %d", id.MinorVersion)
}
// RHEL uses minor version
if id.Name == "rhel" && id.MinorVersion == -1 {
return nil, fmt.Errorf("rhel requires minor version, but got: %d", id.MinorVersion)
}
// So does AlmaLinux
if id.Name == "almalinux" && id.MinorVersion == -1 {
return nil, fmt.Errorf("almalinux requires minor version, but got: %d", id.MinorVersion)
}
return id, nil
}
func DistroFactory(idStr string) distro.Distro {
id, err := ParseID(idStr)
if err != nil {
return nil
}
return newDistro(id.Name, id.MinorVersion)
}

View file

@ -1,155 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkEdgeCommitImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-commit",
"commit.tar",
"application/x-tar",
packageSetLoader,
rhel.EdgeCommitImage,
[]string{"build"},
[]string{"os", "ostree-commit", "commit-archive"},
[]string{"commit-archive"},
)
it.NameAliases = []string{"rhel-edge-commit"}
it.DefaultImageConfig = imageConfig(rd, a.String(), "edge-commit")
it.RPMOSTree = true
return it
}
func mkEdgeOCIImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-container",
"container.tar",
"application/x-tar",
packageSetLoader,
rhel.EdgeContainerImage,
[]string{"build"},
[]string{"os", "ostree-commit", "container-tree", "container"},
[]string{"container"},
)
it.NameAliases = []string{"rhel-edge-container"}
it.DefaultImageConfig = imageConfig(rd, a.String(), "edge-container")
it.RPMOSTree = true
return it
}
func mkEdgeRawImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-raw-image",
"image.raw.xz",
"application/xz",
nil,
rhel.EdgeRawImage,
[]string{"build"},
[]string{"ostree-deployment", "image", "xz"},
[]string{"xz"},
)
it.NameAliases = []string{"rhel-edge-raw-image"}
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, a.String(), "edge-raw-image")
it.DefaultSize = 10 * datasizes.GibiByte
it.RPMOSTree = true
it.Bootable = true
it.BasePartitionTables = partitionTables
it.UnsupportedPartitioningModes = []disk.PartitioningMode{
disk.AutoLVMPartitioningMode,
disk.LVMPartitioningMode,
}
return it
}
func mkEdgeInstallerImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-installer",
"installer.iso",
"application/x-iso9660-image",
packageSetLoader,
rhel.EdgeInstallerImage,
[]string{"build"},
[]string{"anaconda-tree", "rootfs-image", "efiboot-tree", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.NameAliases = []string{"rhel-edge-installer"}
it.DefaultImageConfig = imageConfig(rd, a.String(), "edge-installer")
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"ifcfg",
},
}
it.RPMOSTree = true
it.BootISO = true
it.ISOLabelFn = distroISOLabelFunc
return it
}
func mkEdgeSimplifiedInstallerImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-simplified-installer",
"simplified-installer.iso",
"application/x-iso9660-image",
packageSetLoader,
rhel.EdgeSimplifiedInstallerImage,
[]string{"build"},
[]string{"ostree-deployment", "image", "xz", "coi-tree", "efiboot-tree", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.NameAliases = []string{"rhel-edge-simplified-installer"}
it.DefaultImageConfig = imageConfig(rd, a.String(), "edge-simplified-installer")
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"prefixdevname",
"prefixdevname-tools",
},
}
it.DefaultSize = 10 * datasizes.GibiByte
it.RPMOSTree = true
it.Bootable = true
it.BootISO = true
it.ISOLabelFn = distroISOLabelFunc
it.BasePartitionTables = partitionTables
it.UnsupportedPartitioningModes = []disk.PartitioningMode{
disk.AutoLVMPartitioningMode,
disk.LVMPartitioningMode,
}
return it
}
func mkMinimalRawImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"minimal-raw",
"disk.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(rd, a.String(), "minimal-raw")
it.Bootable = true
it.DefaultSize = 2 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}

View file

@ -1,49 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkGceImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"gce",
"image.tar.gz",
"application/gzip",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "archive"},
[]string{"archive"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "gce")
it.Bootable = true
it.DefaultSize = 20 * datasizes.GibiByte
// TODO: the base partition table still contains the BIOS boot partition, but the image is UEFI-only
it.BasePartitionTables = partitionTables
return it
}
func mkGceRhuiImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"gce-rhui",
"image.tar.gz",
"application/gzip",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "archive"},
[]string{"archive"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "gce-rhui")
it.Bootable = true
it.DefaultSize = 20 * datasizes.GibiByte
// TODO: the base partition table still contains the BIOS boot partition, but the image is UEFI-only
it.BasePartitionTables = partitionTables
return it
}

View file

@ -1,207 +0,0 @@
package rhel8
import (
"fmt"
"strings"
"slices"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/policies"
)
// checkOptions checks the validity and compatibility of options and customizations for the image type.
// Returns ([]string, error) where []string, if non-nil, will hold any generated warnings (e.g. deprecation notices).
func checkOptions(t *rhel.ImageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
// holds warnings (e.g. deprecation notices)
var warnings []string
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.RPMOSTree && (t.Name() != "edge-commit" && t.Name() != "edge-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.Arch().Distro().Name())
}
if options.OSTree != nil {
if err := options.OSTree.Validate(); err != nil {
return warnings, err
}
}
if t.BootISO && t.RPMOSTree {
// ostree-based ISOs require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.Name())
}
if t.Name() == "edge-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO", "User", "Group", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.Name())
}
//making fdo optional so that simplified installer can be composed w/o the FDO section in the blueprint
if customizations.GetFDO() != nil {
if customizations.GetFDO().ManufacturingServerURL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.Name())
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.Name())
}
}
} else if t.Name() == "edge-installer" {
allowed := []string{"User", "Group", "FIPS", "Installer", "Timezone", "Locale"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
}
}
if t.Name() == "edge-raw-image" {
// ostree-based bootable images require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("%q images require specifying a URL from which to retrieve the OSTree commit", t.Name())
}
allowed := []string{"User", "Group", "FIPS"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
// TODO: consider additional checks, such as those in "edge-simplified-installer"
}
if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.RPMOSTree && t.Name() != "edge-raw-image" && t.Name() != "edge-simplified-installer" {
return warnings, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
if slices.Contains(t.UnsupportedPartitioningModes, options.PartitioningMode) {
return warnings, fmt.Errorf("partitioning mode %q is not supported for %q", options.PartitioningMode, t.Name())
}
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if partitioning != nil {
for _, partition := range partitioning.Partitions {
if t.Arch().Name() == arch.ARCH_AARCH64.String() {
if partition.FSType == "swap" {
return warnings, fmt.Errorf("swap partition creation is not supported on %s %s", t.Arch().Distro().Name(), t.Arch().Name())
}
for _, lv := range partition.LogicalVolumes {
if lv.FSType == "swap" {
return warnings, fmt.Errorf("swap partition creation is not supported on %s %s", t.Arch().Distro().Name(), t.Arch().Name())
}
}
}
}
}
if mountpoints != nil && t.RPMOSTree {
return warnings, fmt.Errorf("custom mountpoints are not supported for ostree types")
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
if t.Arch().Distro().OsVersion() == "9.0" {
return warnings, fmt.Errorf("OpenSCAP unsupported os version: %s", t.Arch().Distro().OsVersion())
}
if !oscap.IsProfileAllowed(osc.ProfileID, oscapProfileAllowList) {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if t.RPMOSTree {
return warnings, fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
w := fmt.Sprintln(common.FIPSEnabledImageWarning)
warnings = append(warnings, w)
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if slices.Index([]string{"image-installer", "edge-installer", "live-installer"}, t.Name()) == -1 {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
if t.Name() == "edge-installer" &&
instCust.Kickstart != nil &&
len(instCust.Kickstart.Contents) > 0 &&
(customizations.GetUsers() != nil || customizations.GetGroups() != nil) {
return warnings, fmt.Errorf("edge-installer installer.kickstart.contents are not supported in combination with users or groups")
}
}
return warnings, nil
}

View file

@ -1,19 +0,0 @@
package rhel8
// This file defines package sets that are used by more than one image type.
import (
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/rpmmd"
)
func packageSetLoader(t *rhel.ImageType) (map[string]rpmmd.PackageSet, error) {
return defs.PackageSets(t)
}
func imageConfig(d *rhel.Distribution, archName, imageType string) *distro.ImageConfig {
return common.Must(defs.ImageConfig(d.Name(), archName, imageType))
}

View file

@ -1,23 +0,0 @@
package rhel8
import (
"errors"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/distro/rhel"
)
func partitionTables(t *rhel.ImageType) (disk.PartitionTable, bool) {
partitionTable, err := defs.PartitionTable(t)
if errors.Is(err, defs.ErrNoPartitionTableForImgType) {
return disk.PartitionTable{}, false
}
if err != nil {
panic(err)
}
if partitionTable == nil {
return disk.PartitionTable{}, false
}
return *partitionTable, true
}

View file

@ -1,66 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkQcow2ImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"qcow2",
"disk.qcow2",
"application/x-qemu-disk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "qcow2"},
[]string{"qcow2"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "qcow2")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkOCIImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"oci",
"disk.qcow2",
"application/x-qemu-disk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "qcow2"},
[]string{"qcow2"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "oci")
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkOpenstackImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"openstack",
"disk.qcow2",
"application/x-qemu-disk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "qcow2"},
[]string{"qcow2"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "openstack")
it.DefaultSize = 4 * datasizes.GibiByte
it.Bootable = true
it.BasePartitionTables = partitionTables
return it
}

View file

@ -1,45 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkVmdkImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"vmdk",
"disk.vmdk",
"application/x-vmdk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vmdk"},
[]string{"vmdk"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "vmdk")
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}
func mkOvaImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ova",
"image.ova",
"application/ovf",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vmdk", "ovf", "archive"},
[]string{"archive"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "ova")
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.BasePartitionTables = partitionTables
return it
}

View file

@ -1,23 +0,0 @@
package rhel8
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkWslImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"wsl",
"image.wsl",
"application/x-tar",
packageSetLoader,
rhel.TarImage,
[]string{"build"},
[]string{"os", "archive", "xz"},
[]string{"xz"},
)
it.DefaultImageConfig = imageConfig(rd, a.String(), "wsl")
it.Compression = "xz"
return it
}

View file

@ -1,130 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkEc2ImgTypeX86_64(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ec2",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(d, a.String(), "ec2")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkAMIImgTypeX86_64(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ami",
"image.raw",
"application/octet-stream",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image"},
[]string{"image"},
)
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(d, a.String(), "ami")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkEC2SapImgTypeX86_64(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ec2-sap",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(d, a.String(), "ec2-sap")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkEc2HaImgTypeX86_64(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ec2-ha",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(d, a.String(), "ec2-ha")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkAMIImgTypeAarch64(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ami",
"image.raw",
"application/octet-stream",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image"},
[]string{"image"},
)
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(d, a.String(), "ami")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkEC2ImgTypeAarch64(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ec2",
"image.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 10 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(d, a.String(), "ec2")
it.BasePartitionTables = defaultBasePartitionTables
return it
}

View file

@ -1,115 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
// Azure image type
func mkAzureImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"vhd",
"disk.vhd",
"application/x-vhd",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc"},
[]string{"vpc"},
)
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(rd, a.String(), "vhd")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
// Azure RHEL-internal image type
func mkAzureInternalImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-rhui",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-rhui")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkAzureSapInternalImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-sap-rhui",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-sap-rhui")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkAzureSapAppsImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-sapapps-rhui",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 64 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-sapapps-rhui")
it.BasePartitionTables = defaultBasePartitionTables
return it
}
// Azure Confidential VM
func mkAzureCVMImgType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"azure-cvm",
"disk.vhd.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vpc", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.Bootable = true
it.DefaultSize = 32 * datasizes.GibiByte
it.DefaultImageConfig = imageConfig(rd, a.String(), "azure-cvm")
it.BasePartitionTables = defaultBasePartitionTables
return it
}

View file

@ -1,52 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkTarImgType() *rhel.ImageType {
return rhel.NewImageType(
"tar",
"root.tar.xz",
"application/x-tar",
packageSetLoader,
rhel.TarImage,
[]string{"build"},
[]string{"os", "archive"},
[]string{"archive"},
)
}
func mkImageInstallerImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"image-installer",
"installer.iso",
"application/x-iso9660-image",
packageSetLoader,
rhel.ImageInstallerImage,
[]string{"build"},
[]string{"anaconda-tree", "rootfs-image", "efiboot-tree", "os", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.BootISO = true
it.Bootable = true
it.ISOLabelFn = distroISOLabelFunc
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"nvdimm", // non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)
"ifcfg",
},
AdditionalDrivers: []string{
"cuse",
"ipmi_devintf",
"ipmi_msghandler",
},
}
it.DefaultImageConfig = imageConfig(d, a.String(), "image-installer")
return it
}

View file

@ -1,427 +0,0 @@
package rhel9
import (
"fmt"
"strings"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/platform"
)
var (
// rhel9 & cs9 share the same list
// of allowed profiles so a single
// allow list can be used
oscapProfileAllowList = []oscap.Profile{
oscap.AnssiBp28Enhanced,
oscap.AnssiBp28High,
oscap.AnssiBp28Intermediary,
oscap.AnssiBp28Minimal,
oscap.CcnAdvanced,
oscap.CcnBasic,
oscap.CcnIntermediate,
oscap.Cis,
oscap.CisServerL1,
oscap.CisWorkstationL1,
oscap.CisWorkstationL2,
oscap.Cui,
oscap.E8,
oscap.Hippa,
oscap.IsmO,
oscap.Ospp,
oscap.PciDss,
oscap.Stig,
oscap.StigGui,
}
)
func distroISOLabelFunc(t *rhel.ImageType) string {
const RHEL_ISO_LABEL = "RHEL-%s-%s-0-BaseOS-%s"
const CS_ISO_LABEL = "CentOS-Stream-%s-BaseOS-%s"
const ALMALINUX_ISO_LABEL = "AlmaLinux-%s-%s-%s-dvd"
if t.IsRHEL() {
osVer := strings.Split(t.Arch().Distro().OsVersion(), ".")
return fmt.Sprintf(RHEL_ISO_LABEL, osVer[0], osVer[1], t.Arch().Name())
} else if t.IsAlmaLinux() {
osVer := strings.Split(t.Arch().Distro().OsVersion(), ".")
return fmt.Sprintf(ALMALINUX_ISO_LABEL, osVer[0], osVer[1], t.Arch().Name())
} else {
return fmt.Sprintf(CS_ISO_LABEL, t.Arch().Distro().Releasever(), t.Arch().Name())
}
}
func defaultDistroImageConfig(d *rhel.Distribution) *distro.ImageConfig {
return common.Must(defs.DistroImageConfig(d.Name()))
}
func newDistro(name string, major, minor int) *rhel.Distribution {
rd, err := rhel.NewDistribution(name, major, minor)
if err != nil {
panic(err)
}
rd.CheckOptions = checkOptions
rd.DefaultImageConfig = defaultDistroImageConfig
// Architecture definitions
x86_64 := rhel.NewArchitecture(rd, arch.ARCH_X86_64)
aarch64 := rhel.NewArchitecture(rd, arch.ARCH_AARCH64)
ppc64le := rhel.NewArchitecture(rd, arch.ARCH_PPC64LE)
s390x := rhel.NewArchitecture(rd, arch.ARCH_S390X)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "1.1",
},
},
mkQcow2ImgType(rd, arch.ARCH_X86_64),
mkOCIImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
},
},
mkOpenstackImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VMDK,
},
},
mkVMDKImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_OVA,
},
},
mkOVAImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{},
mkTarImgType(),
mkWSLImgType(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
},
},
mkOpenstackImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
&platform.Aarch64{},
mkTarImgType(),
mkWSLImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "1.1",
},
},
mkQcow2ImgType(rd, arch.ARCH_AARCH64),
)
ppc64le.AddImageTypes(
&platform.PPC64LE{
BIOS: true,
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "1.1",
},
},
mkQcow2ImgType(rd, arch.ARCH_PPC64LE),
)
ppc64le.AddImageTypes(
&platform.PPC64LE{},
mkTarImgType(),
)
s390x.AddImageTypes(
&platform.S390X{
Zipl: true,
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_QCOW2,
QCOW2Compat: "1.1",
},
},
mkQcow2ImgType(rd, arch.ARCH_S390X),
)
s390x.AddImageTypes(
&platform.S390X{},
mkTarImgType(),
)
ec2X86Platform := &platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
}
// Keep the RHEL EC2 x86_64 images before 9.3 BIOS-only for backward compatibility.
// RHEL-internal EC2 images and RHEL AMI images are kept intentionally in sync
// with regard to not supporting hybrid boot mode before RHEL version 9.3.
// The partitioning table for these reflects that and is also intentionally in sync.
if rd.IsRHEL() && common.VersionLessThan(rd.OsVersion(), "9.3") {
ec2X86Platform.UEFIVendor = ""
}
x86_64.AddImageTypes(
ec2X86Platform,
mkAMIImgTypeX86_64(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
},
mkAMIImgTypeAarch64(rd, arch.ARCH_AARCH64),
)
azureX64Platform := &platform.X86{
BIOS: true,
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VHD,
},
}
azureAarch64Platform := &platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VHD,
},
}
x86_64.AddImageTypes(azureX64Platform, mkAzureImgType(rd, azureX64Platform.GetArch()))
aarch64.AddImageTypes(azureAarch64Platform, mkAzureImgType(rd, azureAarch64Platform.GetArch()))
gceX86Platform := &platform.X86{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_GCE,
},
}
x86_64.AddImageTypes(
gceX86Platform,
mkGCEImageType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BasePlatform: platform.BasePlatform{
FirmwarePackages: []string{
"microcode_ctl", // ??
"iwl1000-firmware",
"iwl100-firmware",
"iwl105-firmware",
"iwl135-firmware",
"iwl2000-firmware",
"iwl2030-firmware",
"iwl3160-firmware",
"iwl5000-firmware",
"iwl5150-firmware",
"iwl6050-firmware",
},
},
BIOS: true,
UEFIVendor: rd.Vendor(),
},
mkEdgeOCIImgType(rd, arch.ARCH_X86_64),
mkEdgeCommitImgType(rd, arch.ARCH_X86_64),
mkEdgeInstallerImgType(rd, arch.ARCH_X86_64),
mkEdgeRawImgType(rd, arch.ARCH_X86_64),
mkImageInstallerImgType(rd, arch.ARCH_X86_64),
mkEdgeAMIImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VMDK,
},
BIOS: true,
UEFIVendor: rd.Vendor(),
},
mkEdgeVsphereImgType(rd, arch.ARCH_X86_64),
)
x86_64.AddImageTypes(
&platform.X86{
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
BIOS: false,
UEFIVendor: rd.Vendor(),
},
mkEdgeSimplifiedInstallerImgType(rd, arch.ARCH_X86_64),
mkMinimalrawImgType(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
BasePlatform: platform.BasePlatform{},
UEFIVendor: rd.Vendor(),
},
mkEdgeOCIImgType(rd, arch.ARCH_AARCH64),
mkEdgeCommitImgType(rd, arch.ARCH_AARCH64),
mkEdgeInstallerImgType(rd, arch.ARCH_AARCH64),
mkEdgeSimplifiedInstallerImgType(rd, arch.ARCH_AARCH64),
mkImageInstallerImgType(rd, arch.ARCH_AARCH64),
mkEdgeAMIImgType(rd, arch.ARCH_AARCH64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VMDK,
},
UEFIVendor: rd.Vendor(),
},
mkEdgeVsphereImgType(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
UEFIVendor: rd.Vendor(),
},
mkEdgeRawImgType(rd, arch.ARCH_AARCH64),
mkMinimalrawImgType(rd, arch.ARCH_AARCH64),
)
if rd.IsRHEL() { // RHEL-only (non-CentOS) image types
x86_64.AddImageTypes(azureX64Platform, mkAzureInternalImgType(rd, azureX64Platform.GetArch()))
aarch64.AddImageTypes(azureAarch64Platform, mkAzureInternalImgType(rd, azureAarch64Platform.GetArch()))
x86_64.AddImageTypes(azureX64Platform, mkAzureSapInternalImgType(rd, azureX64Platform.GetArch()), mkAzureSapAppsImgType(rd, azureX64Platform.GetArch()))
// add ec2 image types to RHEL distro only
x86_64.AddImageTypes(ec2X86Platform,
mkEc2ImgTypeX86_64(rd, arch.ARCH_X86_64),
mkEc2HaImgTypeX86_64(rd, arch.ARCH_X86_64),
mkEC2SapImgTypeX86_64(rd, arch.ARCH_X86_64),
)
aarch64.AddImageTypes(
&platform.Aarch64{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_RAW,
},
},
mkEC2ImgTypeAarch64(rd, arch.ARCH_AARCH64),
)
// CVM is only available starting from 9.6
if common.VersionGreaterThanOrEqual(rd.OsVersion(), "9.6") {
azureX64CVMPlatform := &platform.X86{
UEFIVendor: rd.Vendor(),
BasePlatform: platform.BasePlatform{
ImageFormat: platform.FORMAT_VHD,
},
Bootloader: platform.BOOTLOADER_UKI,
}
x86_64.AddImageTypes(
azureX64CVMPlatform,
mkAzureCVMImgType(rd, arch.ARCH_X86_64),
)
}
}
rd.AddArches(x86_64, aarch64, ppc64le, s390x)
return rd
}
func ParseID(idStr string) (*distro.ID, error) {
id, err := distro.ParseID(idStr)
if err != nil {
return nil, err
}
if id.Name != "rhel" && id.Name != "centos" && id.Name != "almalinux" {
return nil, fmt.Errorf("invalid distro name: %s", id.Name)
}
// Backward compatibility layer for "rhel-93" or "rhel-910"
if id.Name == "rhel" && id.MinorVersion == -1 {
if id.MajorVersion/10 == 9 {
// handle single digit minor version
id.MinorVersion = id.MajorVersion % 10
id.MajorVersion = 9
} else if id.MajorVersion/100 == 9 {
// handle two digit minor version
id.MinorVersion = id.MajorVersion % 100
id.MajorVersion = 9
}
}
if id.MajorVersion != 9 {
return nil, fmt.Errorf("invalid distro major version: %d", id.MajorVersion)
}
// CentOS does not use minor version
if id.Name == "centos" && id.MinorVersion != -1 {
return nil, fmt.Errorf("centos does not use minor version, but got: %d", id.MinorVersion)
}
// RHEL uses minor version
if id.Name == "rhel" && id.MinorVersion == -1 {
return nil, fmt.Errorf("rhel requires minor version, but got: %d", id.MinorVersion)
}
// So does AlmaLinux
if id.Name == "almalinux" && id.MinorVersion == -1 {
return nil, fmt.Errorf("almalinux requires minor version, but got: %d", id.MinorVersion)
}
return id, nil
}
func DistroFactory(idStr string) distro.Distro {
id, err := ParseID(idStr)
if err != nil {
return nil
}
return newDistro(id.Name, 9, id.MinorVersion)
}

View file

@ -1,212 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/internal/environment"
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkEdgeCommitImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-commit",
"commit.tar",
"application/x-tar",
packageSetLoader,
rhel.EdgeCommitImage,
[]string{"build"},
[]string{"os", "ostree-commit", "commit-archive"},
[]string{"commit-archive"},
)
it.NameAliases = []string{"rhel-edge-commit"}
it.RPMOSTree = true
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-commit")
return it
}
func mkEdgeOCIImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-container",
"container.tar",
"application/x-tar",
packageSetLoader,
rhel.EdgeContainerImage,
[]string{"build"},
[]string{"os", "ostree-commit", "container-tree", "container"},
[]string{"container"},
)
it.NameAliases = []string{"rhel-edge-container"}
it.RPMOSTree = true
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-container")
return it
}
func mkEdgeRawImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-raw-image",
"image.raw.xz",
"application/xz",
nil,
rhel.EdgeRawImage,
[]string{"build"},
[]string{"ostree-deployment", "image", "xz"},
[]string{"xz"},
)
it.NameAliases = []string{"rhel-edge-raw-image"}
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-raw-image")
it.DefaultSize = 10 * datasizes.GibiByte
it.RPMOSTree = true
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
it.UnsupportedPartitioningModes = []disk.PartitioningMode{disk.RawPartitioningMode}
return it
}
func mkEdgeInstallerImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-installer",
"installer.iso",
"application/x-iso9660-image",
packageSetLoader,
rhel.EdgeInstallerImage,
[]string{"build"},
[]string{"anaconda-tree", "rootfs-image", "efiboot-tree", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.NameAliases = []string{"rhel-edge-installer"}
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-installer")
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"nvdimm", // non-volatile DIMM firmware (provides nfit, cuse, and nd_e820)
"ifcfg",
},
AdditionalDrivers: []string{
"cuse",
"ipmi_devintf",
"ipmi_msghandler",
},
}
it.RPMOSTree = true
it.BootISO = true
it.ISOLabelFn = distroISOLabelFunc
return it
}
func mkEdgeSimplifiedInstallerImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-simplified-installer",
"simplified-installer.iso",
"application/x-iso9660-image",
// TODO: non-arch-specific package set handling for installers
// This image type requires build packages for installers and
// ostree/edge. For now we only have x86-64 installer build
// package sets defined. When we add installer build package sets
// for other architectures, this will need to be moved to the
// architecture and the merging will happen in the PackageSets()
// method like the other sets.
packageSetLoader,
rhel.EdgeSimplifiedInstallerImage,
[]string{"build"},
[]string{"ostree-deployment", "image", "xz", "coi-tree", "efiboot-tree", "bootiso-tree", "bootiso"},
[]string{"bootiso"},
)
it.NameAliases = []string{"rhel-edge-simplified-installer"}
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-simplified-installer")
it.DefaultInstallerConfig = &distro.InstallerConfig{
AdditionalDracutModules: []string{
"prefixdevname",
"prefixdevname-tools",
},
}
it.DefaultSize = 10 * datasizes.GibiByte
it.RPMOSTree = true
it.BootISO = true
it.Bootable = true
it.ISOLabelFn = distroISOLabelFunc
it.BasePartitionTables = defaultBasePartitionTables
it.UnsupportedPartitioningModes = []disk.PartitioningMode{disk.RawPartitioningMode}
return it
}
func mkEdgeAMIImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-ami",
"image.raw",
"application/octet-stream",
nil,
rhel.EdgeRawImage,
[]string{"build"},
[]string{"ostree-deployment", "image"},
[]string{"image"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-ami")
it.DefaultSize = 10 * datasizes.GibiByte
it.RPMOSTree = true
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
it.UnsupportedPartitioningModes = []disk.PartitioningMode{disk.RawPartitioningMode}
it.Environment = &environment.EC2{}
return it
}
func mkEdgeVsphereImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"edge-vsphere",
"image.vmdk",
"application/x-vmdk",
nil,
rhel.EdgeRawImage,
[]string{"build"},
[]string{"ostree-deployment", "image", "vmdk"},
[]string{"vmdk"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "edge-vsphere")
it.DefaultSize = 10 * datasizes.GibiByte
it.RPMOSTree = true
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
it.UnsupportedPartitioningModes = []disk.PartitioningMode{disk.RawPartitioningMode}
return it
}
func mkMinimalrawImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"minimal-raw",
"disk.raw.xz",
"application/xz",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(d, a.String(), "minimal-raw")
it.DefaultSize = 2 * datasizes.GibiByte
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
return it
}

View file

@ -1,31 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkGCEImageType(rd *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"gce",
"image.tar.gz",
"application/gzip",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "archive"},
[]string{"archive"},
)
it.NameAliases = []string{"gce-rhui"}
// The configuration for non-RHUI images does not touch the RHSM configuration at all.
// https://issues.redhat.com/browse/COMPOSER-2157
it.DefaultImageConfig = imageConfig(rd, a.String(), "gce")
it.DefaultSize = 20 * datasizes.GibiByte
it.Bootable = true
// TODO: the base partition table still contains the BIOS boot partition, but the image is UEFI-only
it.BasePartitionTables = defaultBasePartitionTables
return it
}

View file

@ -1,222 +0,0 @@
package rhel9
import (
"fmt"
"strings"
"slices"
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/blueprint"
"github.com/osbuild/images/pkg/customizations/oscap"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/policies"
)
// checkOptions checks the validity and compatibility of options and customizations for the image type.
// Returns ([]string, error) where []string, if non-nil, will hold any generated warnings (e.g. deprecation notices).
func checkOptions(t *rhel.ImageType, bp *blueprint.Blueprint, options distro.ImageOptions) ([]string, error) {
customizations := bp.Customizations
// holds warnings (e.g. deprecation notices)
var warnings []string
// we do not support embedding containers on ostree-derived images, only on commits themselves
if len(bp.Containers) > 0 && t.RPMOSTree && (t.Name() != "edge-commit" && t.Name() != "edge-container") {
return warnings, fmt.Errorf("embedding containers is not supported for %s on %s", t.Name(), t.Arch().Distro().Name())
}
if options.OSTree != nil {
if err := options.OSTree.Validate(); err != nil {
return warnings, err
}
}
if t.BootISO && t.RPMOSTree {
// ostree-based ISOs require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying a URL from which to retrieve the OSTree commit", t.Name())
}
if t.Name() == "edge-simplified-installer" {
allowed := []string{"InstallationDevice", "FDO", "Ignition", "Kernel", "User", "Group", "FIPS", "Filesystem"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
if customizations.GetInstallationDevice() == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.Name())
}
// FDO is optional, but when specified has some restrictions
if customizations.GetFDO() != nil {
if customizations.GetFDO().ManufacturingServerURL == "" {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to when using FDO", t.Name())
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return warnings, fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to when using FDO", t.Name())
}
}
// ignition is optional, we might be using FDO
if customizations.GetIgnition() != nil {
if customizations.GetIgnition().Embedded != nil && customizations.GetIgnition().FirstBoot != nil {
return warnings, fmt.Errorf("both ignition embedded and firstboot configurations found")
}
if customizations.GetIgnition().FirstBoot != nil && customizations.GetIgnition().FirstBoot.ProvisioningURL == "" {
return warnings, fmt.Errorf("ignition.firstboot requires a provisioning url")
}
}
} else if t.Name() == "edge-installer" {
allowed := []string{"User", "Group", "FIPS", "Installer", "Timezone", "Locale"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
}
}
if t.Name() == "edge-raw-image" || t.Name() == "edge-ami" || t.Name() == "edge-vsphere" {
// ostree-based bootable images require a URL from which to pull a payload commit
if options.OSTree == nil || options.OSTree.URL == "" {
return warnings, fmt.Errorf("%q images require specifying a URL from which to retrieve the OSTree commit", t.Name())
}
allowed := []string{"Ignition", "Kernel", "User", "Group", "FIPS", "Filesystem"}
if err := customizations.CheckAllowed(allowed...); err != nil {
return warnings, fmt.Errorf(distro.UnsupportedCustomizationError, t.Name(), strings.Join(allowed, ", "))
}
// TODO: consider additional checks, such as those in "edge-simplified-installer"
}
if kernelOpts := customizations.GetKernel(); kernelOpts.Append != "" && t.RPMOSTree && t.Name() != "edge-raw-image" && t.Name() != "edge-simplified-installer" {
return warnings, fmt.Errorf("kernel boot parameter customizations are not supported for ostree types")
}
if slices.Contains(t.UnsupportedPartitioningModes, options.PartitioningMode) {
return warnings, fmt.Errorf("partitioning mode %q is not supported for %q", options.PartitioningMode, t.Name())
}
mountpoints := customizations.GetFilesystems()
partitioning, err := customizations.GetPartitioning()
if err != nil {
return nil, err
}
if (mountpoints != nil || partitioning != nil) && t.RPMOSTree && (t.Name() == "edge-container" || t.Name() == "edge-commit") {
return warnings, fmt.Errorf("custom mountpoints and partitioning are not supported for ostree types")
} else if (mountpoints != nil || partitioning != nil) && t.RPMOSTree && !(t.Name() == "edge-container" || t.Name() == "edge-commit") {
//customization allowed for edge-raw-image,edge-ami,edge-vsphere,edge-simplified-installer
err := blueprint.CheckMountpointsPolicy(mountpoints, policies.OstreeMountpointPolicies)
if err != nil {
return warnings, err
}
}
if len(mountpoints) > 0 && partitioning != nil {
return nil, fmt.Errorf("partitioning customizations cannot be used with custom filesystems (mountpoints)")
}
if err := blueprint.CheckMountpointsPolicy(mountpoints, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := blueprint.CheckDiskMountpointsPolicy(partitioning, policies.MountpointPolicies); err != nil {
return warnings, err
}
if err := partitioning.ValidateLayoutConstraints(); err != nil {
return warnings, err
}
if osc := customizations.GetOpenSCAP(); osc != nil {
if t.Arch().Distro().OsVersion() == "9.0" {
return warnings, fmt.Errorf("OpenSCAP unsupported os version: %s", t.Arch().Distro().OsVersion())
}
if !oscap.IsProfileAllowed(osc.ProfileID, oscapProfileAllowList) {
return warnings, fmt.Errorf("OpenSCAP unsupported profile: %s", osc.ProfileID)
}
if t.RPMOSTree {
return warnings, fmt.Errorf("OpenSCAP customizations are not supported for ostree types")
}
if osc.ProfileID == "" {
return warnings, fmt.Errorf("OpenSCAP profile cannot be empty")
}
}
// Check Directory/File Customizations are valid
dc := customizations.GetDirectories()
fc := customizations.GetFiles()
err = blueprint.ValidateDirFileCustomizations(dc, fc)
if err != nil {
return warnings, err
}
dcp := policies.CustomDirectoriesPolicies
fcp := policies.CustomFilesPolicies
if t.RPMOSTree {
dcp = policies.OstreeCustomDirectoriesPolicies
fcp = policies.OstreeCustomFilesPolicies
}
err = blueprint.CheckDirectoryCustomizationsPolicy(dc, dcp)
if err != nil {
return warnings, err
}
err = blueprint.CheckFileCustomizationsPolicy(fc, fcp)
if err != nil {
return warnings, err
}
// check if repository customizations are valid
_, err = customizations.GetRepositories()
if err != nil {
return warnings, err
}
if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() {
warnings = append(warnings, fmt.Sprintln(common.FIPSEnabledImageWarning))
}
instCust, err := customizations.GetInstaller()
if err != nil {
return warnings, err
}
if instCust != nil {
// only supported by the Anaconda installer
if slices.Index([]string{"image-installer", "edge-installer", "live-installer"}, t.Name()) == -1 {
return warnings, fmt.Errorf("installer customizations are not supported for %q", t.Name())
}
if t.Name() == "edge-installer" &&
instCust.Kickstart != nil &&
len(instCust.Kickstart.Contents) > 0 &&
(customizations.GetUsers() != nil || customizations.GetGroups() != nil) {
return warnings, fmt.Errorf("edge-installer installer.kickstart.contents are not supported in combination with users or groups")
}
}
// don't support setting any kernel customizations for image types with
// UKIs
// NOTE: this is very ugly and stupid, it should not be based on the image
// type name, but we want to redo this whole function anyway
// NOTE: we can't use customizations.GetKernel() because it returns
// 'Name: "kernel"' when unset.
if t.Name() == "azure-cvm" && customizations != nil && customizations.Kernel != nil {
return warnings, fmt.Errorf("kernel customizations are not supported for %q", t.Name())
}
return warnings, nil
}

View file

@ -1,17 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/internal/common"
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/distro/rhel"
"github.com/osbuild/images/pkg/rpmmd"
)
func packageSetLoader(t *rhel.ImageType) (map[string]rpmmd.PackageSet, error) {
return defs.PackageSets(t)
}
func imageConfig(d *rhel.Distribution, archName, imageType string) *distro.ImageConfig {
return common.Must(defs.ImageConfig(d.Name(), archName, imageType))
}

View file

@ -1,19 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/disk"
"github.com/osbuild/images/pkg/distro/defs"
"github.com/osbuild/images/pkg/distro/rhel"
)
func defaultBasePartitionTables(t *rhel.ImageType) (disk.PartitionTable, bool) {
partitionTable, err := defs.PartitionTable(t)
if err != nil {
// XXX: have a check to differenciate ErrNoEnt and else
return disk.PartitionTable{}, false
}
if partitionTable == nil {
return disk.PartitionTable{}, false
}
return *partitionTable, true
}

View file

@ -1,67 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkQcow2ImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"qcow2",
"disk.qcow2",
"application/x-qemu-disk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "qcow2"},
[]string{"qcow2"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "qcow2")
it.DefaultSize = 10 * datasizes.GibiByte
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkOCIImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"oci",
"disk.qcow2",
"application/x-qemu-disk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "qcow2"},
[]string{"qcow2"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "oci")
it.DefaultSize = 10 * datasizes.GibiByte
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkOpenstackImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"openstack",
"disk.qcow2",
"application/x-qemu-disk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "qcow2"},
[]string{"qcow2"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "openstack")
it.DefaultSize = 4 * datasizes.GibiByte
it.Bootable = true
it.BasePartitionTables = defaultBasePartitionTables
return it
}

View file

@ -1,47 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/datasizes"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkVMDKImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"vmdk",
"disk.vmdk",
"application/x-vmdk",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vmdk"},
[]string{"vmdk"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "vmdk")
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.BasePartitionTables = defaultBasePartitionTables
return it
}
func mkOVAImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"ova",
"image.ova",
"application/ovf",
packageSetLoader,
rhel.DiskImage,
[]string{"build"},
[]string{"os", "image", "vmdk", "ovf", "archive"},
[]string{"archive"},
)
it.DefaultImageConfig = imageConfig(d, a.String(), "ova")
it.Bootable = true
it.DefaultSize = 4 * datasizes.GibiByte
it.BasePartitionTables = defaultBasePartitionTables
return it
}

View file

@ -1,24 +0,0 @@
package rhel9
import (
"github.com/osbuild/images/pkg/arch"
"github.com/osbuild/images/pkg/distro/rhel"
)
func mkWSLImgType(d *rhel.Distribution, a arch.Arch) *rhel.ImageType {
it := rhel.NewImageType(
"wsl",
"image.wsl",
"application/x-tar",
packageSetLoader,
rhel.TarImage,
[]string{"build"},
[]string{"os", "archive", "xz"},
[]string{"xz"},
)
it.Compression = "xz"
it.DefaultImageConfig = imageConfig(d, a.String(), "wsl")
return it
}

View file

@ -1,32 +0,0 @@
#!/bin/sh
# /usr/local/sbin/temp-disk-dataloss-warning
# Write dataloss warning file on mounted Azure resource disk
AZURE_RESOURCE_DISK_PART1="/dev/disk/cloud/azure_resource-part1"
MOUNTPATH=$(grep "$AZURE_RESOURCE_DISK_PART1" /etc/fstab | tr '\t' ' ' | cut -d' ' -f2)
if [ -z "$MOUNTPATH" ]; then
echo "There is no mountpoint of $AZURE_RESOURCE_DISK_PART1 in /etc/fstab"
exit 0
fi
if [ "$MOUNTPATH" = "none" ]; then
echo "Mountpoint of $AZURE_RESOURCE_DISK_PART1 is not a path"
exit 1
fi
if ! mountpoint -q "$MOUNTPATH"; then
echo "$AZURE_RESOURCE_DISK_PART1 is not mounted at $MOUNTPATH"
exit 1
fi
echo "Creating a dataloss warning file at ${MOUNTPATH}/DATALOSS_WARNING_README.txt"
cat <<'EOF' > "${MOUNTPATH}/DATALOSS_WARNING_README.txt"
WARNING: THIS IS A TEMPORARY DISK.
Any data stored on this drive is SUBJECT TO LOSS and THERE IS NO WAY TO RECOVER IT.
Please do not use this disk for storing any personal or application data.
EOF

View file

@ -6,8 +6,6 @@ import (
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/generic"
"github.com/osbuild/images/pkg/distro/rhel/rhel8"
"github.com/osbuild/images/pkg/distro/rhel/rhel9"
"github.com/osbuild/images/pkg/distro/test_distro"
)
@ -108,8 +106,6 @@ func New(factories ...FactoryFunc) *Factory {
func NewDefault() *Factory {
return New(
generic.DistroFactory,
rhel8.DistroFactory,
rhel9.DistroFactory,
)
}

View file

@ -2,8 +2,7 @@ package distroidparser
import (
"github.com/osbuild/images/pkg/distro"
"github.com/osbuild/images/pkg/distro/rhel/rhel8"
"github.com/osbuild/images/pkg/distro/rhel/rhel9"
"github.com/osbuild/images/pkg/distro/defs"
)
var DefaultParser = NewDefaultParser()
@ -60,7 +59,6 @@ func (p *Parser) Standardize(idStr string) (string, error) {
func NewDefaultParser() *Parser {
return New(
rhel8.ParseID,
rhel9.ParseID,
defs.ParseID,
)
}

View file

@ -140,6 +140,9 @@ type OSCustomizations struct {
OpenSCAPRemediationConfig *oscap.RemediationConfig
Subscription *subscription.ImageOptions
// Indicates if rhc should be set to permissive when creating the registration script
PermissiveRHC *bool
// The final RHSM config to be applied to the image
RHSMConfig *subscription.RHSMConfig
RHSMFacts *facts.ImageOptions
@ -700,7 +703,13 @@ func (p *OS) serialize() osbuild.Pipeline {
}
if p.OSCustomizations.Subscription != nil {
subStage, subDirs, subFiles, subServices, err := subscriptionService(*p.OSCustomizations.Subscription, &subscriptionServiceOptions{InsightsOnBoot: p.OSTreeRef != ""})
subStage, subDirs, subFiles, subServices, err := subscriptionService(
*p.OSCustomizations.Subscription,
&subscriptionServiceOptions{
InsightsOnBoot: p.OSTreeRef != "",
PermissiveRHC: common.ValueOrEmpty(p.OSCustomizations.PermissiveRHC),
},
)
if err != nil {
panic(err)
}

View file

@ -77,6 +77,9 @@ type subscriptionServiceOptions struct {
// UnitPath controls the path where the systemd unit will be created,
// /usr/lib/systemd or /etc/systemd.
UnitPath osbuild.SystemdUnitPath
// Indicates if rhc should be set to permissive when creating the registration script
PermissiveRHC bool
}
// subscriptionService creates the necessary stage and modifications to the
@ -86,18 +89,22 @@ type subscriptionServiceOptions struct {
// - Register the system with rhc and enable Insights
// - Register with subscription-manager, no Insights or rhc
// - Register with subscription-manager and enable Insights, no rhc
func subscriptionService(subscriptionOptions subscription.ImageOptions, serviceOptions *subscriptionServiceOptions) (*osbuild.Stage, []*fsnode.Directory, []*fsnode.File, []string, error) {
func subscriptionService(
subscriptionOptions subscription.ImageOptions,
serviceOptions *subscriptionServiceOptions) (*osbuild.Stage, []*fsnode.Directory, []*fsnode.File, []string, error) {
dirs := make([]*fsnode.Directory, 0)
files := make([]*fsnode.File, 0)
services := make([]string, 0)
insightsOnBoot := false
unitPath := osbuild.UsrUnitPath
permissiveRHC := false
if serviceOptions != nil {
insightsOnBoot = serviceOptions.InsightsOnBoot
if serviceOptions.UnitPath != "" {
unitPath = serviceOptions.UnitPath
}
permissiveRHC = serviceOptions.PermissiveRHC
}
// Write a key file that will contain the org ID and activation key to be sourced in the systemd service.
@ -126,8 +133,10 @@ func subscriptionService(subscriptionOptions subscription.ImageOptions, serviceO
rhcConnect += fmt.Sprintf(" --content-template=\"%s\"", subscriptionOptions.TemplateName)
}
commands = append(commands, rhcConnect)
// execute the rhc post install script as the selinuxenabled check doesn't work in the buildroot container
commands = append(commands, "/usr/sbin/semanage permissive --add rhcd_t")
if permissiveRHC {
// execute the rhc post install script as the selinuxenabled check doesn't work in the buildroot container
commands = append(commands, "/usr/sbin/semanage permissive --add rhcd_t")
}
// register to template if template uuid is specified
if curlToAssociateSystem != "" {
commands = append(commands, curlToAssociateSystem)