Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 1 | // 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 Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 17 | // 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 Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 27 | package main |
| 28 | |
| 29 | import ( |
Lorenz Brun | 54a5a05 | 2023-10-02 16:40:11 +0200 | [diff] [blame^] | 30 | "bytes" |
| 31 | _ "embed" |
Leopold Schabel | 6549307 | 2019-11-06 13:40:44 +0000 | [diff] [blame] | 32 | "flag" |
Serge Bazanski | 032ca18 | 2020-06-09 20:17:13 +0200 | [diff] [blame] | 33 | "log" |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 34 | "os" |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 35 | |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 36 | "source.monogon.dev/metropolis/node/build/mkimage/osimage" |
Lorenz Brun | ad13188 | 2023-06-28 16:42:20 +0200 | [diff] [blame] | 37 | "source.monogon.dev/metropolis/pkg/blkio" |
| 38 | "source.monogon.dev/metropolis/pkg/blockdev" |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 39 | ) |
| 40 | |
Lorenz Brun | 54a5a05 | 2023-10-02 16:40:11 +0200 | [diff] [blame^] | 41 | //go:embed metropolis/node/core/abloader/abloader_bin.efi |
| 42 | var abloader []byte |
| 43 | |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 44 | func main() { |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 45 | // Fill in the image parameters based on flags. |
| 46 | var ( |
| 47 | efiPayload string |
| 48 | systemImage string |
| 49 | nodeParams string |
Lorenz Brun | ad13188 | 2023-06-28 16:42:20 +0200 | [diff] [blame] | 50 | outputPath string |
| 51 | diskUUID string |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 52 | 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 Brun | ad13188 | 2023-06-28 16:42:20 +0200 | [diff] [blame] | 57 | 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 Schabel | 6549307 | 2019-11-06 13:40:44 +0000 | [diff] [blame] | 62 | flag.Parse() |
Serge Bazanski | 032ca18 | 2020-06-09 20:17:13 +0200 | [diff] [blame] | 63 | |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 64 | // 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 Brun | ad13188 | 2023-06-28 16:42:20 +0200 | [diff] [blame] | 67 | p, err := blkio.NewFileReader(efiPayload) |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 68 | if err != nil { |
Mateusz Zalega | 8f72b5d | 2021-12-03 17:08:59 +0100 | [diff] [blame] | 69 | log.Fatalf("while opening the EFI payload at %q: %v", efiPayload, err) |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 70 | } |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 71 | cfg.EFIPayload = p |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 72 | |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 73 | // 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 Brun | 3a99c59 | 2021-01-26 19:57:21 +0100 | [diff] [blame] | 78 | if err != nil { |
Mateusz Zalega | 8f72b5d | 2021-12-03 17:08:59 +0100 | [diff] [blame] | 79 | log.Fatalf("while opening the system image at %q: %v", systemImage, err) |
Lorenz Brun | 3a99c59 | 2021-01-26 19:57:21 +0100 | [diff] [blame] | 80 | } |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 81 | 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 Brun | ad13188 | 2023-06-28 16:42:20 +0200 | [diff] [blame] | 87 | np, err := blkio.NewFileReader(nodeParams) |
Lorenz Brun | 3a99c59 | 2021-01-26 19:57:21 +0100 | [diff] [blame] | 88 | if err != nil { |
Mateusz Zalega | 8f72b5d | 2021-12-03 17:08:59 +0100 | [diff] [blame] | 89 | log.Fatalf("while opening node parameters at %q: %v", nodeParams, err) |
Lorenz Brun | 3a99c59 | 2021-01-26 19:57:21 +0100 | [diff] [blame] | 90 | } |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 91 | cfg.NodeParameters = np |
Lorenz Brun | 3a99c59 | 2021-01-26 19:57:21 +0100 | [diff] [blame] | 92 | } |
| 93 | |
Lorenz Brun | ad13188 | 2023-06-28 16:42:20 +0200 | [diff] [blame] | 94 | // 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 Brun | 54a5a05 | 2023-10-02 16:40:11 +0200 | [diff] [blame^] | 100 | cfg.ABLoader = bytes.NewReader(abloader) |
| 101 | |
Mateusz Zalega | c71efc9 | 2021-09-07 16:46:25 +0200 | [diff] [blame] | 102 | // Write the parametrized OS image. |
| 103 | if _, err := osimage.Create(&cfg); err != nil { |
Mateusz Zalega | 8f72b5d | 2021-12-03 17:08:59 +0100 | [diff] [blame] | 104 | log.Fatalf("while creating a Metropolis OS image: %v", err) |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 105 | } |
Lorenz Brun | ae0d90d | 2019-09-05 17:53:56 +0200 | [diff] [blame] | 106 | } |