mirror of
https://github.com/kairos-io/osbuilder.git
synced 2025-08-11 04:32:10 +00:00
Add support for bundles and custom grub config
This commit is contained in:
parent
c942642495
commit
b3e7dcbf59
@ -35,7 +35,30 @@ type OSArtifactSpec struct {
|
|||||||
CloudConfig string `json:"cloudConfig,omitempty"`
|
CloudConfig string `json:"cloudConfig,omitempty"`
|
||||||
GRUBConfig string `json:"grubConfig,omitempty"`
|
GRUBConfig string `json:"grubConfig,omitempty"`
|
||||||
|
|
||||||
PullFromKube bool `json:"pullFromKube,omitempty"`
|
Bundles []string `json:"bundles,omitempty"`
|
||||||
|
PullOptions Pull `json:"pull,omitempty"`
|
||||||
|
PushOptions Push `json:"push,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Push struct {
|
||||||
|
Push bool `json:"push,omitempty"`
|
||||||
|
ImageName string `json:"imageName,omitempty"`
|
||||||
|
ContainerRegistryCredentials *SecretKeySelector `json:"containerRegistryCredentials,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pull struct {
|
||||||
|
ContainerRegistryCredentials *SecretKeySelector `json:"containerRegistryCredentials,omitempty"`
|
||||||
|
}
|
||||||
|
type LocalObjectReference struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecretKeySelector struct {
|
||||||
|
LocalObjectReference `json:",inline"`
|
||||||
|
// +optional
|
||||||
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
// +optional
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSArtifactStatus defines the observed state of OSArtifact
|
// OSArtifactStatus defines the observed state of OSArtifact
|
||||||
|
@ -25,12 +25,27 @@ import (
|
|||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *LocalObjectReference) DeepCopyInto(out *LocalObjectReference) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalObjectReference.
|
||||||
|
func (in *LocalObjectReference) DeepCopy() *LocalObjectReference {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(LocalObjectReference)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *OSArtifact) DeepCopyInto(out *OSArtifact) {
|
func (in *OSArtifact) DeepCopyInto(out *OSArtifact) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.TypeMeta = in.TypeMeta
|
out.TypeMeta = in.TypeMeta
|
||||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
out.Spec = in.Spec
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
out.Status = in.Status
|
out.Status = in.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +102,13 @@ func (in *OSArtifactList) DeepCopyObject() runtime.Object {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *OSArtifactSpec) DeepCopyInto(out *OSArtifactSpec) {
|
func (in *OSArtifactSpec) DeepCopyInto(out *OSArtifactSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
if in.Bundles != nil {
|
||||||
|
in, out := &in.Bundles, &out.Bundles
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
in.PullOptions.DeepCopyInto(&out.PullOptions)
|
||||||
|
in.PushOptions.DeepCopyInto(&out.PushOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSArtifactSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSArtifactSpec.
|
||||||
@ -113,3 +135,59 @@ func (in *OSArtifactStatus) DeepCopy() *OSArtifactStatus {
|
|||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Pull) DeepCopyInto(out *Pull) {
|
||||||
|
*out = *in
|
||||||
|
if in.ContainerRegistryCredentials != nil {
|
||||||
|
in, out := &in.ContainerRegistryCredentials, &out.ContainerRegistryCredentials
|
||||||
|
*out = new(SecretKeySelector)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Pull.
|
||||||
|
func (in *Pull) DeepCopy() *Pull {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Pull)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Push) DeepCopyInto(out *Push) {
|
||||||
|
*out = *in
|
||||||
|
if in.ContainerRegistryCredentials != nil {
|
||||||
|
in, out := &in.ContainerRegistryCredentials, &out.ContainerRegistryCredentials
|
||||||
|
*out = new(SecretKeySelector)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Push.
|
||||||
|
func (in *Push) DeepCopy() *Push {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Push)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
|
||||||
|
*out = *in
|
||||||
|
out.LocalObjectReference = in.LocalObjectReference
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector.
|
||||||
|
func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SecretKeySelector)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
@ -35,7 +35,15 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
description: OSArtifactSpec defines the desired state of OSArtifact
|
description: OSArtifactSpec defines the desired state of OSArtifact
|
||||||
properties:
|
properties:
|
||||||
|
bundles:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
cloudConfig:
|
cloudConfig:
|
||||||
|
description: 'TODO: treat cloudconfig as a secret, and take a secretRef
|
||||||
|
where to store it (optionally)'
|
||||||
|
type: string
|
||||||
|
grubConfig:
|
||||||
type: string
|
type: string
|
||||||
imageName:
|
imageName:
|
||||||
description: Foo is an example field of OSArtifact. Edit osartifact_types.go
|
description: Foo is an example field of OSArtifact. Edit osartifact_types.go
|
||||||
@ -43,6 +51,38 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
iso:
|
iso:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
pull:
|
||||||
|
properties:
|
||||||
|
containerRegistryCredentials:
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
push:
|
||||||
|
properties:
|
||||||
|
containerRegistryCredentials:
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
imageName:
|
||||||
|
type: string
|
||||||
|
push:
|
||||||
|
type: boolean
|
||||||
|
type: object
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: OSArtifactStatus defines the observed state of OSArtifact
|
description: OSArtifactStatus defines the observed state of OSArtifact
|
||||||
|
@ -31,6 +31,78 @@ func genDeploymentLabel(s string) map[string]string {
|
|||||||
"osbuild": "workload" + s,
|
"osbuild": "workload" + s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Handle registry auth
|
||||||
|
// TODO: This shells out, but needs ENV_VAR with key refs mapping
|
||||||
|
func unpackContainer(id, containerImage, pullImage string, pullOptions buildv1alpha1.Pull) v1.Container {
|
||||||
|
return v1.Container{
|
||||||
|
ImagePullPolicy: v1.PullAlways,
|
||||||
|
Name: fmt.Sprintf("pull-image-%s", id),
|
||||||
|
Image: containerImage,
|
||||||
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
|
Args: []string{
|
||||||
|
fmt.Sprintf(
|
||||||
|
"luet util unpack %s %s",
|
||||||
|
pullImage,
|
||||||
|
"/rootfs",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "rootfs",
|
||||||
|
MountPath: "/rootfs",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createImageContainer(containerImage string, pushOptions buildv1alpha1.Push) v1.Container {
|
||||||
|
return v1.Container{
|
||||||
|
ImagePullPolicy: v1.PullAlways,
|
||||||
|
Name: "create-image",
|
||||||
|
Image: containerImage,
|
||||||
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
|
Args: []string{
|
||||||
|
fmt.Sprintf(
|
||||||
|
"tar -czvpf test.tar -C /rootfs . && luet util pack %s test.tar image.tar && mv image.tar /public",
|
||||||
|
pushOptions.ImageName,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
{
|
||||||
|
Name: "rootfs",
|
||||||
|
MountPath: "/rootfs",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "public",
|
||||||
|
MountPath: "/public",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func pushImageContainer(containerImage string, pushOptions buildv1alpha1.Push) v1.Container {
|
||||||
|
return v1.Container{
|
||||||
|
ImagePullPolicy: v1.PullAlways,
|
||||||
|
Name: "push-image",
|
||||||
|
Image: containerImage,
|
||||||
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
|
Args: []string{
|
||||||
|
fmt.Sprintf(
|
||||||
|
"skopeo /public/image.tar %s",
|
||||||
|
pushOptions.ImageName,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
VolumeMounts: []v1.VolumeMount{
|
||||||
|
|
||||||
|
{
|
||||||
|
Name: "public",
|
||||||
|
MountPath: "/public",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact) *appsv1.Deployment {
|
func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact) *appsv1.Deployment {
|
||||||
objMeta := metav1.ObjectMeta{
|
objMeta := metav1.ObjectMeta{
|
||||||
Name: artifact.Name,
|
Name: artifact.Name,
|
||||||
@ -38,8 +110,11 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
|
|||||||
OwnerReferences: genOwner(artifact),
|
OwnerReferences: genOwner(artifact),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pushImage := artifact.Spec.PushOptions.Push
|
||||||
|
|
||||||
privileged := false
|
privileged := false
|
||||||
serviceAccount := false
|
serviceAccount := false
|
||||||
|
|
||||||
buildIsoContainer := v1.Container{
|
buildIsoContainer := v1.Container{
|
||||||
ImagePullPolicy: v1.PullAlways,
|
ImagePullPolicy: v1.PullAlways,
|
||||||
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
|
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
|
||||||
@ -48,9 +123,8 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
|
|||||||
Command: []string{"/bin/bash", "-cxe"},
|
Command: []string{"/bin/bash", "-cxe"},
|
||||||
Args: []string{
|
Args: []string{
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"elemental --debug --name %s build-iso --date=false --overlay-iso /iso/iso-overlay %s --output /public",
|
"elemental --debug --name %s build-iso --date=false --overlay-iso /iso/iso-overlay --output /public dir:/rootfs",
|
||||||
artifact.Name,
|
artifact.Name,
|
||||||
artifact.Spec.ImageName,
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
VolumeMounts: []v1.VolumeMount{
|
VolumeMounts: []v1.VolumeMount{
|
||||||
@ -64,35 +138,10 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
|
|||||||
SubPath: "config",
|
SubPath: "config",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "grub",
|
Name: "config",
|
||||||
MountPath: "/iso/iso-overlay/boot/grub2/grub.cfg",
|
MountPath: "/iso/iso-overlay/boot/grub2/grub.cfg",
|
||||||
SubPath: "grub.cfg",
|
SubPath: "grub.cfg",
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if artifact.Spec.PullFromKube {
|
|
||||||
buildIsoContainer.Args = []string{
|
|
||||||
fmt.Sprintf(
|
|
||||||
"elemental --debug --name %s build-iso --date=false --overlay-iso /iso/iso-overlay --output /public /rootfs",
|
|
||||||
artifact.Name,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pullContainer := v1.Container{
|
|
||||||
ImagePullPolicy: v1.PullAlways,
|
|
||||||
Name: "build-iso",
|
|
||||||
Image: artifact.Spec.ImageName,
|
|
||||||
Command: []string{"/bin/bash", "-cxe"},
|
|
||||||
Args: []string{
|
|
||||||
fmt.Sprintf(
|
|
||||||
"rsync -aqAX --exclude='mnt' --exclude='proc' --exclude='sys' --exclude='dev' --exclude='tmp' %s %s",
|
|
||||||
"/",
|
|
||||||
"/rootfs",
|
|
||||||
),
|
|
||||||
},
|
|
||||||
VolumeMounts: []v1.VolumeMount{
|
|
||||||
{
|
{
|
||||||
Name: "rootfs",
|
Name: "rootfs",
|
||||||
MountPath: "/rootfs",
|
MountPath: "/rootfs",
|
||||||
@ -134,11 +183,19 @@ func (r *OSArtifactReconciler) genDeployment(artifact buildv1alpha1.OSArtifact)
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pod.InitContainers = []v1.Container{buildIsoContainer}
|
pod.InitContainers = []v1.Container{unpackContainer("baseimage", r.ToolImage, artifact.Spec.ImageName, artifact.Spec.PullOptions)}
|
||||||
if artifact.Spec.PullFromKube {
|
|
||||||
// pull first
|
for i, bundle := range artifact.Spec.Bundles {
|
||||||
pod.InitContainers = append([]v1.Container{pullContainer}, pod.InitContainers...)
|
pod.InitContainers = append(pod.InitContainers, unpackContainer(fmt.Sprint(i), r.ToolImage, bundle, artifact.Spec.PullOptions))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pod.InitContainers = append(pod.InitContainers, buildIsoContainer)
|
||||||
|
|
||||||
|
if pushImage {
|
||||||
|
pod.InitContainers = append(pod.InitContainers, createImageContainer(r.ToolImage, artifact.Spec.PushOptions))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pod.Containers = []v1.Container{servingContainer}
|
pod.Containers = []v1.Container{servingContainer}
|
||||||
|
|
||||||
deploymentLabels := genDeploymentLabel(artifact.Name)
|
deploymentLabels := genDeploymentLabel(artifact.Name)
|
||||||
|
@ -38,9 +38,9 @@ import (
|
|||||||
// OSArtifactReconciler reconciles a OSArtifact object
|
// OSArtifactReconciler reconciles a OSArtifact object
|
||||||
type OSArtifactReconciler struct {
|
type OSArtifactReconciler struct {
|
||||||
client.Client
|
client.Client
|
||||||
Scheme *runtime.Scheme
|
Scheme *runtime.Scheme
|
||||||
clientSet *kubernetes.Clientset
|
clientSet *kubernetes.Clientset
|
||||||
ServingImage, BuildImage string
|
ServingImage, BuildImage, ToolImage string
|
||||||
}
|
}
|
||||||
|
|
||||||
func genOwner(artifact buildv1alpha1.OSArtifact) []metav1.OwnerReference {
|
func genOwner(artifact buildv1alpha1.OSArtifact) []metav1.OwnerReference {
|
||||||
|
7
main.go
7
main.go
@ -52,10 +52,12 @@ func main() {
|
|||||||
var metricsAddr string
|
var metricsAddr string
|
||||||
var enableLeaderElection bool
|
var enableLeaderElection bool
|
||||||
var probeAddr string
|
var probeAddr string
|
||||||
var buildImage, serveImage string
|
var buildImage, serveImage, toolImage string
|
||||||
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
|
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
|
||||||
flag.StringVar(&buildImage, "build-image", "quay.io/costoolkit/elemental-cli:v0.0.15-8a78e6b", "Build image.")
|
flag.StringVar(&buildImage, "build-image", "quay.io/costoolkit/elemental-cli:v0.0.15-ae4f000", "Build image.")
|
||||||
flag.StringVar(&serveImage, "serve-image", "nginx", "Serve image.")
|
flag.StringVar(&serveImage, "serve-image", "nginx", "Serve image.")
|
||||||
|
// It needs luet inside
|
||||||
|
flag.StringVar(&toolImage, "tool-image", "quay.io/c3os/core-alpine:v0.57.0", "Tool image.")
|
||||||
|
|
||||||
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
||||||
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
|
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
|
||||||
@ -96,6 +98,7 @@ func main() {
|
|||||||
if err = (&controllers.OSArtifactReconciler{
|
if err = (&controllers.OSArtifactReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
ServingImage: serveImage,
|
ServingImage: serveImage,
|
||||||
|
ToolImage: toolImage,
|
||||||
BuildImage: buildImage,
|
BuildImage: buildImage,
|
||||||
Scheme: mgr.GetScheme(),
|
Scheme: mgr.GetScheme(),
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
|
47
tests/fixtures/simple.yaml
vendored
47
tests/fixtures/simple.yaml
vendored
@ -4,4 +4,49 @@ metadata:
|
|||||||
name: hello-c3os
|
name: hello-c3os
|
||||||
spec:
|
spec:
|
||||||
imageName: "quay.io/c3os/c3os:opensuse-latest"
|
imageName: "quay.io/c3os/c3os:opensuse-latest"
|
||||||
iso: true
|
iso: true
|
||||||
|
bundles:
|
||||||
|
- quay.io/c3os/packages:goreleaser-utils-1.11.1
|
||||||
|
grubConfig: |
|
||||||
|
search --file --set=root /boot/kernel.xz
|
||||||
|
set default=0
|
||||||
|
set timeout=10
|
||||||
|
set timeout_style=menu
|
||||||
|
set linux=linux
|
||||||
|
set initrd=initrd
|
||||||
|
if [ "${grub_cpu}" = "x86_64" -o "${grub_cpu}" = "i386" -o "${grub_cpu}" = "arm64" ];then
|
||||||
|
if [ "${grub_platform}" = "efi" ]; then
|
||||||
|
if [ "${grub_cpu}" != "arm64" ]; then
|
||||||
|
set linux=linuxefi
|
||||||
|
set initrd=initrdefi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "${grub_platform}" = "efi" ]; then
|
||||||
|
echo "Please press 't' to show the boot menu on this console"
|
||||||
|
fi
|
||||||
|
set font=($root)/boot/${grub_cpu}/loader/grub2/fonts/unicode.pf2
|
||||||
|
if [ -f ${font} ];then
|
||||||
|
loadfont ${font}
|
||||||
|
fi
|
||||||
|
menuentry "install" --class os --unrestricted {
|
||||||
|
echo Loading kernel...
|
||||||
|
$linux ($root)/boot/kernel.xz cdroot root=live:CDLABEL=COS_LIVE rd.live.dir=/ rd.live.squashimg=rootfs.squashfs console=tty1 console=ttyS0 rd.cos.disable vga=795 nomodeset nodepair.enable
|
||||||
|
echo Loading initrd...
|
||||||
|
$initrd ($root)/boot/rootfs.xz
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "${grub_platform}" = "efi" ]; then
|
||||||
|
hiddenentry "Text mode" --hotkey "t" {
|
||||||
|
set textmode=true
|
||||||
|
terminal_output console
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
cloudConfig: |
|
||||||
|
#node-config
|
||||||
|
install:
|
||||||
|
device: "/dev/sda"
|
||||||
|
reboot: true
|
||||||
|
poweroff: true
|
||||||
|
auto: true # Required, for automated installations
|
Loading…
Reference in New Issue
Block a user