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" ImageTypesIotRawImage ImageTypes = "iot-raw-image"
ImageTypesLiveInstaller ImageTypes = "live-installer"
ImageTypesVsphere ImageTypes = "vsphere" ImageTypesVsphere ImageTypes = "vsphere"
ImageTypesVsphereOva ImageTypes = "vsphere-ova" ImageTypesVsphereOva ImageTypes = "vsphere-ova"
@ -938,73 +940,73 @@ var swaggerSpec = []string{
"A5fdV16XqFvYruZnmoUF0oTHNqYTpRd2bO/+6wPS/6OVi1TS3i+X2dfndjiSrdSMk0HKHxBm8zf5b9Q9", "A5fdV16XqFvYruZnmoUF0oTHNqYTpRd2bO/+6wPS/6OVi1TS3i+X2dfndjiSrdSMk0HKHxBm8zf5b9Q9",
"qFglaWJtHUiIky5BlQ3Uv4arsIujUOg3H1zMELl/ny7mCMogIlIcBiBZDpheQ7ExzU/VJ2QzKiTr/+lj", "qFglaWJtHUiIky5BlQ3Uv4arsIujUOg3H1zMELl/ny7mCMogIlIcBiBZDpheQ7ExzU/VJ2QzKiTr/+lj",
"5v8dVpQHRQxbvBjjsNhQcCGHgQues2COWR4OnmJ/cuhGj+8+Mn5xOYJuPfEl+RDrh3QT5aJqruApTAgF", "5v8dVpQHRQxbvBjjsNhQcCGHgQues2COWR4OnmJ/cuhGj+8+Mn5xOYJuPfEl+RDrh3QT5aJqruApTAgF",
"LzDhAtq2emFqrv//EIApZTJSGurfRAdMxRq+/7AGL583GzO4iMDNuSsNwvVfOTqHqTTsBZVL6ZUFa41w", "LzDhAtq2emFqrv//EIApZTJSGurfRAdMxRq+/7AGL583GzO4iMDNuSsNwvVfOTqHmWzGxvP4KGlE7QWl",
"7ich29L0y7Ug32GsqrRhsme5WC4WT4r1fDHVAENs7vuK2wnSGZ3ilOyofG15k0PyypDPNtVutZxNyTHO", "TOmlBmsVce5nJdvSFsy1IN9hvao8YrJnuVguFk+K9Xwx1SJDbO47j9sZ0xmd4pR0qXxteZNDEs2Qzzb1",
"EeNbNWiV/QdcAvTXQwVZzjXENVXSFHRUtpmy08jtOqglIqrEcCvCQ3zm8FvuAr9L8SihO4Q6aYHrMOqV", "cLWcTUk6zhHjW0Vplf0nXgL010MFac81xDVV0jR2VMeZsvXI/TsoLiKq5nAr5EN8bvFb7gK/SxMpKTyE",
"BDnDJD0IF56YTEnuBg729hdBBbTTPm1QQQ2ajY5a+icc/c7ZnUGwbCbYalIzwYiI1JKOpjp1pZzJLMDq", "OmmR7DAMlgQ5wyQ9KhceoUzJ9gYe9/YXQQW00z5tUEENmo3OXvpHHv3O2Z1RsWwm2HtSU8OIiNQaj6Y6",
"aFY2cvOkU2kgoVnSrA+g5EHXcW2MAoPznx6z/yk7cCSkW7hAtp0dE987TSRvJTAnKNZUybN8euWJH+VK", "hqW8yyzA6qxWNvL7pJdpIKFZ0s4PoORB13FtjAIL9J8es/8pO3AkpJ+4QLadHRPfXU1kcyUwJ6jeVNm0",
"iblBImEhrNJfMKg7Bb8EC30KiuXjYnVS1uExOqlVJ3qlOmlMGmXYqNRQDdbrenlyXDQM+GvWj81MGCSa", "fHopih/2SgnCQSJhIazyYTAoRAW/BAt9Corl42J1UtbhMTqpVSd6pTppTBpl2KjUUA3W63p5clw0DPhr",
"lbPxDAEWFWit4TEL2evqD6n+ft1wwLZbpKsQY7sQ9IBuFnf2xwjPkEDMwQRx6TAHpPG9usSpFwcSaCIG", "1g/WTBgkmpWz8QwBFlVsreExC9nrchCpD3/d8Mi2W6SrEGO7MvSAbhZ39gcNz5BAzMEEcelBB6Tx3bzE",
"ftEg0W3kYulm6ogILFb+oTuf/YCgykL2PQr1ITRA8qBNCfccxIAmmUsVkW2m6CEHmo0RERttLETGJOKl", "MRgHEmgiBn7RINFt5GLpd+qICCxW/ik8n/2AoMpk9l0M9SG0SPKgTQn3HMSAJplLVZVt5uwhB5qNEREb",
"iA+k9x4y1o7jejuPzG3z/0YAfksQrGAptk3AdBnfIfxpZY2ByKoR0mRzs1o51XJNRQK5dMeXncUnsU1r", "bSxExiTipYgPpDsfMtaO83s7z9Bt8/9GRH5LEKxgKbZtwnQZ3yH8aXWOgciqEdJkc7N8OdWUTUUCuXTH",
"e3fCpqPXdn0iMLScdzggKR9iG82e0z2+MblzN8n6RIhwlBZYssIryfvrb5KHDGx6fnojPyZNASRMoU4e", "l53VKLFNa3t3wqaj13Z9IjA0pXd4JCkfYhvNnuM+vnW5czfJ+kSIcJQmWbLkK8n762+Shwxsen6+Iz8m",
"BnGHL0FF2BfpgEdFQuopKE76AtZrosIYYzJBa6dTRdAcykKIDoAMbfqklOl+qMNlSEO60imYq0qU6NSq", "TQEkTKGOIgaBiC9BidgX6ZFHVUPqKahW+gLWa6LiGmMyQWsvVIXUHMpCiA6ADG06qZTpfuzDZUhDutIp",
"HFfKyoTOUVrSIVa69vdVrH26Qm1f8kJluYHpmkHRafJs5lqvRNpghwJYV69t5C7uLsAMraICDMm+66IO", "mKvSlOgYqxxXysqEzlFaFiJWy/b3lbB9umRtXzZDpb2B6ZpBFWrysOZar0TaYIcCWJezbSQz7i7ADK2i",
"FTNN6q+E7s7J/1qdi+4NuLu4A3cPretuG/Q6L6B1fdvuqc9jMibOffemddHUhhptdZpn10bj5XKG3q+O", "igzJvusqDxVETeqvhO7Oyf9anYvuDbi7uAN3D63rbhv0Oi+gdX3b7qnPYzImzn33pnXR1IYabXWaZ9dG",
"oW73XxZ1eHHRta+gLRpX0/Ky0Cr3jqyu0fWWF8J9nNbRmFwPzLOH+vEUjmru41nNOe9fVdwZImhQ0EbO", "4+Vyht6vjqFu918WdXhx0bWvoC0aV9PystAq946srtH1lhfCfZzW0ZhcD8yzh/rxFI5q7uNZzTnvX1Xc",
"29v97GZ1z63nMr1/XnTeH4aTUvum3zbaF+bsuXFfHpP31xnram12XrwvL1hvYkNPtx6O8CMkzTPulBov", "GSJoUNBGztvb/exmdc+t5zK9f1503h+Gk1L7pt822hfm7LlxXx6T99cZ62ptdl68Ly9Yb2JDT7cejvAj",
"nTc+qTUfKnVdPLB+5f5FfzJPBkfP+M54bAzGpNeajoqV+WPrVu8P+Uvl5Bq2yXHXLd3O3Ua3Qwtd1Hl8", "JM0z7pQaL503Pqk1Hyp1XTywfuX+RX8yTwZHz/jOeGwMxqTXmo6Klflj61bvD/lL5eQatslx1y3dzt1G",
"Kb057du7JuwVJ1eXFc8wq20PzfjRaDgmi/unEWpfL73X6+Pb/jO9vest5v17YzkxS89njbn3WuyJaUG7", "t0MLXdR5fCm9Oe3buybsFSdXlxXPMKttD8340Wg4Jov7pxFqXy+91+vj2/4zvb3rLeb9e2M5MUvPZ425",
"uSwvoVdcOrzpnVxeuWg2v70bLO0xWb2J6erVYPQRo/OVu3g15/cLQUi/UTCHHa9w9ThiL8Va2ek8jOpt", "91rsiWlBu7ksL6FXXDq86Z1cXrloNr+9GyztMVm9ienq1WD0EaPzlbt4Nef3C0FIv1Ewhx2vcPU4Yi/F",
"bVKvzrTL89G50Z/ZZHZRGJOi8VBtDmCtWL2sLKfFmZigyryn3T3Tu1uv13rkl8N5sfhw8dJc3SFvddSo", "WtnpPIzqbW1Sr860y/PRudGf2WR2URiTovFQbQ5grVi9rCynxZmYoMq8p90907tbr9d65JfDebH4cPHS",
"aw+Fl47Vr88qw8fedEyOUffVXOH+bXFhl14uzgY9zbMXM37SPPLsmVmio0mVV96d1/ldsX5BR8unankK", "XN0hb3XUqGsPhZeO1a/PKsPH3nRMjlH31Vzh/m1xYZdeLs4GPc2zFzN+0jzy7JlZoqNJlVfendf5XbF+",
"e7Wn4dGN9YrQmDSOi8/00ZpopZ47PJoar3TKWUe8Nu4mD69HL/PzxsBl+lOTTS8nV7PylTvoNZcja8nv", "QUfLp2p5Cnu1p+HRjfWK0Jg0jovP9NGaaKWeOzyaGq90yllHvDbuJg+vRy/z88bAZfpTk00vJ1ez8pU7",
"m7xlXZTGpHjtLctPsN8qmuVu7U7r61cF7W1Kiw1NY9PWs4eXTwzXsHfSf3Ybb6OCMXy/cbjeNUmj8Pba", "6DWXI2vJ75u8ZV2UxqR47S3LT7DfKprlbu1O6+tXBe1tSosNTWPT1rOHl08M17B30n92G2+jgjF8v3G4",
"GxPcuPdsw6vXvTfrqbAQ5YkgWJgD/ja1ln1v+vJQfZ1UrZk4b1i9h8Lzc71afrOua71Fc9C8b7bGRJyd", "3jVJo/D22hsT3Lj3bMOr170366mwEOWJIFiYA/42tZZ9b/ryUH2dVK2ZOG9YvYfC83O9Wn6zrmu9RXPQ",
"X7w+Deaa0zF7Z/1Sb9hsvDqPs0nlyroe9UvXz60VfCpZGrGb4Xvt8moOncep3q7Nx0RztCN8f3XbavVb", "vG+2xkScnV+8Pg3mmtMxe2f9Um/YbLw6j7NJ5cq6HvVL18+tFXwqWRqxm+F77fJqDp3Hqd6uzcdEc7Qj",
"7Wazeo47HXR57DDr/LLuPfL7636/XHypaa8WWb40zpuOkqH2xaJx3l7MumPSWnQvzu/pVbvJ263WS7u5", "fH9122r1W+1ms3qOOx10eeww6/yy7j3y++t+v1x8qWmvFlm+NM6bjpKh9sWicd5ezLpj0lp0L87v6VW7",
"6LQvzU77vNpsts3Z/br30c1Ls1BvvbimvRo2X18uremqZ41J4cg4fr8zHueTy3Kx81aZdeu3562bIrl+", "ydut1ku7uei0L81O+7zabLbN2f2699HNS7NQb724pr0aNl9fLq3pqmeNSeHIOH6/Mx7nk8tysfNWmXXr",
"Pmo9lBxvPjx6G3nDytM1a1WcyoVnC7c36Fz1roVT65yNSYldvD836ai0ck9euo3r5pneb7dvV9PmlNOn", "t+etmyK5fj5qPZQcbz48eht5w8rTNWtVnMqFZwu3N+hc9a6FU+ucjUmJXbw/N+motHJPXrqN6+aZ3m+3",
"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",
"RhGRhFcxRcPsg/P1+/8fAAD//4yZSqt0egAA", "A3ABTfQvDqOISMK7maJh9sH5+v3/DwAA//8ido22hXoAAA==",
} }
// GetSwagger returns the content of the embedded swagger specification file // GetSwagger returns the content of the embedded swagger specification file

View file

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

View file

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

View file

@ -80,6 +80,23 @@ var (
exports: []string{"bootiso"}, 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{ iotCommitImgType = imageType{
name: "iot-commit", name: "iot-commit",
nameAliases: []string{"fedora-iot-commit"}, nameAliases: []string{"fedora-iot-commit"},
@ -578,6 +595,7 @@ func newDistro(version int) distro.Distro {
iotCommitImgType, iotCommitImgType,
iotInstallerImgType, iotInstallerImgType,
imageInstallerImgType, imageInstallerImgType,
liveInstallerImgType,
) )
x86_64.addImageTypes( x86_64.addImageTypes(
&platform.X86{ &platform.X86{

View file

@ -152,6 +152,14 @@ func TestFilenameFromType(t *testing.T) {
mimeType: "application/x-iso9660-image", 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", name: "image-installer",
args: args{"image-installer"}, args: args{"image-installer"},
@ -282,6 +290,7 @@ func TestImageType_Name(t *testing.T) {
"iot-raw-image", "iot-raw-image",
"oci", "oci",
"image-installer", "image-installer",
"live-installer",
"minimal-raw", "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)) 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" { } 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)) 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" { } 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)) assert.EqualError(t, err, fmt.Sprintf("unsupported blueprint customizations found for image type %q: (allowed: User, Group, Directories, Files, Services)", imgTypeName))
} else { } else {
@ -461,6 +472,7 @@ func TestArchitecture_ListImageTypes(t *testing.T) {
"oci", "oci",
"container", "container",
"image-installer", "image-installer",
"live-installer",
"minimal-raw", "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)) 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" { } else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue 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 { } else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/etc\"]") 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)) 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" { } else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue 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 { } else {
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -644,6 +660,8 @@ func TestDistro_CustomFileSystemSubDirectories(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") { if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") {
continue 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 { } else {
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -682,6 +700,8 @@ func TestDistro_MountpointsWithArbitraryDepthAllowed(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") { if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") {
continue 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 { } else {
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -716,6 +736,8 @@ func TestDistro_DirtyMountpointsNotAllowed(t *testing.T) {
_, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0) _, _, err := imgType.Manifest(&bp, distro.ImageOptions{}, nil, 0)
if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") { if strings.HasPrefix(imgTypeName, "iot-") || strings.HasPrefix(imgTypeName, "image-") {
continue 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 { } else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"//\" \"/var//\" \"/var//log/audit/\"]") 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)) 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" { } else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue 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 { } else {
assert.EqualError(t, err, "The following custom mountpoints are not supported [\"/variable\" \"/variable/log/audit\"]") 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)) 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" { } else if imgTypeName == "iot-installer" || imgTypeName == "image-installer" {
continue 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 { } else {
assert.NoError(t, err) assert.NoError(t, err)
} }

View file

@ -238,6 +238,44 @@ func containerImage(workload workload.Workload,
return img, nil 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, func imageInstallerImage(workload workload.Workload,
t *imageType, t *imageType,
customizations *blueprint.Customizations, customizations *blueprint.Customizations,
@ -246,7 +284,7 @@ func imageInstallerImage(workload workload.Workload,
containers []container.SourceSpec, containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) { rng *rand.Rand) (image.ImageKind, error) {
img := image.NewImageInstaller() img := image.NewAnacondaTarInstaller()
// Enable anaconda-webui for Fedora > 38 // Enable anaconda-webui for Fedora > 38
distro := t.Arch().Distro() distro := t.Arch().Distro()
@ -343,7 +381,7 @@ func iotInstallerImage(workload workload.Workload,
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error()) return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
} }
img := image.NewOSTreeInstaller(commit) img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey] 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 { 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, ", ")) 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 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 { func imageInstallerPackageSet(t *imageType) rpmmd.PackageSet {
ps := anacondaPackageSet(t) ps := anacondaPackageSet(t)

View file

@ -255,7 +255,7 @@ func imageInstallerImage(workload workload.Workload,
containers []container.SourceSpec, containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) { rng *rand.Rand) (image.ImageKind, error) {
img := image.NewImageInstaller() img := image.NewAnacondaTarInstaller()
img.Platform = t.platform img.Platform = t.platform
img.Workload = workload img.Workload = workload
@ -366,7 +366,7 @@ func edgeInstallerImage(workload workload.Workload,
return nil, fmt.Errorf("%s: %s", t.Name(), err.Error()) return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
} }
img := image.NewOSTreeInstaller(commit) img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey] 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()) return nil, fmt.Errorf("%s: %s", t.Name(), err.Error())
} }
img := image.NewOSTreeInstaller(commit) img := image.NewAnacondaOSTreeInstaller(commit)
img.Platform = t.platform img.Platform = t.platform
img.ExtraBasePackages = packageSets[installerPkgsKey] img.ExtraBasePackages = packageSets[installerPkgsKey]
@ -510,7 +510,7 @@ func imageInstallerImage(workload workload.Workload,
containers []container.SourceSpec, containers []container.SourceSpec,
rng *rand.Rand) (image.ImageKind, error) { rng *rand.Rand) (image.ImageKind, error) {
img := image.NewImageInstaller() img := image.NewAnacondaTarInstaller()
img.Platform = t.platform img.Platform = t.platform
img.Workload = workload 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" "github.com/osbuild/osbuild-composer/internal/users"
) )
type OSTreeInstaller struct { type AnacondaOSTreeInstaller struct {
Base Base
Platform platform.Platform Platform platform.Platform
ExtraBasePackages rpmmd.PackageSet ExtraBasePackages rpmmd.PackageSet
@ -40,21 +40,22 @@ type OSTreeInstaller struct {
AdditionalDrivers []string AdditionalDrivers []string
} }
func NewOSTreeInstaller(commit ostree.SourceSpec) *OSTreeInstaller { func NewAnacondaOSTreeInstaller(commit ostree.SourceSpec) *AnacondaOSTreeInstaller {
return &OSTreeInstaller{ return &AnacondaOSTreeInstaller{
Base: NewBase("ostree-installer"), Base: NewBase("ostree-installer"),
Commit: commit, Commit: commit,
} }
} }
func (img *OSTreeInstaller) InstantiateManifest(m *manifest.Manifest, func (img *AnacondaOSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
repos []rpmmd.RepoConfig, repos []rpmmd.RepoConfig,
runner runner.Runner, runner runner.Runner,
rng *rand.Rand) (*artifact.Artifact, error) { rng *rand.Rand) (*artifact.Artifact, error) {
buildPipeline := manifest.NewBuild(m, runner, repos) buildPipeline := manifest.NewBuild(m, runner, repos)
buildPipeline.Checkpoint() buildPipeline.Checkpoint()
anacondaPipeline := manifest.NewAnaconda(m, anacondaPipeline := manifest.NewAnacondaInstaller(m,
manifest.AnacondaInstallerTypePayload,
buildPipeline, buildPipeline,
img.Platform, img.Platform,
repos, repos,
@ -102,7 +103,7 @@ func (img *OSTreeInstaller) InstantiateManifest(m *manifest.Manifest,
// enable ISOLinux on x86_64 only // enable ISOLinux on x86_64 only
isoLinuxEnabled := img.Platform.GetArch() == platform.ARCH_X86_64 isoLinuxEnabled := img.Platform.GetArch() == platform.ARCH_X86_64
isoTreePipeline := manifest.NewAnacondaISOTree(m, isoTreePipeline := manifest.NewAnacondaInstallerISOTree(m,
buildPipeline, buildPipeline,
anacondaPipeline, anacondaPipeline,
rootfsImagePipeline, rootfsImagePipeline,

View file

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

View file

@ -2,8 +2,10 @@ package manifest
import ( import (
"fmt" "fmt"
"os"
"github.com/osbuild/osbuild-composer/internal/container" "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/osbuild"
"github.com/osbuild/osbuild-composer/internal/ostree" "github.com/osbuild/osbuild-composer/internal/ostree"
"github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/platform"
@ -11,10 +13,23 @@ import (
"github.com/osbuild/osbuild-composer/internal/users" "github.com/osbuild/osbuild-composer/internal/users"
) )
// An Anaconda represents the installer tree as found on an ISO. type AnacondaInstallerType int
type Anaconda struct {
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 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 // Packages to install in addition to the ones required by the
// pipeline. // pipeline.
ExtraPackages []string ExtraPackages []string
@ -53,24 +68,22 @@ type Anaconda struct {
// Additional dracut modules and drivers to enable // Additional dracut modules and drivers to enable
AdditionalDracutModules []string AdditionalDracutModules []string
AdditionalDrivers []string AdditionalDrivers []string
Files []*fsnode.File
} }
// NewAnaconda creates an anaconda pipeline object. repos and packages func NewAnacondaInstaller(m *Manifest,
// indicate the content to build the installer from, which is distinct from the installerType AnacondaInstallerType,
// 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,
buildPipeline *Build, buildPipeline *Build,
platform platform.Platform, platform platform.Platform,
repos []rpmmd.RepoConfig, repos []rpmmd.RepoConfig,
kernelName, kernelName,
product, product,
version string) *Anaconda { version string) *AnacondaInstaller {
name := "anaconda-tree" name := "anaconda-tree"
p := &Anaconda{ p := &AnacondaInstaller{
Base: NewBase(m, name, buildPipeline), Base: NewBase(m, name, buildPipeline),
Type: installerType,
platform: platform, platform: platform,
repos: filterRepos(repos, name), repos: filterRepos(repos, name),
kernelName: kernelName, kernelName: kernelName,
@ -84,7 +97,7 @@ func NewAnaconda(m *Manifest,
// TODO: refactor - what is required to boot and what to build, and // TODO: refactor - what is required to boot and what to build, and
// do they all belong in this pipeline? // do they all belong in this pipeline?
func (p *Anaconda) anacondaBootPackageSet() []string { func (p *AnacondaInstaller) anacondaBootPackageSet() []string {
packages := []string{ packages := []string{
"grub2-tools", "grub2-tools",
"grub2-tools-extra", "grub2-tools-extra",
@ -116,7 +129,7 @@ func (p *Anaconda) anacondaBootPackageSet() []string {
return packages return packages
} }
func (p *Anaconda) getBuildPackages(Distro) []string { func (p *AnacondaInstaller) getBuildPackages(Distro) []string {
packages := p.anacondaBootPackageSet() packages := p.anacondaBootPackageSet()
packages = append(packages, packages = append(packages,
"rpm", "rpm",
@ -125,7 +138,7 @@ func (p *Anaconda) getBuildPackages(Distro) []string {
return packages return packages
} }
func (p *Anaconda) getPackageSetChain(Distro) []rpmmd.PackageSet { func (p *AnacondaInstaller) getPackageSetChain(Distro) []rpmmd.PackageSet {
packages := p.anacondaBootPackageSet() packages := p.anacondaBootPackageSet()
if p.Biosdevname { if p.Biosdevname {
packages = append(packages, "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 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 { if len(p.packageSpecs) > 0 {
panic("double call to serializeStart()") 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 { if len(p.packageSpecs) == 0 {
panic("serializeEnd() call when serialization not in progress") panic("serializeEnd() call when serialization not in progress")
} }
@ -160,10 +173,26 @@ func (p *Anaconda) serializeEnd() {
p.packageSpecs = nil p.packageSpecs = nil
} }
func (p *Anaconda) serialize() osbuild.Pipeline { func (p *AnacondaInstaller) serialize() osbuild.Pipeline {
if len(p.packageSpecs) == 0 { if len(p.packageSpecs) == 0 {
panic("serialization not started") 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 := p.Base.serialize()
pipeline.AddStage(osbuild.NewRPMStage(osbuild.NewRPMStageOptions(p.repos), osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs))) pipeline.AddStage(osbuild.NewRPMStage(osbuild.NewRPMStageOptions(p.repos), osbuild.NewRpmStageSourceFilesInputs(p.packageSpecs)))
@ -181,32 +210,67 @@ func (p *Anaconda) serialize() osbuild.Pipeline {
Password: &rootPassword, Password: &rootPassword,
} }
installUID := 0 var usersStageOptions *osbuild.UsersStageOptions
installGID := 0
installHome := "/root" if p.Type == AnacondaInstallerTypePayload {
installShell := "/usr/libexec/anaconda/run-anaconda" installUID := 0
installPassword := "" installGID := 0
installUser := osbuild.UsersStageOptionsUser{ installHome := "/root"
UID: &installUID, installShell := "/usr/libexec/anaconda/run-anaconda"
GID: &installGID, installPassword := ""
Home: &installHome, installUser := osbuild.UsersStageOptionsUser{
Shell: &installShell, UID: &installUID,
Password: &installPassword, GID: &installGID,
} Home: &installHome,
usersStageOptions := &osbuild.UsersStageOptions{ Shell: &installShell,
Users: map[string]osbuild.UsersStageOptionsUser{ Password: &installPassword,
"root": rootUser, }
"install": installUser,
}, 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.NewUsersStage(usersStageOptions))
pipeline.AddStage(osbuild.NewAnacondaStage(osbuild.NewAnacondaStageOptions(p.AdditionalAnacondaModules))) if p.Type == AnacondaInstallerTypeLive {
pipeline.AddStage(osbuild.NewLoraxScriptStage(&osbuild.LoraxScriptStageOptions{ systemdStageOptions := &osbuild.SystemdStageOptions{
Path: "99-generic/runtime-postinstall.tmpl", EnabledServices: []string{
BaseArch: p.platform.GetArch().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( dracutModules := append(
p.AdditionalDracutModules, p.AdditionalDracutModules,
@ -225,22 +289,24 @@ func (p *Anaconda) serialize() osbuild.Pipeline {
pipeline.AddStage(osbuild.NewDracutStage(dracutOptions)) pipeline.AddStage(osbuild.NewDracutStage(dracutOptions))
pipeline.AddStage(osbuild.NewSELinuxConfigStage(&osbuild.SELinuxConfigStageOptions{State: osbuild.SELinuxStatePermissive})) pipeline.AddStage(osbuild.NewSELinuxConfigStage(&osbuild.SELinuxConfigStageOptions{State: osbuild.SELinuxStatePermissive}))
if p.InteractiveDefaults != nil { if p.Type == AnacondaInstallerTypePayload {
kickstartOptions, err := osbuild.NewKickstartStageOptions( if p.InteractiveDefaults != nil {
"/usr/share/anaconda/interactive-defaults.ks", kickstartOptions, err := osbuild.NewKickstartStageOptions(
p.InteractiveDefaults.TarPath, "/usr/share/anaconda/interactive-defaults.ks",
p.Users, p.InteractiveDefaults.TarPath,
p.Groups, p.Users,
"", p.Groups,
"", "",
"", "",
) "",
)
if err != nil { if err != nil {
panic("failed to create kickstartstage options for interactive defaults") panic("failed to create kickstartstage options for interactive defaults")
}
pipeline.AddStage(osbuild.NewKickstartStage(kickstartOptions))
} }
pipeline.AddStage(osbuild.NewKickstartStage(kickstartOptions))
} }
return pipeline 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 return p.platform
} }
@ -315,3 +381,14 @@ func NewAnacondaInteractiveDefaults(tarPath string) *AnacondaInteractiveDefaults
return i 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" "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 // configuration in terms of a kickstart file, as well as an embedded
// payload to be installed, this payload can either be an ostree // payload to be installed, this payload can either be an ostree
// CommitSpec or OSPipeline for an OS. // CommitSpec or OSPipeline for an OS.
type AnacondaISOTree struct { type AnacondaInstallerISOTree struct {
Base Base
// TODO: review optional and mandatory fields and their meaning // TODO: review optional and mandatory fields and their meaning
@ -27,7 +27,7 @@ type AnacondaISOTree struct {
PartitionTable *disk.PartitionTable PartitionTable *disk.PartitionTable
anacondaPipeline *Anaconda anacondaPipeline *AnacondaInstaller
rootfsPipeline *ISORootfsImg rootfsPipeline *ISORootfsImg
bootTreePipeline *EFIBootTree bootTreePipeline *EFIBootTree
@ -55,14 +55,14 @@ type AnacondaISOTree struct {
ISOLinux bool ISOLinux bool
} }
func NewAnacondaISOTree(m *Manifest, func NewAnacondaInstallerISOTree(m *Manifest,
buildPipeline *Build, buildPipeline *Build,
anacondaPipeline *Anaconda, anacondaPipeline *AnacondaInstaller,
rootfsPipeline *ISORootfsImg, rootfsPipeline *ISORootfsImg,
bootTreePipeline *EFIBootTree, bootTreePipeline *EFIBootTree,
isoLabel string) *AnacondaISOTree { isoLabel string) *AnacondaInstallerISOTree {
p := &AnacondaISOTree{ p := &AnacondaInstallerISOTree{
Base: NewBase(m, "bootiso-tree", buildPipeline), Base: NewBase(m, "bootiso-tree", buildPipeline),
anacondaPipeline: anacondaPipeline, anacondaPipeline: anacondaPipeline,
rootfsPipeline: rootfsPipeline, rootfsPipeline: rootfsPipeline,
@ -77,7 +77,7 @@ func NewAnacondaISOTree(m *Manifest,
return p return p
} }
func (p *AnacondaISOTree) getOSTreeCommitSources() []ostree.SourceSpec { func (p *AnacondaInstallerISOTree) getOSTreeCommitSources() []ostree.SourceSpec {
if p.OSTreeCommitSource == nil { if p.OSTreeCommitSource == nil {
return 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 { if p.ostreeCommitSpec == nil {
return nil return nil
} }
return []ostree.CommitSpec{*p.ostreeCommitSpec} return []ostree.CommitSpec{*p.ostreeCommitSpec}
} }
func (p *AnacondaISOTree) getBuildPackages(Distro) []string { func (p *AnacondaInstallerISOTree) getBuildPackages(_ Distro) []string {
packages := []string{ packages := []string{
"squashfs-tools", "squashfs-tools",
} }
@ -110,7 +110,7 @@ func (p *AnacondaISOTree) getBuildPackages(Distro) []string {
return packages 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 { if len(commits) == 0 {
// nothing to do // nothing to do
return return
@ -123,28 +123,32 @@ func (p *AnacondaISOTree) serializeStart(_ []rpmmd.PackageSpec, _ []container.Sp
p.ostreeCommitSpec = &commits[0] p.ostreeCommitSpec = &commits[0]
} }
func (p *AnacondaISOTree) serializeEnd() { func (p *AnacondaInstallerISOTree) serializeEnd() {
p.ostreeCommitSpec = nil p.ostreeCommitSpec = nil
} }
func (p *AnacondaISOTree) serialize() osbuild.Pipeline { func (p *AnacondaInstallerISOTree) serialize() osbuild.Pipeline {
// We need one of two payloads // If the anaconda pipeline is a payload then we need one of two payload types
if p.ostreeCommitSpec == nil && p.OSPipeline == nil { if p.anacondaPipeline.Type == AnacondaInstallerTypePayload {
panic("missing ostree or ospipeline parameters in ISO tree pipeline") if p.ostreeCommitSpec == nil && p.OSPipeline == nil {
} panic("missing ostree or ospipeline parameters in ISO tree pipeline")
}
// But not both payloads // But not both payloads
if p.ostreeCommitSpec != nil && p.OSPipeline != nil { if p.ostreeCommitSpec != nil && p.OSPipeline != nil {
panic("got both ostree and ospipeline parameters in ISO tree pipeline") panic("got both ostree and ospipeline parameters in ISO tree pipeline")
}
} }
pipeline := p.Base.serialize() pipeline := p.Base.serialize()
kernelOpts := []string{} kernelOpts := []string{}
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.stage2=hd:LABEL=%s", p.isoLabel)) if p.anacondaPipeline.Type == AnacondaInstallerTypePayload {
if p.KSPath != "" { kernelOpts = append(kernelOpts, fmt.Sprintf("inst.stage2=hd:LABEL=%s", p.isoLabel))
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", p.isoLabel, p.KSPath)) if p.KSPath != "" {
kernelOpts = append(kernelOpts, fmt.Sprintf("inst.ks=hd:LABEL=%s:%s", p.isoLabel, p.KSPath))
}
} }
if len(p.KernelOpts) > 0 { 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" inputName := "tree"
copyStageOptions := &osbuild.CopyStageOptions{ copyStageOptions := &osbuild.CopyStageOptions{
Paths: []osbuild.CopyStagePath{ Paths: []osbuild.CopyStagePath{
@ -179,8 +193,16 @@ func (p *AnacondaISOTree) serialize() osbuild.Pipeline {
copyStage := osbuild.NewCopyStageSimple(copyStageOptions, copyStageInputs) copyStage := osbuild.NewCopyStageSimple(copyStageOptions, copyStageInputs)
pipeline.AddStage(copyStage) pipeline.AddStage(copyStage)
squashfsOptions := osbuild.SquashfsStageOptions{ var squashfsOptions osbuild.SquashfsStageOptions
Filename: "images/install.img",
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 != "" { if p.SquashfsCompression != "" {

View file

@ -15,7 +15,7 @@ type ISOLinuxProduct struct {
type ISOLinuxKernel struct { type ISOLinuxKernel struct {
Dir string `json:"dir"` Dir string `json:"dir"`
Opts []string `json:"opts,omitempty"` Opts []string `json:"opts"`
} }
func NewISOLinuxStage(options *ISOLinuxStageOptions, inputPipeline string) *Stage { 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, "no-image-info": true,
"overrides": {} "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": { "image-installer-with-users": {
"compose-request": { "compose-request": {
"distro": "", "distro": "",