From c53e522e4aa882eb55ea275ef7e3570e1b643cd9 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 23 Jun 2026 18:07:14 +0200 Subject: [PATCH] Add a container image for partitioning ephemeral disks We often get questions on Slack about how to combine multiple ephemeral block devices into a single larger one, and how to carve it up to have separate block devices for the CAS, AC, etc.. I once wrote a tool that does exactly that. Let's make it part of bb-storage, so that others can use it more easily. --- .github/workflows/main.yaml | 131 ++++++++++++ cmd/partition_ephemeral_disks/BUILD.bazel | 31 +++ cmd/partition_ephemeral_disks/main.go | 115 +++++++++++ .../partition_ephemeral_disks/BUILD.bazel | 24 +++ .../partition_ephemeral_disks.pb.go | 192 ++++++++++++++++++ .../partition_ephemeral_disks.proto | 23 +++ .../github_workflows/github_workflows.jsonnet | 2 + 7 files changed, 518 insertions(+) create mode 100644 cmd/partition_ephemeral_disks/BUILD.bazel create mode 100644 cmd/partition_ephemeral_disks/main.go create mode 100644 pkg/proto/configuration/partition_ephemeral_disks/BUILD.bazel create mode 100644 pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.pb.go create mode 100644 pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.proto diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index d73e7bf0d..0074905c8 100755 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -65,6 +65,20 @@ "path": "bb_storage.linux_amd64" } }, + { + "if": "matrix.host.upload", + "name": "linux_amd64: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.linux_amd64 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:linux_amd64 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.linux_amd64" + }, + { + "if": "matrix.host.upload", + "name": "linux_amd64: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.linux_amd64", + "path": "partition_ephemeral_disks.linux_amd64" + } + }, { "if": "matrix.host.upload", "name": "linux_amd64: copy sync_jwks_to_configmap", @@ -126,6 +140,20 @@ "path": "bb_storage.linux_amd64_v3" } }, + { + "if": "matrix.host.upload", + "name": "linux_amd64_v3: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.linux_amd64_v3 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:linux_amd64_v3 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.linux_amd64_v3" + }, + { + "if": "matrix.host.upload", + "name": "linux_amd64_v3: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.linux_amd64_v3", + "path": "partition_ephemeral_disks.linux_amd64_v3" + } + }, { "if": "matrix.host.upload", "name": "linux_amd64_v3: copy sync_jwks_to_configmap", @@ -187,6 +215,20 @@ "path": "bb_storage.linux_386" } }, + { + "if": "matrix.host.upload", + "name": "linux_386: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.linux_386 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:linux_386 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.linux_386" + }, + { + "if": "matrix.host.upload", + "name": "linux_386: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.linux_386", + "path": "partition_ephemeral_disks.linux_386" + } + }, { "if": "matrix.host.upload", "name": "linux_386: copy sync_jwks_to_configmap", @@ -248,6 +290,20 @@ "path": "bb_storage.linux_arm" } }, + { + "if": "matrix.host.upload", + "name": "linux_arm: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.linux_arm && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:linux_arm //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.linux_arm" + }, + { + "if": "matrix.host.upload", + "name": "linux_arm: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.linux_arm", + "path": "partition_ephemeral_disks.linux_arm" + } + }, { "if": "matrix.host.upload", "name": "linux_arm: copy sync_jwks_to_configmap", @@ -309,6 +365,20 @@ "path": "bb_storage.linux_arm64" } }, + { + "if": "matrix.host.upload", + "name": "linux_arm64: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.linux_arm64 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:linux_arm64 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.linux_arm64" + }, + { + "if": "matrix.host.upload", + "name": "linux_arm64: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.linux_arm64", + "path": "partition_ephemeral_disks.linux_arm64" + } + }, { "if": "matrix.host.upload", "name": "linux_arm64: copy sync_jwks_to_configmap", @@ -370,6 +440,20 @@ "path": "bb_storage.darwin_amd64" } }, + { + "if": "matrix.host.upload", + "name": "darwin_amd64: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.darwin_amd64 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:darwin_amd64 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.darwin_amd64" + }, + { + "if": "matrix.host.upload", + "name": "darwin_amd64: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.darwin_amd64", + "path": "partition_ephemeral_disks.darwin_amd64" + } + }, { "if": "matrix.host.upload", "name": "darwin_amd64: copy sync_jwks_to_configmap", @@ -431,6 +515,20 @@ "path": "bb_storage.darwin_arm64" } }, + { + "if": "matrix.host.upload", + "name": "darwin_arm64: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.darwin_arm64 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:darwin_arm64 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.darwin_arm64" + }, + { + "if": "matrix.host.upload", + "name": "darwin_arm64: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.darwin_arm64", + "path": "partition_ephemeral_disks.darwin_arm64" + } + }, { "if": "matrix.host.upload", "name": "darwin_arm64: copy sync_jwks_to_configmap", @@ -492,6 +590,20 @@ "path": "bb_storage.freebsd_amd64" } }, + { + "if": "matrix.host.upload", + "name": "freebsd_amd64: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.freebsd_amd64 && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:freebsd_amd64 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.freebsd_amd64" + }, + { + "if": "matrix.host.upload", + "name": "freebsd_amd64: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.freebsd_amd64", + "path": "partition_ephemeral_disks.freebsd_amd64" + } + }, { "if": "matrix.host.upload", "name": "freebsd_amd64: copy sync_jwks_to_configmap", @@ -553,6 +665,20 @@ "path": "bb_storage.windows_amd64.exe" } }, + { + "if": "matrix.host.upload", + "name": "windows_amd64: copy partition_ephemeral_disks", + "run": "rm -f partition_ephemeral_disks.windows_amd64.exe && bazel run --run_under cp --platforms=@com_github_buildbarn_bb_storage//tools/platforms:windows_amd64 //cmd/partition_ephemeral_disks $(pwd)/partition_ephemeral_disks.windows_amd64.exe" + }, + { + "if": "matrix.host.upload", + "name": "windows_amd64: upload partition_ephemeral_disks", + "uses": "actions/upload-artifact@v4", + "with": { + "name": "partition_ephemeral_disks.windows_amd64", + "path": "partition_ephemeral_disks.windows_amd64.exe" + } + }, { "if": "matrix.host.upload", "name": "windows_amd64: copy sync_jwks_to_configmap", @@ -595,6 +721,11 @@ "name": "Push container bb_storage:bb_storage", "run": "bazel run --stamp //cmd/bb_storage:bb_storage_container_push" }, + { + "if": "matrix.host.upload", + "name": "Push container partition_ephemeral_disks:partition_ephemeral_disks", + "run": "bazel run --stamp //cmd/partition_ephemeral_disks:partition_ephemeral_disks_container_push" + }, { "if": "matrix.host.upload", "name": "Push container sync_jwks_to_configmap:sync_jwks_to_configmap", diff --git a/cmd/partition_ephemeral_disks/BUILD.bazel b/cmd/partition_ephemeral_disks/BUILD.bazel new file mode 100644 index 000000000..d072ad7aa --- /dev/null +++ b/cmd/partition_ephemeral_disks/BUILD.bazel @@ -0,0 +1,31 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") +load("//tools:container.bzl", "container_push_official", "multiarch_go_image") + +go_library( + name = "partition_ephemeral_disks_lib", + srcs = ["main.go"], + importpath = "github.com/buildbarn/bb-storage/cmd/partition_ephemeral_disks", + visibility = ["//visibility:private"], + deps = [ + "//pkg/proto/configuration/partition_ephemeral_disks", + "//pkg/util", + ], +) + +go_binary( + name = "partition_ephemeral_disks", + embed = [":partition_ephemeral_disks_lib"], + pure = "on", + visibility = ["//visibility:public"], +) + +multiarch_go_image( + name = "partition_ephemeral_disks_container", + binary = ":partition_ephemeral_disks", +) + +container_push_official( + name = "partition_ephemeral_disks_container_push", + component = "bb-storage", + image = ":partition_ephemeral_disks_container", +) diff --git a/cmd/partition_ephemeral_disks/main.go b/cmd/partition_ephemeral_disks/main.go new file mode 100644 index 000000000..4735ec7e8 --- /dev/null +++ b/cmd/partition_ephemeral_disks/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "errors" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + + "github.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disks" + "github.com/buildbarn/bb-storage/pkg/util" +) + +// partition_ephemeral_disks: Place all local SSDs of a cloud compute +// instance in a single LVM2 volume group, and partition it. +// +// This command can be run as part of a daemonset on all nodes in a +// given Kubernetes node group to ensure that the ephemeral storage +// present on these systems is partitioned properly. That way other pods +// can make use of raw block devices with fine-grained sizes. + +func run(command string, arguments ...string) error { + cmd := exec.Command(command, arguments...) + // lvcreate may hang if the following environment variable is + // not set, as it can't post device creation notifications to + // udev on the host system. By setting this environment + // variable, lvcreate will create new device nodes under /dev + // directly. + cmd.Env = append(cmd.Environ(), "DM_DISABLE_UDEV=y") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +func main() { + if len(os.Args) != 2 { + log.Fatal("Usage: partition_ephemeral_disks partition_ephemeral_disks.jsonnet") + } + var configuration partition_ephemeral_disks.ApplicationConfiguration + if err := util.UnmarshalConfigurationFromFile(os.Args[1], &configuration); err != nil { + log.Fatalf("Failed to read configuration from %s: %s", os.Args[1], err) + } + + // Determine which devices need to go in the volume group. + unexpandedDevicePaths, err := filepath.Glob(configuration.EphemeralDiskDevicesPattern) + if err != nil { + log.Fatal("Failed to obtain paths of ephemeral disk devices: ", err) + } + expandedDevicePaths := make(map[string]struct{}, len(unexpandedDevicePaths)) + for _, unexpandedDevicePath := range unexpandedDevicePaths { + expandedDevicePath, err := filepath.EvalSymlinks(unexpandedDevicePath) + if err != nil { + log.Fatalf("Cannot evaluate symbolic links for path %#v: %s", unexpandedDevicePath, err) + } + expandedDevicePaths[expandedDevicePath] = struct{}{} + } + if len(expandedDevicePaths) == 0 { + log.Fatalf("Pattern %#v does not expand to any ephemeral disk devices", configuration.EphemeralDiskDevicesPattern) + } + + // Create the volume group if needed. + volumeGroupName := "ephemeral" + if err := run("vgs", volumeGroupName); err != nil { + var exitErr *exec.ExitError + if !errors.As(err, &exitErr) || exitErr.ExitCode() != 5 { + log.Fatalf("Failed to determine existence of volume group %#v: %s", volumeGroupName, err) + } + + arguments := []string{"--force", volumeGroupName} + for expandedDevicePath := range expandedDevicePaths { + arguments = append(arguments, expandedDevicePath) + } + if err := run("vgcreate", arguments...); err != nil { + log.Fatalf("Failed to create volume group %#v: %s", volumeGroupName, err) + } + } + + // Check validity of the provided partitions. + totalPercentage := int32(0) + for _, partition := range configuration.Partitions { + if partition.SizePercentage < 1 || partition.SizePercentage > 100 { + log.Fatalf("Partition %#v has illegal size %d", partition.Name, partition.SizePercentage) + } + totalPercentage += partition.SizePercentage + } + if totalPercentage != 100 { + log.Fatal("Partition sizes do not add up to 100%") + } + + // Create the partitions inside the ephemeral volume group. + var baseArguments []string + if len(expandedDevicePaths) > 1 { + baseArguments = []string{ + "--type", "raid0", + "--stripes", strconv.FormatInt(int64(len(expandedDevicePaths)), 10), + "--stripesize", "2048", + } + } + for _, partition := range configuration.Partitions { + if err := run("lvcreate", append( + append([]string(nil), baseArguments...), + "--extents", fmt.Sprintf("%d%%VG", partition.SizePercentage), + "--name", partition.Name, + "--wipesignatures", "n", + volumeGroupName, + )...); err != nil { + var exitErr *exec.ExitError + if !errors.As(err, &exitErr) || exitErr.ExitCode() != 5 { + log.Fatalf("Failed to create logical volume %#v: %s", partition.Name, err) + } + } + } +} diff --git a/pkg/proto/configuration/partition_ephemeral_disks/BUILD.bazel b/pkg/proto/configuration/partition_ephemeral_disks/BUILD.bazel new file mode 100644 index 000000000..254713f15 --- /dev/null +++ b/pkg/proto/configuration/partition_ephemeral_disks/BUILD.bazel @@ -0,0 +1,24 @@ +load("@protobuf//bazel:proto_library.bzl", "proto_library") +load("@rules_go//go:def.bzl", "go_library") +load("@rules_go//proto:def.bzl", "go_proto_library") + +proto_library( + name = "partition_ephemeral_disks_proto", + srcs = ["partition_ephemeral_disks.proto"], + import_prefix = "github.com/buildbarn/bb-storage", + visibility = ["//visibility:public"], +) + +go_proto_library( + name = "partition_ephemeral_disks_go_proto", + importpath = "github.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disks", + proto = ":partition_ephemeral_disks_proto", + visibility = ["//visibility:public"], +) + +go_library( + name = "partition_ephemeral_disks", + embed = [":partition_ephemeral_disks_go_proto"], + importpath = "github.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disks", + visibility = ["//visibility:public"], +) diff --git a/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.pb.go b/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.pb.go new file mode 100644 index 000000000..c7a7f5079 --- /dev/null +++ b/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.pb.go @@ -0,0 +1,192 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11-devel +// protoc v7.35.0 +// source: github.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.proto + +package partition_ephemeral_disks + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ApplicationConfiguration struct { + state protoimpl.MessageState `protogen:"open.v1"` + EphemeralDiskDevicesPattern string `protobuf:"bytes,1,opt,name=ephemeral_disk_devices_pattern,json=ephemeralDiskDevicesPattern,proto3" json:"ephemeral_disk_devices_pattern,omitempty"` + Partitions []*Partition `protobuf:"bytes,2,rep,name=partitions,proto3" json:"partitions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ApplicationConfiguration) Reset() { + *x = ApplicationConfiguration{} + mi := &file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ApplicationConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplicationConfiguration) ProtoMessage() {} + +func (x *ApplicationConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplicationConfiguration.ProtoReflect.Descriptor instead. +func (*ApplicationConfiguration) Descriptor() ([]byte, []int) { + return file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescGZIP(), []int{0} +} + +func (x *ApplicationConfiguration) GetEphemeralDiskDevicesPattern() string { + if x != nil { + return x.EphemeralDiskDevicesPattern + } + return "" +} + +func (x *ApplicationConfiguration) GetPartitions() []*Partition { + if x != nil { + return x.Partitions + } + return nil +} + +type Partition struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + SizePercentage int32 `protobuf:"varint,2,opt,name=size_percentage,json=sizePercentage,proto3" json:"size_percentage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Partition) Reset() { + *x = Partition{} + mi := &file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Partition) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Partition) ProtoMessage() {} + +func (x *Partition) ProtoReflect() protoreflect.Message { + mi := &file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Partition.ProtoReflect.Descriptor instead. +func (*Partition) Descriptor() ([]byte, []int) { + return file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescGZIP(), []int{1} +} + +func (x *Partition) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Partition) GetSizePercentage() int32 { + if x != nil { + return x.SizePercentage + } + return 0 +} + +var File_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto protoreflect.FileDescriptor + +const file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDesc = "" + + "\n" + + "qgithub.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.proto\x121buildbarn.configuration.partition_ephemeral_disks\"\xbd\x01\n" + + "\x18ApplicationConfiguration\x12C\n" + + "\x1eephemeral_disk_devices_pattern\x18\x01 \x01(\tR\x1bephemeralDiskDevicesPattern\x12\\\n" + + "\n" + + "partitions\x18\x02 \x03(\v2<.buildbarn.configuration.partition_ephemeral_disks.PartitionR\n" + + "partitions\"H\n" + + "\tPartition\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12'\n" + + "\x0fsize_percentage\x18\x02 \x01(\x05R\x0esizePercentageBSZQgithub.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disksb\x06proto3" + +var ( + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescOnce sync.Once + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescData []byte +) + +func file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescGZIP() []byte { + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescOnce.Do(func() { + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDesc), len(file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDesc))) + }) + return file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDescData +} + +var file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_goTypes = []any{ + (*ApplicationConfiguration)(nil), // 0: buildbarn.configuration.partition_ephemeral_disks.ApplicationConfiguration + (*Partition)(nil), // 1: buildbarn.configuration.partition_ephemeral_disks.Partition +} +var file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_depIdxs = []int32{ + 1, // 0: buildbarn.configuration.partition_ephemeral_disks.ApplicationConfiguration.partitions:type_name -> buildbarn.configuration.partition_ephemeral_disks.Partition + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_init() +} +func file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_init() { + if File_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDesc), len(file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_rawDesc)), + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_goTypes, + DependencyIndexes: file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_depIdxs, + MessageInfos: file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_msgTypes, + }.Build() + File_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto = out.File + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_goTypes = nil + file_github_com_buildbarn_bb_storage_pkg_proto_configuration_partition_ephemeral_disks_partition_ephemeral_disks_proto_depIdxs = nil +} diff --git a/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.proto b/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.proto new file mode 100644 index 000000000..615b73516 --- /dev/null +++ b/pkg/proto/configuration/partition_ephemeral_disks/partition_ephemeral_disks.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package buildbarn.configuration.partition_ephemeral_disks; + +option go_package = "github.com/buildbarn/bb-storage/pkg/proto/configuration/partition_ephemeral_disks"; + +message ApplicationConfiguration { + // A glob pattern indicating which block devices on the host system + // should be placed in the ephemeral volume group. + string ephemeral_disk_devices_pattern = 1; + + // Partitions to create within the ephemeral volume group. + repeated Partition partitions = 2; +} + +message Partition { + // The name of the partition to create. + string name = 1; + + // The size of the partition, provided in the form of a percentage. + // The sizes of all partitions must add up to 100%. + int32 size_percentage = 2; +} diff --git a/tools/github_workflows/github_workflows.jsonnet b/tools/github_workflows/github_workflows.jsonnet index 2acda4f15..27e42b4f8 100644 --- a/tools/github_workflows/github_workflows.jsonnet +++ b/tools/github_workflows/github_workflows.jsonnet @@ -5,12 +5,14 @@ workflows_template.getWorkflows( 'bb_copy', 'bb_replicator', 'bb_storage', + 'partition_ephemeral_disks', 'sync_jwks_to_configmap', ], [ 'bb_copy:bb_copy', 'bb_replicator:bb_replicator', 'bb_storage:bb_storage', + 'partition_ephemeral_disks:partition_ephemeral_disks', 'sync_jwks_to_configmap:sync_jwks_to_configmap', ], )