blob: 7de951ee5303d48bf2ea0895b6fb8fb05a38ca08 [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
Mateusz Zalegac71efc92021-09-07 16:46:25 +020017// mkimage is a tool to generate Metropolis node disk images.
18// It can be used both to initialize block devices and to create image
19// files.
20//
21// The tool takes a path to an EFI payload (--efi), and a path to a
22// Metropolis system image (--system) as its only required inputs. In
23// addition, an output path must be supplied (--out).
24// 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 "bytes"
31 _ "embed"
Leopold Schabel65493072019-11-06 13:40:44 +000032 "flag"
Serge Bazanski032ca182020-06-09 20:17:13 +020033 "log"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020034 "os"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020035
Mateusz Zalegac71efc92021-09-07 16:46:25 +020036 "source.monogon.dev/metropolis/node/build/mkimage/osimage"
Lorenz Brunad131882023-06-28 16:42:20 +020037 "source.monogon.dev/metropolis/pkg/blkio"
38 "source.monogon.dev/metropolis/pkg/blockdev"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020039)
40
Lorenz Brun54a5a052023-10-02 16:40:11 +020041//go:embed metropolis/node/core/abloader/abloader_bin.efi
42var abloader []byte
43
Lorenz Brunae0d90d2019-09-05 17:53:56 +020044func main() {
Mateusz Zalegac71efc92021-09-07 16:46:25 +020045 // Fill in the image parameters based on flags.
46 var (
47 efiPayload string
48 systemImage string
49 nodeParams string
Lorenz Brunad131882023-06-28 16:42:20 +020050 outputPath string
51 diskUUID string
Mateusz Zalegac71efc92021-09-07 16:46:25 +020052 cfg osimage.Params
53 )
54 flag.StringVar(&efiPayload, "efi", "", "Path to the UEFI payload used")
55 flag.StringVar(&systemImage, "system", "", "Path to the system partition image used")
56 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
Mateusz Zalegac71efc92021-09-07 16:46:25 +020073 // Attempt to open the system image if its path is set. In case the path
74 // isn't set, the system partition will still be created, but no
75 // contents will be written into it.
76 if systemImage != "" {
77 img, err := os.Open(systemImage)
Lorenz Brun3a99c592021-01-26 19:57:21 +010078 if err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +010079 log.Fatalf("while opening the system image at %q: %v", systemImage, err)
Lorenz Brun3a99c592021-01-26 19:57:21 +010080 }
Mateusz Zalegac71efc92021-09-07 16:46:25 +020081 defer img.Close()
82 cfg.SystemImage = img
83 }
84
85 // Attempt to open the node parameters file if its path is set.
86 if nodeParams != "" {
Lorenz Brunad131882023-06-28 16:42:20 +020087 np, err := blkio.NewFileReader(nodeParams)
Lorenz Brun3a99c592021-01-26 19:57:21 +010088 if err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +010089 log.Fatalf("while opening node parameters at %q: %v", nodeParams, err)
Lorenz Brun3a99c592021-01-26 19:57:21 +010090 }
Mateusz Zalegac71efc92021-09-07 16:46:25 +020091 cfg.NodeParameters = np
Lorenz Brun3a99c592021-01-26 19:57:21 +010092 }
93
Lorenz Brunad131882023-06-28 16:42:20 +020094 // TODO(#254): Build and use dynamically-grown block devices
95 cfg.Output, err = blockdev.CreateFile(outputPath, 512, 10*1024*1024)
96 if err != nil {
97 panic(err)
98 }
99
Lorenz Brun54a5a052023-10-02 16:40:11 +0200100 cfg.ABLoader = bytes.NewReader(abloader)
101
Mateusz Zalegac71efc92021-09-07 16:46:25 +0200102 // Write the parametrized OS image.
103 if _, err := osimage.Create(&cfg); err != nil {
Mateusz Zalega8f72b5d2021-12-03 17:08:59 +0100104 log.Fatalf("while creating a Metropolis OS image: %v", err)
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200105 }
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200106}