~nabijaczleweli/klapki

9daa92b2b809e71d16a33b29741cab2686aeda4c — наб a year ago ece9bd2
Last pass #notspon
M .build.yml => .build.yml +1 -1
@@ 1,7 1,7 @@
image: debian/sid
secrets:
  - f80b756a-e99e-4936-a62a-93c2c2c6dfd5  # klapki auth token
  - e43a6d41-a99b-44cb-8a7a-4d85ba72897b  # klapki SSH key
  - d9cc88fb-6e8e-4ff6-b2bf-d0ec6641bb15  # klapki SSH key v2
packages:
  - clang
  - libefivar-dev

M README.md => README.md +4 -0
@@ 7,6 7,10 @@ EFI boot manager; or, well, an EFI bootorder [compiler](//twitter.com/nabijaczle

You'll need `libssl-dev` and `libefi{var,boot}-dev`, and `make` should hopefully Just Work™ if you have a C++17-capable compiler.

Note that `klapki` uses Linux-specific [`memfd`](//manpages.debian.org/buster/manpages-dev/memfd_create.2.en.html)
and [`sendfile()`](//manpages.debian.org/buster/manpages-dev/sendfile.2.en.html) interfaces, and as such building it will fail on other systems.
AFAICT libefivar only supports Linux anyway, but these will have to be ported in case it doesn't (patches welcome, &c.).

### Installation

Copy `out/klapki` to `/sbin` and write a `/etc/klapki/{description,cmdline}`, as seen in the [manpage](//git.sr.ht/~nabijaczleweli/klapki/tree/trunk/man/klapki.md),

M configMakefile => configMakefile +3 -3
@@ 54,9 54,9 @@ LNCMAKEAR := LDFLAGS="$(LNCXXAR)"

OBJ := .o
ARCH := .a
AR := ar
CXXAR := -O3 -std=c++17 -Wall -Wextra $(PEDANTIC) -pipe $(INCCXXAR) $(PIC)
STRIP := strip
AR ?= ar
CXXAR := -O3 -g -std=c++17 -Wall -Wextra $(PEDANTIC) -pipe $(INCCXXAR) $(PIC)
STRIP ?= echo strip
STRIPAR := --strip-all --remove-section=.comment --remove-section=.note

OUTDIR := out/

M man/klapki.md => man/klapki.md +0 -1
@@ 6,7 6,6 @@ klapki(8) -- EFI boot manager; or, well, an EFI bootorder compiler.
`klapki` [`-nvVEh`]… [`op` [`arg`…]]…

## DESCRIPTION
<!-- TODO: klapki-internals(7) maybe? -->

klapki(8) generates and manages EFI boot entries on platforms compatible therewith.


M src/context.hpp => src/context.hpp +1 -4
@@ 103,10 103,7 @@ struct fmt::formatter<klapki::context::context> {
	auto format(const klapki::context::context & context, FormatContext & ctx) {
		auto out = ctx.out();

		out = format_to(out,
		                "\n"
		                "{} of our kernels: [",
		                context.our_kernels.size());
		out = format_to(out, "{} of our kernels: [", context.our_kernels.size());

		bool first = true;
		for(auto && el : context.our_kernels) {

M src/context_age.cpp => src/context_age.cpp +1 -2
@@ 129,7 129,6 @@ std::optional<std::string> klapki::context::context::allocate_kernel_variant(con
                                                                             std::vector<std::pair<state::nonbase_dirname_t, state::shaa_t>> initrd_dirnames,
                                                                             std::string image_basename,
                                                                             std::vector<std::pair<state::nonbase_dirname_t, std::string>> initrd_paths) {
	// \base\version
	auto efi_base = fmt::format("{}{}\\", cfg.news_efi_dir(), version);

	const auto new_bootnum = TRY(allocate_bootnum(state));


@@ 194,7 193,7 @@ std::optional<std::string> klapki::context::context::age(const config & cfg, sta
	fkerns.swap(this->fresh_kernels);
	for(auto && fkern : std::move(fkerns)) {
		if(cfg.verbose)
			fmt::print("Aging fresh kernel {}…\n", fkern.version);
			fmt::print("Aging fresh kernel {}\n", fkern.version);

		const auto image_dir = TRY(unrelativise(fkern.image, fkern.version.data(), "image"));


M src/context_derive.cpp => src/context_derive.cpp +2 -10
@@ 58,11 58,7 @@ klapki::context::context klapki::context::context::derive(const config & cfg, st
			}

			const auto dp = efi_loadopt_path(efi_opt, efi_opt_len);
			if(dp->type != EFIDP_MEDIA_TYPE) {
				fmt::print(stderr, "Entry {:04X} not Media Device Path. Abandoning.\n", went.bootnum_hint);
				continue;
			}
			if(dp->subtype != EFIDP_MEDIA_HD) {
			if(dp->type != EFIDP_MEDIA_TYPE && dp->subtype != EFIDP_MEDIA_HD) {
				fmt::print(stderr, "Entry {:04X} not Media Device Path HD. Abandoning.\n", went.bootnum_hint);
				continue;
			}


@@ 81,11 77,7 @@ klapki::context::context klapki::context::context::derive(const config & cfg, st
					fmt::print(stderr, "Entry {:04X}: second (file) node doesn't exist. Abandoning.\n", went.bootnum_hint);
					continue;
				case 1: {
					if(file->type != EFIDP_MEDIA_TYPE) {
						fmt::print(stderr, "Entry {:04X} file not Media Device Path. Abandoning.\n", went.bootnum_hint);
						continue;
					}
					if(file->subtype != EFIDP_MEDIA_FILE) {
					if(file->type != EFIDP_MEDIA_TYPE && file->subtype != EFIDP_MEDIA_FILE) {
						fmt::print(stderr, "Entry {:04X} file not Media Device Path File. Abandoning.\n", went.bootnum_hint);
						continue;
					}

M src/main.cpp => src/main.cpp +2 -5
@@ 101,9 101,6 @@ namespace klapki {
	}
}

int main(int, const char ** argv) try { return klapki::main(argv); } catch(const char * thrown) {
	fmt::print(stderr, "{}\n", thrown);
	throw;
} catch(...) {
	throw;
int main(int, const char ** argv) {
	return klapki::main(argv);
}

M src/ops_execute.cpp => src/ops_execute.cpp +3 -3
@@ 42,7 42,8 @@ std::optional<std::string> klapki::ops::execute(const klapki::ops::dump &, const
	           "Boot order: {}\n"
	           "{} boot entries\n"
	           "Desired boot position: {}\n"
	           "Boot variants: ");
	           "Boot variants: ",
	           state.order, state.entries.size(), state.statecfg.boot_position);

	if(state.statecfg.variants.empty())
		fmt::print("(none)");


@@ 58,8 59,7 @@ std::optional<std::string> klapki::ops::execute(const klapki::ops::dump &, const
		}
	}
	fmt::print("\n"
	           "Wanted entries: [",
	           state.order, state.entries.size(), state.statecfg.boot_position);
	           "Wanted entries: [");

	bool first = true;
	for(auto && el : state.statecfg.wanted_entries) {

M src/state.cpp => src/state.cpp +1 -1
@@ 119,7 119,7 @@ std::variant<klapki::state::state, std::string> klapki::state::state::load(std::
		   else if(is_our_config(guid, name, us))
			   have_our_config = true;
	   }))
		return fmt::format("EFI load: klapki::state::state::load(): iteration: {}", strerror(res));  // No threads here, and we avoid a strerror_r() clusterfuck
		return fmt::format("EFI load: iteration: {}", strerror(res));  // No threads here, and we avoid a strerror_r() clusterfuck


	boot_order_flat bord{};