fedora: live-installer image type

This image type produces the same artifact as the current workstation
installer live media.

During the implementation of this new installer some names have been
changed to make a bit more sense in the source tree. Installer images
now always mention which installer they are (anaconda, etc).
This commit is contained in:
Simon de Vlieger 2023-03-21 08:56:19 +01:00
parent 32c3865507
commit 46f93614f2
20 changed files with 135311 additions and 166 deletions

View file

@ -86,6 +86,8 @@ const (
ImageTypesIotRawImage ImageTypes = "iot-raw-image"
ImageTypesLiveInstaller ImageTypes = "live-installer"
ImageTypesVsphere ImageTypes = "vsphere"
ImageTypesVsphereOva ImageTypes = "vsphere-ova"
@ -938,73 +940,73 @@ var swaggerSpec = []string{
"A5fdV16XqFvYruZnmoUF0oTHNqYTpRd2bO/+6wPS/6OVi1TS3i+X2dfndjiSrdSMk0HKHxBm8zf5b9Q9",
"qFglaWJtHUiIky5BlQ3Uv4arsIujUOg3H1zMELl/ny7mCMogIlIcBiBZDpheQ7ExzU/VJ2QzKiTr/+lj",
"5v8dVpQHRQxbvBjjsNhQcCGHgQues2COWR4OnmJ/cuhGj+8+Mn5xOYJuPfEl+RDrh3QT5aJqruApTAgF",
"LzDhAtq2emFqrv//EIApZTJSGurfRAdMxRq+/7AGL583GzO4iMDNuSsNwvVfOTqHqTTsBZVL6ZUFa41w",
"7ich29L0y7Ug32GsqrRhsme5WC4WT4r1fDHVAENs7vuK2wnSGZ3ilOyofG15k0PyypDPNtVutZxNyTHO",
"EeNbNWiV/QdcAvTXQwVZzjXENVXSFHRUtpmy08jtOqglIqrEcCvCQ3zm8FvuAr9L8SihO4Q6aYHrMOqV",
"BDnDJD0IF56YTEnuBg729hdBBbTTPm1QQQ2ajY5a+icc/c7ZnUGwbCbYalIzwYiI1JKOpjp1pZzJLMDq",
"aFY2cvOkU2kgoVnSrA+g5EHXcW2MAoPznx6z/yk7cCSkW7hAtp0dE987TSRvJTAnKNZUybN8euWJH+VK",
"iblBImEhrNJfMKg7Bb8EC30KiuXjYnVS1uExOqlVJ3qlOmlMGmXYqNRQDdbrenlyXDQM+GvWj81MGCSa",
"lbPxDAEWFWit4TEL2evqD6n+ft1wwLZbpKsQY7sQ9IBuFnf2xwjPkEDMwQRx6TAHpPG9usSpFwcSaCIG",
"ftEg0W3kYulm6ogILFb+oTuf/YCgykL2PQr1ITRA8qBNCfccxIAmmUsVkW2m6CEHmo0RERttLETGJOKl",
"iA+k9x4y1o7jejuPzG3z/0YAfksQrGAptk3AdBnfIfxpZY2ByKoR0mRzs1o51XJNRQK5dMeXncUnsU1r",
"e3fCpqPXdn0iMLScdzggKR9iG82e0z2+MblzN8n6RIhwlBZYssIryfvrb5KHDGx6fnojPyZNASRMoU4e",
"BnGHL0FF2BfpgEdFQuopKE76AtZrosIYYzJBa6dTRdAcykKIDoAMbfqklOl+qMNlSEO60imYq0qU6NSq",
"HFfKyoTOUVrSIVa69vdVrH26Qm1f8kJluYHpmkHRafJs5lqvRNpghwJYV69t5C7uLsAMraICDMm+66IO",
"FTNN6q+E7s7J/1qdi+4NuLu4A3cPretuG/Q6L6B1fdvuqc9jMibOffemddHUhhptdZpn10bj5XKG3q+O",
"oW73XxZ1eHHRta+gLRpX0/Ky0Cr3jqyu0fWWF8J9nNbRmFwPzLOH+vEUjmru41nNOe9fVdwZImhQ0EbO",
"29v97GZ1z63nMr1/XnTeH4aTUvum3zbaF+bsuXFfHpP31xnram12XrwvL1hvYkNPtx6O8CMkzTPulBov",
"nTc+qTUfKnVdPLB+5f5FfzJPBkfP+M54bAzGpNeajoqV+WPrVu8P+Uvl5Bq2yXHXLd3O3Ua3Qwtd1Hl8",
"Kb057du7JuwVJ1eXFc8wq20PzfjRaDgmi/unEWpfL73X6+Pb/jO9vest5v17YzkxS89njbn3WuyJaUG7",
"uSwvoVdcOrzpnVxeuWg2v70bLO0xWb2J6erVYPQRo/OVu3g15/cLQUi/UTCHHa9w9ThiL8Va2ek8jOpt",
"bVKvzrTL89G50Z/ZZHZRGJOi8VBtDmCtWL2sLKfFmZigyryn3T3Tu1uv13rkl8N5sfhw8dJc3SFvddSo",
"aw+Fl47Vr88qw8fedEyOUffVXOH+bXFhl14uzgY9zbMXM37SPPLsmVmio0mVV96d1/ldsX5BR8unankK",
"e7Wn4dGN9YrQmDSOi8/00ZpopZ47PJoar3TKWUe8Nu4mD69HL/PzxsBl+lOTTS8nV7PylTvoNZcja8nv",
"m7xlXZTGpHjtLctPsN8qmuVu7U7r61cF7W1Kiw1NY9PWs4eXTwzXsHfSf3Ybb6OCMXy/cbjeNUmj8Pba",
"GxPcuPdsw6vXvTfrqbAQ5YkgWJgD/ja1ln1v+vJQfZ1UrZk4b1i9h8Lzc71afrOua71Fc9C8b7bGRJyd",
"X7w+Deaa0zF7Z/1Sb9hsvDqPs0nlyroe9UvXz60VfCpZGrGb4Xvt8moOncep3q7Nx0RztCN8f3XbavVb",
"7Wazeo47HXR57DDr/LLuPfL7636/XHypaa8WWb40zpuOkqH2xaJx3l7MumPSWnQvzu/pVbvJ263WS7u5",
"6LQvzU77vNpsts3Z/br30c1Ls1BvvbimvRo2X18uremqZ41J4cg4fr8zHueTy3Kx81aZdeu3562bIrl+",
"Pmo9lBxvPjx6G3nDytM1a1WcyoVnC7c36Fz1roVT65yNSYldvD836ai0ck9euo3r5pneb7dvV9PmlNOn",
"h0b95cFrHxUmZMpGaFC+Hty2jdVdu378dNKo4dvHMXFqw6MJvz9b1Nvla2brzX61f+bR1WtpiMUFfK32",
"7q8fxdGoA0tVzF+GF+3pO63fvTQeK1e3s1pxTMy3J7NRvilMnHLnfVgfNSpPnbNJyZ5Pq117vjS7bz1k",
"lkrvzy9Lh70MX6+u2sb83Tiyb4bH3tK8HJPpsnBVXNmv5Ws8uWDHF83m6vbk4Yk1X4eLYb/Y0aajxqLT",
"JsvZ8MxbvTlPi8f5TevZ63QfG7eo8jImffxQMq5uGlyvn7n8fFnrHz3rpE/uh0eXbDq6651VnCdmN3XS",
"GVn6y2Nj+jpzn6yzFa8UTk7Q7ZhYsyK7Jqvi9GYxg55RwA+NW+34ed6fTa8H/Suz9nDy2FtdeU9P4n3x",
"TKb9m9rT4Lz11qvyV+r0+2NiiMnosnRUW00GT4VmZd6awOXgqSzqD+83U+0dzYavHQyvb06uC5faVbs7",
"KN2fN44b5TO9aXfOT/QxmZXNe/wyvG9CeFW8umq+X84Hs8HV9bXZK7/cv+DLm8dVWVSuVucGZ9CpLYbt",
"p1vDukPd1XVr9Ho1JnPm3th3E2Tw0UmtPjLKrZuuZ76/snbtcXk27M1ezYFVeryYD7v3pL16n92vjjsP",
"5bc7Fz/VTqSOsu66z6+sR7VepXc9PCng96v70cAW037ztzH57c4Y1cdE7S6dm7OPtp7UUKUq0/vGuZ2+",
"Sf+szk47gKhqIFNTx9IXCRoBv1BSeYYx2wRyaVZwgFUWb51hUvWXY/KLi11kY4J+Ta3F3MoxhIdS6CcL",
"XX+sM5j098AOdy+Tehpoy7MZbhQhbrg1msBzv+goMOKSd/8gjSGRk59iy+lCzheUpdZrSpv2W6pxvG0b",
"H8AimHBsWht3He0qoqHMhCQoDd6MCFaLlXI13Y8/4IIePygPbWDY0AxrCZilyT/DmLGfQ1aVHWH6H9qc",
"Amgv4IoH5accdIMZbfDerjn54b5tisYZJi/ZL0bYvXTdcPwSdMtu8kQCh9gCxxYnzaPePmZGVgdfsrCR",
"Csnu7bN5FdO+LlsVLXvH2L7cZ1+XHSfuvn/NblVWYB7eKMIQtP3CdVV+BCaeANvzkyoCKqWBBKDGmKSQ",
"LQ8UXAdBEgQDoW2DlIbAXzQ+JtJfVjzrK6WtcWHUNmDwOabqxJjvWkuEx4R5NvIL8xkyKENZsEDAgvOo",
"BkcxAlDlI3J2EwTgAoaFdOqOHPJFjIlLOccTvyzQwUsVi3Kg0Czfxw+oDAQ1lSqV8hSx3a4IdCwT95k7",
"P5L5qMO58cAemzngT/DigT3SDziqor/PZ+SinN4hOVm/Y5CU3XUaOog8havzdWMdP5nbYx4huxJ4cXTS",
"Mnh5XolSZ2Gibp0GS4XI044vq8oCvuNwo/pYOuRY4taezLmVQ3q5ViudgGaz2WxXbt5hu2S/nnVLN6NO",
"Tb7r3rCLXof1X/BRv/+w8C7hoHnlDK5p931glN/OyvpZ7b3YGi0Lx8uPDs2tR/U4YvszUztqAtQmpnkM",
"i9VQMoVPoBaCzCfcRP11Hm5YV0+j8L5ItRX67SKo0pLwb43ExKDbVuMwqOwRNDD1VIWdn7j0C0+4tJxs",
"rKHgmp7gosqmCzULgbJKGqrtNjLMF4tFHqrPyhoO+vLCdbfduRl2cuV8MW8Jx1YriIUi2e2wpYYP8ugM",
"qBI2AF0ci62eZsoZv6KcyA+nmUq+mC9l/PpYRaaCZlOCeOEPrH9XfJVWZHmB/AJkX55UuSUIhABQBqRU",
"2kiEZ4H9Y/IqQSMxUxV5mAfXfMRMU8pUfc66kFDVZkv7VIkf0pGej1etd3UflfiFQdnEtae/p1+zFdyo",
"5SMvKDBVmae6TFRV0UZ3iQYXFIQc55tM65tFf/i9Pl/VnVbqPie1GOViMZavUzaN69pB4LQwDYr+1wh9",
"qJFjVFLsnKRMnCaSRao/cOigmmN70C7x9/2AMwDW/aFLf/3QTU+Vfs+Q8n6wj4g/euWvH/2BQE9YlOF3",
"3+NyEZO8ASLe9jGp/h2YzAhdkI0lqP0dq/9A0NJF6mZCVSEEqKZ5TEpaXIUrKQ6V9+9fpYxwz3EgWwUl",
"wnElpJRXxE8KTkGLXetL0y5MaPtHQCAgaBF2zQKXyqljZRxrlPCgllyd8ZsjBkPlrvR9UFyt7i/2i3sx",
"AzqSXYJC4S3FdUe5CG9185UM4iK8H+7HSHzyZqPvye1TKrPvW/qm9KNH7+ppSx98BBbkcv2YQPq/Temw",
"9Z1HPzXPT81zoOYJlEaapvlRxtMn7KWQhnsMpcTFWweZShHg/8eMpQSlUjgoSZefBtNPtfUfajDt1F++",
"Ixi3mlLsl/jVtAfpk5iy+j+kRf4C22vz0t+/2/pKuyI4haXUcUW0WJ+QmSBV2+nfeJau1wRaioI62ZzE",
"J+WHNg7TXtUfNUCabH5P7NqSLImzoR8IgB0ULf+ZXdzABHMrtomDD/dwLNZbd1Z5FCoq7iABASY+D2NK",
"AJxQT4Q3qnu2+GibVzXXPzf5vZt8cKVwqmhIFoiO8Pq/fBA5iJgAQlXaF2ueDVlwZhH8IizqmVaQ0rga",
"3t78mv+vE6QLdT7VDBPkIZeniVHieuQPZSlqeYA4DdSPgnBVzxndcSiRUT54oM5I/Ocn8kAdSo0aa1QJ",
"Fo8uAPCXT0cGVj82IkA8HBvcV+hXR0AS3l+YC8Hlax+I4vra6Z/yuFce18TaIZSJ5d4SzP9OWUuKxwFC",
"F6sr/1jmohMYUuS25Mw/PY+WUBOJjSj6TR4duYjofH2JqJK1KPSvznR/JBkhnj8FY79gRDeb75CLcCk/",
"Ixc/ndSfTur/NSd1Szel6TsFPG5TbKmY9d1VW8olbWbrJgV10G5XiUOsnTqJ95eK/noOadzu/14CNUBA",
"jJ9i9u8RM5/R//OEDEYMBG0bRPVPITetxWx/RBsSv+iBaNH5Kh+z9e1CkxVQW2e6oB4eP0JB839p16/8",
"zXv4zqVUH0D83U8p/inFn5FitM1BUnKjIp/dO+Rt0CSd75PIBuCUPEvPWtIgvIHvP9C2+HA636M66DRN",
"1A+uOqK6p/n3c0VXJCTLuKCL83IcbuHgB/egi/2f7cip6AFiufCetcK8rCyOjeIyAU1MzI8G4AKa6F8c",
"RhGRhFcxRcPsg/P1+/8fAAD//4yZSqt0egAA",
"LzDhAtq2emFqrv//EIApZTJSGurfRAdMxRq+/7AGL583GzO4iMDNuSsNwvVfOTqHmWzGxvP4KGlE7QWl",
"TOmlBmsVce5nJdvSFsy1IN9hvao8YrJnuVguFk+K9Xwx1SJDbO47j9sZ0xmd4pR0qXxteZNDEs2Qzzb1",
"cLWcTUk6zhHjW0Vplf0nXgL010MFac81xDVV0jR2VMeZsvXI/TsoLiKq5nAr5EN8bvFb7gK/SxMpKTyE",
"OmmR7DAMlgQ5wyQ9KhceoUzJ9gYe9/YXQQW00z5tUEENmo3OXvpHHv3O2Z1RsWwm2HtSU8OIiNQaj6Y6",
"hqW8yyzA6qxWNvL7pJdpIKFZ0s4PoORB13FtjAIL9J8es/8pO3AkpJ+4QLadHRPfXU1kcyUwJ6jeVNm0",
"fHopih/2SgnCQSJhIazyYTAoRAW/BAt9Corl42J1UtbhMTqpVSd6pTppTBpl2KjUUA3W63p5clw0DPhr",
"1g/WTBgkmpWz8QwBFlVsreExC9nrchCpD3/d8Mi2W6SrEGO7MvSAbhZ39gcNz5BAzMEEcelBB6Tx3bzE",
"MRgHEmgiBn7RINFt5GLpd+qICCxW/ik8n/2AoMpk9l0M9SG0SPKgTQn3HMSAJplLVZVt5uwhB5qNEREb",
"bSxExiTipYgPpDsfMtaO83s7z9Bt8/9GRH5LEKxgKbZtwnQZ3yH8aXWOgciqEdJkc7N8OdWUTUUCuXTH",
"l53VKLFNa3t3wqaj13Z9IjA0pXd4JCkfYhvNnuM+vnW5czfJ+kSIcJQmWbLkK8n762+Shwxsen6+Iz8m",
"TQEkTKGOIgaBiC9BidgX6ZFHVUPqKahW+gLWa6LiGmMyQWsvVIXUHMpCiA6ADG06qZTpfuzDZUhDutIp",
"mKvSlOgYqxxXysqEzlFaFiJWy/b3lbB9umRtXzZDpb2B6ZpBFWrysOZar0TaYIcCWJezbSQz7i7ADK2i",
"igzJvusqDxVETeqvhO7Oyf9anYvuDbi7uAN3D63rbhv0Oi+gdX3b7qnPYzImzn33pnXR1IYabXWaZ9dG",
"4+Vyht6vjqFu918WdXhx0bWvoC0aV9PystAq946srtH1lhfCfZzW0ZhcD8yzh/rxFI5q7uNZzTnvX1Xc",
"GSJoUNBGztvb/exmdc+t5zK9f1503h+Gk1L7pt822hfm7LlxXx6T99cZ62ptdl68Ly9Yb2JDT7cejvAj",
"JM0z7pQaL503Pqk1Hyp1XTywfuX+RX8yTwZHz/jOeGwMxqTXmo6Klflj61bvD/lL5eQatslx1y3dzt1G",
"t0MLXdR5fCm9Oe3buybsFSdXlxXPMKttD8340Wg4Jov7pxFqXy+91+vj2/4zvb3rLeb9e2M5MUvPZ425",
"91rsiWlBu7ksL6FXXDq86Z1cXrloNr+9GyztMVm9ienq1WD0EaPzlbt4Nef3C0FIv1Ewhx2vcPU4Yi/F",
"WtnpPIzqbW1Sr860y/PRudGf2WR2URiTovFQbQ5grVi9rCynxZmYoMq8p90907tbr9d65JfDebH4cPHS",
"XN0hb3XUqGsPhZeO1a/PKsPH3nRMjlH31Vzh/m1xYZdeLs4GPc2zFzN+0jzy7JlZoqNJlVfendf5XbF+",
"QUfLp2p5Cnu1p+HRjfWK0Jg0jovP9NGaaKWeOzyaGq90yllHvDbuJg+vRy/z88bAZfpTk00vJ1ez8pU7",
"6DWXI2vJ75u8ZV2UxqR47S3LT7DfKprlbu1O6+tXBe1tSosNTWPT1rOHl08M17B30n92G2+jgjF8v3G4",
"3jVJo/D22hsT3Lj3bMOr170366mwEOWJIFiYA/42tZZ9b/ryUH2dVK2ZOG9YvYfC83O9Wn6zrmu9RXPQ",
"vG+2xkScnV+8Pg3mmtMxe2f9Um/YbLw6j7NJ5cq6HvVL18+tFXwqWRqxm+F77fJqDp3Hqd6uzcdEc7Qj",
"fH9122r1W+1ms3qOOx10eeww6/yy7j3y++t+v1x8qWmvFlm+NM6bjpKh9sWicd5ezLpj0lp0L87v6VW7",
"ydut1ku7uei0L81O+7zabLbN2f2699HNS7NQb724pr0aNl9fLq3pqmeNSeHIOH6/Mx7nk8tysfNWmXXr",
"t+etmyK5fj5qPZQcbz48eht5w8rTNWtVnMqFZwu3N+hc9a6FU+ucjUmJXbw/N+motHJPXrqN6+aZ3m+3",
"b1fT5pTTp4dG/eXBax8VJmTKRmhQvh7cto3VXbt+/HTSqOHbxzFxasOjCb8/W9Tb5Wtm681+tX/m0dVr",
"aYjFBXyt9u6vH8XRqANLVcxfhhft6Tut3700HitXt7NacUzMtyezUb4pTJxy531YHzUqT52zScmeT6td",
"e740u289ZJZK788vS4e9DF+vrtrG/N04sm+Gx97SvByT6bJwVVzZr+VrPLlgxxfN5ur25OGJNV+Hi2G/",
"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",
}
// GetSwagger returns the content of the embedded swagger specification file

View file

@ -778,6 +778,7 @@ components:
- iot-raw-image
- vsphere
- vsphere-ova
- live-installer
Repository:
type: object
description: |

View file

@ -263,6 +263,7 @@ func TestDistro_KernelOption(t *testing.T, d distro.Distro) {
// on RHEL we support kernel name
// TODO: Remove when we unify the allowed options
"image-installer": true,
"live-installer": true,
}
{ // empty blueprint: all image types should just have the default kernel
@ -301,6 +302,9 @@ func TestDistro_KernelOption(t *testing.T, d distro.Distro) {
if typeName != "image-installer" {
continue
}
if typeName != "live-installer" {
continue
}
if skipList[typeName] {
continue
}

View file

@ -80,6 +80,23 @@ var (
exports: []string{"bootiso"},
}
liveInstallerImgType = imageType{
name: "live-installer",
nameAliases: []string{},
filename: "live-installer.iso",
mimeType: "application/x-iso9660-image",
packageSets: map[string]packageSetFunc{
installerPkgsKey: liveInstallerPackageSet,
},
bootable: true,
bootISO: true,
rpmOstree: false,
image: liveInstallerImage,
buildPipelines: []string{"build"},
payloadPipelines: []string{"anaconda-tree", "rootfs-image", "efiboot-tree", "bootiso-tree", "bootiso"},
exports: []string{"bootiso"},
}
iotCommitImgType = imageType{
name: "iot-commit",
nameAliases: []string{"fedora-iot-commit"},
@ -578,6 +595,7 @@ func newDistro(version int) distro.Distro {
iotCommitImgType,
iotInstallerImgType,
imageInstallerImgType,
liveInstallerImgType,
)
x86_64.addImageTypes(
&platform.X86{

View file

@ -152,6 +152,14 @@ func TestFilenameFromType(t *testing.T) {
mimeType: "application/x-iso9660-image",
},
},
{
name: "live-installer",
args: args{"live-installer"},
want: wantResult{
filename: "live-installer.iso",
mimeType: "application/x-iso9660-image",
},
},
{
name: "image-installer",
args: args{"image-installer"},
@ -282,6 +290,7 @@ func TestImageType_Name(t *testing.T) {
"iot-raw-image",
"oci",
"image-installer",
"live-installer",
"minimal-raw",
},
},
@ -430,6 +439,8 @@ func TestDistro_ManifestError(t *testing.T) {
assert.EqualError(t, err, fmt.Sprintf("boot ISO image type \"%s\" requires specifying a URL from which to retrieve the OSTree commit", imgTypeName))
} else if imgTypeName == "image-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: User, Group)", imgTypeName))
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else if imgTypeName == "iot-raw-image" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for image type %q: (allowed: User, Group, Directories, Files, Services)", imgTypeName))
} else {
@ -461,6 +472,7 @@ func TestArchitecture_ListImageTypes(t *testing.T) {
"oci",
"container",
"image-installer",
"live-installer",
"minimal-raw",
},
},
@ -584,6 +596,8 @@ func TestDistro_CustomFileSystemManifestError(t *testing.T) {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for image type %q: (allowed: User, Group, Directories, Files, Services)", imgTypeName))
} else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/etc\"]")
}
@ -614,6 +628,8 @@ func TestDistro_TestRootMountPoint(t *testing.T) {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for image type %q: (allowed: User, Group, Directories, Files, Services)", imgTypeName))
} else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.NoError(t, err)
}
@ -644,6 +660,8 @@ func TestDistro_CustomFileSystemSubDirectories(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.NoError(t, err)
}
@ -682,6 +700,8 @@ func TestDistro_MountpointsWithArbitraryDepthAllowed(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.NoError(t, err)
}
@ -716,6 +736,8 @@ func TestDistro_DirtyMountpointsNotAllowed(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"//\" \"/var//\" \"/var//log/audit/\"]")
}
@ -750,6 +772,8 @@ func TestDistro_CustomFileSystemPatternMatching(t *testing.T) {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for image type %q: (allowed: User, Group, Directories, Files, Services)", imgTypeName))
} else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/variable\" \"/variable/log/audit\"]")
}
@ -780,6 +804,8 @@ func TestDistro_CustomUsrPartitionNotLargeEnough(t *testing.T) {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for image type %q: (allowed: User, Group, Directories, Files, Services)", imgTypeName))
} else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue
} else if imgTypeName == "live-installer" {
assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for boot ISO image type \"%s\": (allowed: None)", imgTypeName))
} else {
assert.NoError(t, err)
}

View file

@ -238,6 +238,44 @@ func containerImage(workload workload.Workload,
return img, nil
}
func liveInstallerImage(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.NewAnacondaLiveInstaller()
distro := t.Arch().Distro()
// If the live installer is generated for Fedora 39 or higher then we enable the web ui
// kernel options. This is a temporary thing as the check for this should really lie with
// anaconda and their `liveinst` script to determine which frontend to start.
if common.VersionLessThan(distro.Releasever(), "39") {
img.AdditionalKernelOpts = []string{}
} else {
img.AdditionalKernelOpts = []string{"inst.webui"}
}
img.Platform = t.platform
img.Workload = workload
img.ExtraBasePackages = packageSets[installerPkgsKey]
d := t.arch.distro
img.ISOLabelTempl = d.isolabelTmpl
img.Product = d.product
img.OSName = "fedora"
img.OSVersion = d.osVersion
img.Release = fmt.Sprintf("%s %s", d.product, d.osVersion)
img.Filename = t.Filename()
return img, nil
}
func imageInstallerImage(workload workload.Workload,
t *imageType,
customizations *blueprint.Customizations,
@ -246,7 +284,7 @@ func imageInstallerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewImageInstaller()
img := image.NewAnacondaTarInstaller()
// Enable anaconda-webui for Fedora > 38
distro := t.Arch().Distro()
@ -343,7 +381,7 @@ func iotInstallerImage(workload workload.Workload,
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeInstaller(commit)
img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey]

View file

@ -277,6 +277,11 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp
if err := customizations.CheckAllowed(allowed...); err != nil {
return nil, fmt.Errorf("unsupported blueprint customizations found for boot ISO image type %q: (allowed: %s)", t.name, strings.Join(allowed, ", "))
}
} else if t.name == "live-installer" {
allowed := []string{}
if err := customizations.CheckAllowed(allowed...); err != nil {
return nil, fmt.Errorf("unsupported blueprint customizations found for boot ISO image type %q: (allowed: None)", t.name)
}
}
}

View file

@ -436,6 +436,47 @@ func iotInstallerPackageSet(t *imageType) rpmmd.PackageSet {
return ps
}
func liveInstallerPackageSet(t *imageType) rpmmd.PackageSet {
ps := rpmmd.PackageSet{
Include: []string{
"@workstation-product-environment",
"@anaconda-tools",
"anaconda-install-env-deps",
"anaconda-live",
"anaconda-dracut",
"dracut-live",
"glibc-all-langpacks",
"kernel",
"kernel-modules",
"kernel-modules-extra",
"livesys-scripts",
"rng-tools",
"rdma-core",
"gnome-kiosk",
},
Exclude: []string{
"@dial-up",
"@input-methods",
"@standard",
"device-mapper-multipath",
"fcoe-utils",
"gfs2-utils",
"reiserfs-utils",
},
}
// We want to generate a preview image when rawhide is built
if !common.VersionLessThan(t.arch.distro.osVersion, "39") {
ps = ps.Append(rpmmd.PackageSet{
Include: []string{
"anaconda-webui",
},
})
}
return ps
}
func imageInstallerPackageSet(t *imageType) rpmmd.PackageSet {
ps := anacondaPackageSet(t)

View file

@ -255,7 +255,7 @@ func imageInstallerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewImageInstaller()
img := image.NewAnacondaTarInstaller()
img.Platform = t.platform
img.Workload = workload
@ -366,7 +366,7 @@ func edgeInstallerImage(workload workload.Workload,
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeInstaller(commit)
img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey]

View file

@ -319,7 +319,7 @@ func edgeInstallerImage(workload workload.Workload,
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
}
img := image.NewOSTreeInstaller(commit)
img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey]
@ -510,7 +510,7 @@ func imageInstallerImage(workload workload.Workload,
containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) {
img := image.NewImageInstaller()
img := image.NewAnacondaTarInstaller()
img.Platform = t.platform
img.Workload = workload

View file

@ -0,0 +1,127 @@
package image
import (
"fmt"
"math/rand"
"github.com/osbuild/osbuild-composer/internal/artifact"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/disk"
"github.com/osbuild/osbuild-composer/internal/environment"
"github.com/osbuild/osbuild-composer/internal/manifest"
"github.com/osbuild/osbuild-composer/internal/platform"
"github.com/osbuild/osbuild-composer/internal/rpmmd"
"github.com/osbuild/osbuild-composer/internal/runner"
"github.com/osbuild/osbuild-composer/internal/workload"
)
type AnacondaLiveInstaller struct {
Base
Platform platform.Platform
Environment environment.Environment
Workload workload.Workload
ExtraBasePackages rpmmd.PackageSet
ISOLabelTempl string
Product string
Variant string
OSName string
OSVersion string
Release string
Filename string
AdditionalKernelOpts []string
}
func NewAnacondaLiveInstaller() *AnacondaLiveInstaller {
return &AnacondaLiveInstaller{
Base: NewBase("live-installer"),
}
}
func (img *AnacondaLiveInstaller) InstantiateManifest(m *manifest.Manifest,
repos []rpmmd.RepoConfig,
runner runner.Runner,
rng *rand.Rand) (*artifact.Artifact, error) {
buildPipeline := manifest.NewBuild(m, runner, repos)
buildPipeline.Checkpoint()
livePipeline := manifest.NewAnacondaInstaller(m,
manifest.AnacondaInstallerTypeLive,
buildPipeline,
img.Platform,
repos,
"kernel",
img.Product,
img.OSVersion)
livePipeline.ExtraPackages = img.ExtraBasePackages.Include
livePipeline.Variant = img.Variant
livePipeline.Biosdevname = (img.Platform.GetArch() == platform.ARCH_X86_64)
livePipeline.Checkpoint()
rootfsPartitionTable := &disk.PartitionTable{
Size: 20 * common.MebiByte,
Partitions: []disk.Partition{
{
Start: 0,
Size: 20 * common.MebiByte,
Payload: &disk.Filesystem{
Type: "vfat",
Mountpoint: "/",
UUID: disk.NewVolIDFromRand(rng),
},
},
},
}
// TODO: replace isoLabelTmpl with more high-level properties
isoLabel := fmt.Sprintf(img.ISOLabelTempl, img.Platform.GetArch())
rootfsImagePipeline := manifest.NewISORootfsImg(m, buildPipeline, livePipeline)
rootfsImagePipeline.Size = 8 * common.GibiByte
bootTreePipeline := manifest.NewEFIBootTree(m, buildPipeline, img.Product, img.OSVersion)
bootTreePipeline.Platform = img.Platform
bootTreePipeline.UEFIVendor = img.Platform.GetUEFIVendor()
bootTreePipeline.ISOLabel = isoLabel
kernelOpts := []string{
fmt.Sprintf("root=live:CDLABEL=%s", isoLabel),
"rd.live.image",
"quiet",
"rhgb",
}
kernelOpts = append(kernelOpts, img.AdditionalKernelOpts...)
bootTreePipeline.KernelOpts = kernelOpts
// enable ISOLinux on x86_64 only
isoLinuxEnabled := img.Platform.GetArch() == platform.ARCH_X86_64
isoTreePipeline := manifest.NewAnacondaInstallerISOTree(m,
buildPipeline,
livePipeline,
rootfsImagePipeline,
bootTreePipeline,
isoLabel)
isoTreePipeline.PartitionTable = rootfsPartitionTable
isoTreePipeline.Release = img.Release
isoTreePipeline.OSName = img.OSName
isoTreePipeline.KernelOpts = kernelOpts
isoTreePipeline.ISOLinux = isoLinuxEnabled
isoPipeline := manifest.NewISO(m, buildPipeline, isoTreePipeline, isoLabel)
isoPipeline.Filename = img.Filename
isoPipeline.ISOLinux = isoLinuxEnabled
artifact := isoPipeline.Export()
return artifact, nil
}

View file

@ -15,7 +15,7 @@ import (
"github.com/osbuild/osbuild-composer/internal/users"
)
type OSTreeInstaller struct {
type AnacondaOSTreeInstaller struct {
Base
Platform platform.Platform
ExtraBasePackages rpmmd.PackageSet
@ -40,21 +40,22 @@ type OSTreeInstaller struct {
AdditionalDrivers []string
}
func NewOSTreeInstaller(commit ostree.SourceSpec) *OSTreeInstaller {
return &OSTreeInstaller{
func NewAnacondaOSTreeInstaller(commit ostree.SourceSpec) *AnacondaOSTreeInstaller {
return &AnacondaOSTreeInstaller{
Base: NewBase("ostree-installer"),
Commit: commit,
}
}
func (img *OSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
func (img *AnacondaOSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
repos []rpmmd.RepoConfig,
runner runner.Runner,
rng *rand.Rand) (*artifact.Artifact, error) {
buildPipeline := manifest.NewBuild(m, runner, repos)
buildPipeline.Checkpoint()
anacondaPipeline := manifest.NewAnaconda(m,
anacondaPipeline := manifest.NewAnacondaInstaller(m,
manifest.AnacondaInstallerTypePayload,
buildPipeline,
img.Platform,
repos,
@ -102,7 +103,7 @@ func (img *OSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
// enable ISOLinux on x86_64 only
isoLinuxEnabled := img.Platform.GetArch() == platform.ARCH_X86_64
isoTreePipeline := manifest.NewAnacondaISOTree(m,
isoTreePipeline := manifest.NewAnacondaInstallerISOTree(m,
buildPipeline,
anacondaPipeline,
rootfsImagePipeline,

View file

@ -19,7 +19,7 @@ import (
const kspath = "/osbuild.ks"
type ImageInstaller struct {
type AnacondaTarInstaller struct {
Base
Platform platform.Platform
OSCustomizations manifest.OSCustomizations
@ -52,20 +52,21 @@ type ImageInstaller struct {
AdditionalDrivers []string
}
func NewImageInstaller() *ImageInstaller {
return &ImageInstaller{
func NewAnacondaTarInstaller() *AnacondaTarInstaller {
return &AnacondaTarInstaller{
Base: NewBase("image-installer"),
}
}
func (img *ImageInstaller) InstantiateManifest(m *manifest.Manifest,
func (img *AnacondaTarInstaller) InstantiateManifest(m *manifest.Manifest,
repos []rpmmd.RepoConfig,
runner runner.Runner,
rng *rand.Rand) (*artifact.Artifact, error) {
buildPipeline := manifest.NewBuild(m, runner, repos)
buildPipeline.Checkpoint()
anacondaPipeline := manifest.NewAnaconda(m,
anacondaPipeline := manifest.NewAnacondaInstaller(m,
manifest.AnacondaInstallerTypePayload,
buildPipeline,
img.Platform,
repos,
@ -133,7 +134,7 @@ func (img *ImageInstaller) InstantiateManifest(m *manifest.Manifest,
// enable ISOLinux on x86_64 only
isoLinuxEnabled := img.Platform.GetArch() == platform.ARCH_X86_64
isoTreePipeline := manifest.NewAnacondaISOTree(m,
isoTreePipeline := manifest.NewAnacondaInstallerISOTree(m,
buildPipeline,
anacondaPipeline,
rootfsImagePipeline,

View file

@ -2,8 +2,10 @@ package manifest
import (
"fmt"
"os"
"github.com/osbuild/osbuild-composer/internal/container"
"github.com/osbuild/osbuild-composer/internal/fsnode"
"github.com/osbuild/osbuild-composer/internal/osbuild"
"github.com/osbuild/osbuild-composer/internal/ostree"
"github.com/osbuild/osbuild-composer/internal/platform"
@ -11,10 +13,23 @@ import (
"github.com/osbuild/osbuild-composer/internal/users"
)
// An Anaconda represents the installer tree as found on an ISO.
type Anaconda struct {
type AnacondaInstallerType int
const (
AnacondaInstallerTypeLive AnacondaInstallerType = iota + 1
AnacondaInstallerTypePayload
)
// An Anaconda represents the installer tree as found on an ISO this can be either
// a payload installer or a live installer depending on `Type`.
type AnacondaInstaller struct {
Base
// The type of the Anaconda installer tree to prepare, this can be either
// a 'live' or a 'payload' and it controls which stages are added to the
// manifest.
Type AnacondaInstallerType
// Packages to install in addition to the ones required by the
// pipeline.
ExtraPackages []string
@ -53,24 +68,22 @@ type Anaconda struct {
// Additional dracut modules and drivers to enable
AdditionalDracutModules []string
AdditionalDrivers []string
Files []*fsnode.File
}
// NewAnaconda creates an anaconda pipeline object. repos and packages
// indicate the content to build the installer from, which is distinct from the
// packages the installer will install on the target system. kernelName is the
// name of the kernel package the intsaller will use. arch is the supported
// architecture. Product and version refers to the product the installer is the
// installer for.
func NewAnaconda(m *Manifest,
func NewAnacondaInstaller(m *Manifest,
installerType AnacondaInstallerType,
buildPipeline *Build,
platform platform.Platform,
repos []rpmmd.RepoConfig,
kernelName,
product,
version string) *Anaconda {
version string) *AnacondaInstaller {
name := "anaconda-tree"
p := &Anaconda{
p := &AnacondaInstaller{
Base: NewBase(m, name, buildPipeline),
Type: installerType,
platform: platform,
repos: filterRepos(repos, name),
kernelName: kernelName,
@ -84,7 +97,7 @@ func NewAnaconda(m *Manifest,
// TODO: refactor - what is required to boot and what to build, and
// do they all belong in this pipeline?
func (p *Anaconda) anacondaBootPackageSet() []string {
func (p *AnacondaInstaller) anacondaBootPackageSet() []string {
packages := []string{
"grub2-tools",
"grub2-tools-extra",
@ -116,7 +129,7 @@ func (p *Anaconda) anacondaBootPackageSet() []string {
return packages
}
func (p *Anaconda) getBuildPackages(Distro) []string {
func (p *AnacondaInstaller) getBuildPackages(Distro) []string {
packages := p.anacondaBootPackageSet()
packages = append(packages,
"rpm",
@ -125,7 +138,7 @@ func (p *Anaconda) getBuildPackages(Distro) []string {
return packages
}
func (p *Anaconda) getPackageSetChain(Distro) []rpmmd.PackageSet {
func (p *AnacondaInstaller) getPackageSetChain(Distro) []rpmmd.PackageSet {
packages := p.anacondaBootPackageSet()
if p.Biosdevname {
packages = append(packages, "biosdevname")
@ -138,11 +151,11 @@ func (p *Anaconda) getPackageSetChain(Distro) []rpmmd.PackageSet {
}
}
func (p *Anaconda) getPackageSpecs() []rpmmd.PackageSpec {
func (p *AnacondaInstaller) getPackageSpecs() []rpmmd.PackageSpec {
return p.packageSpecs
}
func (p *Anaconda) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec) {
func (p *AnacondaInstaller) serializeStart(packages []rpmmd.PackageSpec, _ []container.Spec, _ []ostree.CommitSpec) {
if len(p.packageSpecs) > 0 {
panic("double call to serializeStart()")
}
@ -152,7 +165,7 @@ func (p *Anaconda) serializeStart(packages []rpmmd.PackageSpec, _ []container.Sp
}
}
func (p *Anaconda) serializeEnd() {
func (p *AnacondaInstaller) serializeEnd() {
if len(p.packageSpecs) == 0 {
panic("serializeEnd() call when serialization not in progress")
}
@ -160,10 +173,26 @@ func (p *Anaconda) serializeEnd() {
p.packageSpecs = nil
}
func (p *Anaconda) serialize() osbuild.Pipeline {
func (p *AnacondaInstaller) serialize() osbuild.Pipeline {
if len(p.packageSpecs) == 0 {
panic("serialization not started")
}
// Let's do a bunch of sanity checks that are dependent on the installer type
// being serialized
if p.Type == AnacondaInstallerTypeLive {
if len(p.Users) != 0 || len(p.Groups) != 0 {
panic("anaconda installer type payload does not support users and groups customization")
}
if p.InteractiveDefaults != nil {
panic("anaconda installer type payload does not support interactive defaults")
}
} else if p.Type == AnacondaInstallerTypePayload {
} else {
panic("invalid anaconda installer type")
}
pipeline := p.Base.serialize()
pipeline.AddStage(osbuild.NewRPMStage(osbuild.NewRPMStageOptions(p.repos), osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs)))
@ -181,32 +210,67 @@ func (p *Anaconda) serialize() osbuild.Pipeline {
Password: &rootPassword,
}
installUID := 0
installGID := 0
installHome := "/root"
installShell := "/usr/libexec/anaconda/run-anaconda"
installPassword := ""
installUser := osbuild.UsersStageOptionsUser{
UID: &installUID,
GID: &installGID,
Home: &installHome,
Shell: &installShell,
Password: &installPassword,
}
usersStageOptions := &osbuild.UsersStageOptions{
Users: map[string]osbuild.UsersStageOptionsUser{
"root": rootUser,
"install": installUser,
},
var usersStageOptions *osbuild.UsersStageOptions
if p.Type == AnacondaInstallerTypePayload {
installUID := 0
installGID := 0
installHome := "/root"
installShell := "/usr/libexec/anaconda/run-anaconda"
installPassword := ""
installUser := osbuild.UsersStageOptionsUser{
UID: &installUID,
GID: &installGID,
Home: &installHome,
Shell: &installShell,
Password: &installPassword,
}
usersStageOptions = &osbuild.UsersStageOptions{
Users: map[string]osbuild.UsersStageOptionsUser{
"root": rootUser,
"install": installUser,
},
}
} else if p.Type == AnacondaInstallerTypeLive {
usersStageOptions = &osbuild.UsersStageOptions{
Users: map[string]osbuild.UsersStageOptionsUser{
"root": rootUser,
},
}
}
pipeline.AddStage(osbuild.NewUsersStage(usersStageOptions))
pipeline.AddStage(osbuild.NewAnacondaStage(osbuild.NewAnacondaStageOptions(p.AdditionalAnacondaModules)))
pipeline.AddStage(osbuild.NewLoraxScriptStage(&osbuild.LoraxScriptStageOptions{
Path: "99-generic/runtime-postinstall.tmpl",
BaseArch: p.platform.GetArch().String(),
}))
if p.Type == AnacondaInstallerTypeLive {
systemdStageOptions := &osbuild.SystemdStageOptions{
EnabledServices: []string{
"livesys.service",
"livesys-late.service",
},
}
pipeline.AddStage(osbuild.NewSystemdStage(systemdStageOptions))
livesysMode := os.FileMode(int(0644))
livesysFile, err := fsnode.NewFile("/etc/sysconfig/livesys", &livesysMode, "root", "root", []byte("livesys_session=\"gnome\""))
if err != nil {
panic(err)
}
p.Files = []*fsnode.File{livesysFile}
pipeline.AddStages(osbuild.GenFileNodesStages(p.Files)...)
}
if p.Type == AnacondaInstallerTypePayload {
pipeline.AddStage(osbuild.NewAnacondaStage(osbuild.NewAnacondaStageOptions(p.AdditionalAnacondaModules)))
pipeline.AddStage(osbuild.NewLoraxScriptStage(&osbuild.LoraxScriptStageOptions{
Path: "99-generic/runtime-postinstall.tmpl",
BaseArch: p.platform.GetArch().String(),
}))
}
dracutModules := append(
p.AdditionalDracutModules,
@ -225,22 +289,24 @@ func (p *Anaconda) serialize() osbuild.Pipeline {
pipeline.AddStage(osbuild.NewDracutStage(dracutOptions))
pipeline.AddStage(osbuild.NewSELinuxConfigStage(&osbuild.SELinuxConfigStageOptions{State: osbuild.SELinuxStatePermissive}))
if p.InteractiveDefaults != nil {
kickstartOptions, err := osbuild.NewKickstartStageOptions(
"/usr/share/anaconda/interactive-defaults.ks",
p.InteractiveDefaults.TarPath,
p.Users,
p.Groups,
"",
"",
"",
)
if p.Type == AnacondaInstallerTypePayload {
if p.InteractiveDefaults != nil {
kickstartOptions, err := osbuild.NewKickstartStageOptions(
"/usr/share/anaconda/interactive-defaults.ks",
p.InteractiveDefaults.TarPath,
p.Users,
p.Groups,
"",
"",
"",
)
if err != nil {
panic("failed to create kickstartstage options for interactive defaults")
if err != nil {
panic("failed to create kickstartstage options for interactive defaults")
}
pipeline.AddStage(osbuild.NewKickstartStage(kickstartOptions))
}
pipeline.AddStage(osbuild.NewKickstartStage(kickstartOptions))
}
return pipeline
@ -300,7 +366,7 @@ func dracutStageOptions(kernelVer string, biosdevname bool, additionalModules []
}
}
func (p *Anaconda) GetPlatform() platform.Platform {
func (p *AnacondaInstaller) GetPlatform() platform.Platform {
return p.platform
}
@ -315,3 +381,14 @@ func NewAnacondaInteractiveDefaults(tarPath string) *AnacondaInteractiveDefaults
return i
}
func (p *AnacondaInstaller) getInline() []string {
inlineData := []string{}
// inline data for custom files
for _, file := range p.Files {
inlineData = append(inlineData, string(file.Data()))
}
return inlineData
}

View file

@ -12,11 +12,11 @@ import (
"github.com/osbuild/osbuild-composer/internal/users"
)
// An AnacondaISOTree represents a tree containing the anaconda installer,
// An AnacondaInstallerISOTree represents a tree containing the anaconda installer,
// configuration in terms of a kickstart file, as well as an embedded
// payload to be installed, this payload can either be an ostree
// CommitSpec or OSPipeline for an OS.
type AnacondaISOTree struct {
type AnacondaInstallerISOTree struct {
Base
// TODO: review optional and mandatory fields and their meaning
@ -27,7 +27,7 @@ type AnacondaISOTree struct {
PartitionTable *disk.PartitionTable
anacondaPipeline *Anaconda
anacondaPipeline *AnacondaInstaller
rootfsPipeline *ISORootfsImg
bootTreePipeline *EFIBootTree
@ -55,14 +55,14 @@ type AnacondaISOTree struct {
ISOLinux bool
}
func NewAnacondaISOTree(m *Manifest,
func NewAnacondaInstallerISOTree(m *Manifest,
buildPipeline *Build,
anacondaPipeline *Anaconda,
anacondaPipeline *AnacondaInstaller,
rootfsPipeline *ISORootfsImg,
bootTreePipeline *EFIBootTree,
isoLabel string) *AnacondaISOTree {
isoLabel string) *AnacondaInstallerISOTree {
p := &AnacondaISOTree{
p := &AnacondaInstallerISOTree{
Base: NewBase(m, "bootiso-tree", buildPipeline),
anacondaPipeline: anacondaPipeline,
rootfsPipeline: rootfsPipeline,
@ -77,7 +77,7 @@ func NewAnacondaISOTree(m *Manifest,
return p
}
func (p *AnacondaISOTree) getOSTreeCommitSources() []ostree.SourceSpec {
func (p *AnacondaInstallerISOTree) getOSTreeCommitSources() []ostree.SourceSpec {
if p.OSTreeCommitSource == nil {
return nil
}
@ -87,14 +87,14 @@ func (p *AnacondaISOTree) getOSTreeCommitSources() []ostree.SourceSpec {
}
}
func (p *AnacondaISOTree) getOSTreeCommits() []ostree.CommitSpec {
func (p *AnacondaInstallerISOTree) getOSTreeCommits() []ostree.CommitSpec {
if p.ostreeCommitSpec == nil {
return nil
}
return []ostree.CommitSpec{*p.ostreeCommitSpec}
}
func (p *AnacondaISOTree) getBuildPackages(Distro) []string {
func (p *AnacondaInstallerISOTree) getBuildPackages(_ Distro) []string {
packages := []string{
"squashfs-tools",
}
@ -110,7 +110,7 @@ func (p *AnacondaISOTree) getBuildPackages(Distro) []string {
return packages
}
func (p *AnacondaISOTree) serializeStart(_ []rpmmd.PackageSpec, _ []container.Spec, commits []ostree.CommitSpec) {
func (p *AnacondaInstallerISOTree) serializeStart(_ []rpmmd.PackageSpec, _ []container.Spec, commits []ostree.CommitSpec) {
if len(commits) == 0 {
// nothing to do
return
@ -123,28 +123,32 @@ func (p *AnacondaISOTree) serializeStart(_ []rpmmd.PackageSpec, _ []container.Sp
p.ostreeCommitSpec = &commits[0]
}
func (p *AnacondaISOTree) serializeEnd() {
func (p *AnacondaInstallerISOTree) serializeEnd() {
p.ostreeCommitSpec = nil
}
func (p *AnacondaISOTree) serialize() osbuild.Pipeline {
// We need one of two payloads
if p.ostreeCommitSpec == nil && p.OSPipeline == nil {
panic("missing ostree or ospipeline parameters in ISO tree pipeline")
}
func (p *AnacondaInstallerISOTree) serialize() osbuild.Pipeline {
// If the anaconda pipeline is a payload then we need one of two payload types
if p.anacondaPipeline.Type == AnacondaInstallerTypePayload {
if p.ostreeCommitSpec == nil && p.OSPipeline == nil {
panic("missing ostree or ospipeline parameters in ISO tree pipeline")
}
// But not both payloads
if p.ostreeCommitSpec != nil && p.OSPipeline != nil {
panic("got both ostree and ospipeline parameters in ISO tree pipeline")
// But not both payloads
if p.ostreeCommitSpec != nil && p.OSPipeline != nil {
panic("got both ostree and ospipeline parameters in ISO tree pipeline")
}
}
pipeline := p.Base.serialize()
kernelOpts := []string{}
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.stage2=hd:LABEL=%s", p.isoLabel))
if p.KSPath != "" {
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", p.isoLabel, p.KSPath))
if p.anacondaPipeline.Type == AnacondaInstallerTypePayload {
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.stage2=hd:LABEL=%s", p.isoLabel))
if p.KSPath != "" {
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", p.isoLabel, p.KSPath))
}
}
if len(p.KernelOpts) > 0 {
@ -162,6 +166,16 @@ func (p *AnacondaISOTree) serialize() osbuild.Pipeline {
},
}))
if p.anacondaPipeline.Type == AnacondaInstallerTypeLive {
pipeline.AddStage(osbuild.NewMkdirStage(&osbuild.MkdirStageOptions{
Paths: []osbuild.MkdirStagePath{
{
Path: "LiveOS",
},
},
}))
}
inputName := "tree"
copyStageOptions := &osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{
@ -179,8 +193,16 @@ func (p *AnacondaISOTree) serialize() osbuild.Pipeline {
copyStage := osbuild.NewCopyStageSimple(copyStageOptions, copyStageInputs)
pipeline.AddStage(copyStage)
squashfsOptions := osbuild.SquashfsStageOptions{
Filename: "images/install.img",
var squashfsOptions osbuild.SquashfsStageOptions
if p.anacondaPipeline.Type == AnacondaInstallerTypePayload {
squashfsOptions = osbuild.SquashfsStageOptions{
Filename: "images/install.img",
}
} else if p.anacondaPipeline.Type == AnacondaInstallerTypeLive {
squashfsOptions = osbuild.SquashfsStageOptions{
Filename: "LiveOS/squashfs.img",
}
}
if p.SquashfsCompression != "" {

View file

@ -15,7 +15,7 @@ type ISOLinuxProduct struct {
type ISOLinuxKernel struct {
Dir string `json:"dir"`
Opts []string `json:"opts,omitempty"`
Opts []string `json:"opts"`
}
func NewISOLinuxStage(options *ISOLinuxStageOptions, inputPipeline string) *Stage {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -698,6 +698,18 @@
"no-image-info": true,
"overrides": {}
},
"live-installer": {
"compose-request": {
"distro": "",
"arch": "",
"image-type": "live-installer",
"repositories": [],
"filename": "installer.iso",
"blueprint": {}
},
"no-image-info": true,
"overrides": {}
},
"image-installer-with-users": {
"compose-request": {
"distro": "",