blob: 5e2b0822b7dabfca4ca7ee80c5585102ef367287 [file] [log] [blame]
Lorenz Brunae0d90d2019-09-05 17:53:56 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
Tim Windelschmidtc2290c22024-08-15 19:56:00 +020017// mkimage is a tool to generate node disk images.
Mateusz Zalegac71efc92021-09-07 16:46:25 +020018// It can be used both to initialize block devices and to create image
19// files.
20//
Tim Windelschmidt272c8302024-11-05 05:17:44 +010021// The tool takes a path to an EFI payload (--efi), a path to a abloader
22// payload (--abloader) and a path to a system image (--system) as its only
23// required inputs. In addition, an output path must be supplied (--out).
Mateusz Zalegac71efc92021-09-07 16:46:25 +020024// Node parameters file path (--node_parameters) may also be supplied, in
25// which case the file will be copied to the EFI system partition.
26// Partition sizes are fixed and may be overridden by command line flags.
Lorenz Brunae0d90d2019-09-05 17:53:56 +020027package main
28
29import (
Lorenz Brun54a5a052023-10-02 16:40:11 +020030 _ "embed"
Leopold Schabel65493072019-11-06 13:40:44 +000031 "flag"
Serge Bazanski032ca182020-06-09 20:17:13 +020032 "log"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020033 "os"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020034
Tim Windelschmidt9f21f532024-05-07 15:14:20 +020035 "source.monogon.dev/osbase/blkio"
36 "source.monogon.dev/osbase/blockdev"
Tim Windelschmidtc2290c22024-08-15 19:56:00 +020037 "source.monogon.dev/osbase/build/mkimage/osimage"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020038)
39
Lorenz Brunae0d90d2019-09-05 17:53:56 +020040func main() {
Mateusz Zalegac71efc92021-09-07 16:46:25 +020041 // Fill in the image parameters based on flags.
42 var (
Tim Windelschmidt8e19fa42024-11-12 13:39:43 +000043 efiPayload string
44 systemImage string
45 abLoaderPayload string
46 biosBootCodePayload string
47 nodeParams string
48 outputPath string
49 diskUUID string
50 cfg osimage.Params
Mateusz Zalegac71efc92021-09-07 16:46:25 +020051 )
52 flag.StringVar(&efiPayload, "efi", "", "Path to the UEFI payload used")
53 flag.StringVar(&systemImage, "system", "", "Path to the system partition image used")
Tim Windelschmidt272c8302024-11-05 05:17:44 +010054 flag.StringVar(&abLoaderPayload, "abloader", "", "Path to the abloader payload used")
Tim Windelschmidt8e19fa42024-11-12 13:39:43 +000055 flag.StringVar(&biosBootCodePayload, "bios_bootcode", "", "Optional path to the BIOS bootcode which gets placed at the start of the first block of the image. Limited to 440 bytes, padding is not required. It is only used by legacy BIOS boot.")
Mateusz Zalegac71efc92021-09-07 16:46:25 +020056 flag.StringVar(&nodeParams, "node_parameters", "", "Path to Node Parameters to be written to the ESP (default: don't write Node Parameters)")
Lorenz Brunad131882023-06-28 16:42:20 +020057 flag.StringVar(&outputPath, "out", "", "Path to the resulting disk image or block device")
58 flag.Int64Var(&cfg.PartitionSize.Data, "data_partition_size", 2048, "Override the data partition size (default 2048 MiB). Used only when generating image files.")
59 flag.Int64Var(&cfg.PartitionSize.ESP, "esp_partition_size", 128, "Override the ESP partition size (default: 128MiB)")
60 flag.Int64Var(&cfg.PartitionSize.System, "system_partition_size", 1024, "Override the System partition size (default: 1024MiB)")
61 flag.StringVar(&diskUUID, "GUID", "", "Disk GUID marked in the resulting image's partition table (default: randomly generated)")
Leopold Schabel65493072019-11-06 13:40:44 +000062 flag.Parse()
Serge Bazanski032ca182020-06-09 20:17:13 +020063
Mateusz Zalegac71efc92021-09-07 16:46:25 +020064 // Open the input files for osimage.Create, fill in reader objects and
65 // metadata in osimage.Params.
66 // Start with the EFI Payload the OS will boot from.
Lorenz Brunad131882023-06-28 16:42:20 +020067 p, err := blkio.NewFileReader(efiPayload)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020068 if err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +010069 log.Fatalf("while opening the EFI payload at %q: %v", efiPayload, err)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020070 }
Mateusz Zalegac71efc92021-09-07 16:46:25 +020071 cfg.EFIPayload = p
Lorenz Brunae0d90d2019-09-05 17:53:56 +020072
Tim Windelschmidt272c8302024-11-05 05:17:44 +010073 ab, err := blkio.NewFileReader(abLoaderPayload)
74 if err != nil {
75 log.Fatalf("while opening the abloader payload at %q: %v", abLoaderPayload, err)
76 }
77 cfg.ABLoader = ab
78
Mateusz Zalegac71efc92021-09-07 16:46:25 +020079 // Attempt to open the system image if its path is set. In case the path
80 // isn't set, the system partition will still be created, but no
81 // contents will be written into it.
82 if systemImage != "" {
83 img, err := os.Open(systemImage)
Lorenz Brun3a99c592021-01-26 19:57:21 +010084 if err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +010085 log.Fatalf("while opening the system image at %q: %v", systemImage, err)
Lorenz Brun3a99c592021-01-26 19:57:21 +010086 }
Mateusz Zalegac71efc92021-09-07 16:46:25 +020087 defer img.Close()
88 cfg.SystemImage = img
89 }
90
91 // Attempt to open the node parameters file if its path is set.
92 if nodeParams != "" {
Lorenz Brunad131882023-06-28 16:42:20 +020093 np, err := blkio.NewFileReader(nodeParams)
Lorenz Brun3a99c592021-01-26 19:57:21 +010094 if err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +010095 log.Fatalf("while opening node parameters at %q: %v", nodeParams, err)
Lorenz Brun3a99c592021-01-26 19:57:21 +010096 }
Mateusz Zalegac71efc92021-09-07 16:46:25 +020097 cfg.NodeParameters = np
Lorenz Brun3a99c592021-01-26 19:57:21 +010098 }
99
Tim Windelschmidt8e19fa42024-11-12 13:39:43 +0000100 if biosBootCodePayload != "" {
101 bp, err := os.ReadFile(biosBootCodePayload)
102 if err != nil {
103 log.Fatalf("while opening BIOS bootcode at %q: %v", biosBootCodePayload, err)
104 }
105 cfg.BIOSBootCode = bp
106 }
107
Lorenz Brunad131882023-06-28 16:42:20 +0200108 // TODO(#254): Build and use dynamically-grown block devices
109 cfg.Output, err = blockdev.CreateFile(outputPath, 512, 10*1024*1024)
110 if err != nil {
111 panic(err)
112 }
113
Mateusz Zalegac71efc92021-09-07 16:46:25 +0200114 // Write the parametrized OS image.
Tim Windelschmidtcc27faa2024-08-01 02:18:35 +0200115 if _, err := osimage.Write(&cfg); err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +0100116 log.Fatalf("while creating a Metropolis OS image: %v", err)
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200117 }
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200118}