Add global.with-veth/with-ipv6 config defaults for -n/--network creation
Replaces --no-ipv6/--no-veth (plain flags) with --with-ipv6/--with-veth, each taking an explicit true/false value (e.g. --with-veth=false), parsed via the same parse_bool_flag() the config file itself already uses (now exported from config_file.h so cli_args.cpp can reuse it). create_network_command() now resolves ipv6/veth as CLI flag -> config's own global.with-ipv6/global.with-veth -> true, so a host that always wants the tap+relay fallback (or no IPv6) can set it once in the config instead of passing the flag on every network creation. -w/--write-config fills in both new keys like the existing six unshare-* bools.
This commit is contained in:
@@ -75,20 +75,34 @@ Source layout (all under `src/`):
|
||||
consumption needed, `'n'`'s own `case` just does
|
||||
`network_specs.push_back(optarg)`. The same post-loop split as `-v` decides
|
||||
`Mode::network` (standalone, exactly one occurrence) vs. join-with-`-r`
|
||||
(repeatable, no limit). `--extern`/`--intern`/`--subnet <cidr>`/`--no-ipv6`/
|
||||
`--subnet6 <cidr>`/`--no-veth` (`ParsedArgs::network_extern_flag`/`network_intern_flag`/
|
||||
`network_subnet_flag`/`network_no_ipv6_flag`/`network_subnet6_flag`/
|
||||
`network_no_veth_flag`) only
|
||||
(repeatable, no limit). `--extern`/`--intern`/`--subnet <cidr>`/`--with-ipv6`/
|
||||
`--subnet6 <cidr>`/`--with-veth` (`ParsedArgs::network_extern_flag`/`network_intern_flag`/
|
||||
`network_subnet_flag`/`network_with_ipv6_flag`/`network_subnet6_flag`/
|
||||
`network_with_veth_flag`) only
|
||||
apply to the standalone (create) case and are rejected with a clear error if
|
||||
given any other way (e.g. alongside `-r`) — `Mode::network` additionally
|
||||
requires exactly one of `--extern`/`--intern`. `--no-veth` forces
|
||||
`NetworkEntry::veth` (`config_file.h`) to `false` at creation time,
|
||||
overriding the default `true` — see `network_bridge.h`'s
|
||||
`probe_veth_support()`/`should_use_veth()` for what this controls: lets
|
||||
the tap+relay fallback (the real target device's kernel lacks `CONFIG_VETH`
|
||||
— see `docs/networking-design.md`'s addendum) be exercised on a
|
||||
veth-capable machine like this dev box, without needing the actual
|
||||
veth-less hardware. **`-n` used to belong to
|
||||
requires exactly one of `--extern`/`--intern`. Unlike the plain boolean
|
||||
flags elsewhere in this file, `--with-ipv6`/`--with-veth` are
|
||||
`required_argument` (e.g. `--with-veth=false`), parsed via
|
||||
`parse_bool_flag()` (`config_file.h` — exported specifically so this file
|
||||
can reuse the exact same accepted forms, `"1"/"on"/"yes"/"true"` and
|
||||
`"0"/"off"/"no"/"false"`, as the config file itself, rather than a second,
|
||||
drifting copy) into `ParsedArgs::network_with_ipv6_flag`/`network_with_veth_flag`
|
||||
(`std::optional<bool>` — `nullopt` means "not given on the CLI, use the
|
||||
config file's own default", not "false"). `--with-veth=false` forces
|
||||
`NetworkEntry::veth` (`config_file.h`) to `false` at creation time; when
|
||||
neither is given, `create_network_command()` (`commands.cpp`) falls back to
|
||||
`AppConfig::with_veth`/`with_ipv6` (`config_file.h`'s own two new
|
||||
`global.with-veth`/`global.with-ipv6` keys, same "unset means enabled"
|
||||
convention as the six `unshare-*` keys), only defaulting to `true` if that,
|
||||
too, is unset — see `network_bridge.h`'s
|
||||
`probe_veth_support()`/`should_use_veth()` for what a resolved `false`
|
||||
controls: lets the tap+relay fallback (the real target device's kernel
|
||||
lacks `CONFIG_VETH` — see `docs/networking-design.md`'s addendum) be
|
||||
exercised on a veth-capable machine like this dev box, without needing the
|
||||
actual veth-less hardware, or be made this dev box's own default via the
|
||||
config file instead of passing `--with-veth=false` on every `-n --extern`/
|
||||
`--intern` invocation. **`-n` used to belong to
|
||||
`--no-nsenter`**: reassigned here since `--network` will be far more
|
||||
heavily used; `--no-nsenter` moved to long-option-only (`options::no_nsenter`)
|
||||
rather than hunting for a new letter, matching `--kill`'s own "rare/niche
|
||||
@@ -200,7 +214,8 @@ Source layout (all under `src/`):
|
||||
`create_volume_command()`/`delete_volume_command()`'s use of
|
||||
`write_config_file()` (which only ever persists `AppConfig` fields that are
|
||||
already set), this fills in *every* field before writing — the six
|
||||
`unshare-*` bools via `.value_or(true)`, and `log_level` from the actually
|
||||
`unshare-*` bools plus `with-veth`/`with-ipv6`, all via `.value_or(true)`,
|
||||
and `log_level` from the actually
|
||||
active `spdlog::get_level()` (not merely a default for when unset — this
|
||||
also captures an explicit `--log-level` passed alongside `-w` on the same
|
||||
command line, overriding whatever an existing config file's own
|
||||
@@ -1666,7 +1681,7 @@ Source layout (all under `src/`):
|
||||
`host.containers.internal` file (`dns-internal-hosts/<container>-<pid>`,
|
||||
likewise just deleted) — called from `clean_processes_command()`
|
||||
(`commands.cpp`) alongside the three existing sweeps. `--no-dns`
|
||||
(`cli_args.{h,cpp}`, long-option only, same precedent as `--no-veth`) opts
|
||||
(`cli_args.{h,cpp}`, long-option only, plain boolean flag, no value) opts
|
||||
out even when `dnsmasq` is available. `build_bwrap_args()`/`run_bwrap()`
|
||||
(`bwrap.{h,cpp}`) gained a `inject_dns_resolv_conf` bool, resolved once in
|
||||
`run_container()` from `!network_specs.empty() && is_dnsmasq_available() &&
|
||||
@@ -2054,20 +2069,32 @@ Source layout (all under `src/`):
|
||||
the local YAML config file located by `config_file_path()`
|
||||
(`$XDG_CONFIG_HOME/slocker-lite/config.yaml`,
|
||||
falling back to `$HOME/.config/slocker-lite/config.yaml`). Supported `global` keys:
|
||||
`log-level`, and six `unshare-<type>` keys (`unshare-user`/`unshare-ipc`/
|
||||
`log-level`; six `unshare-<type>` keys (`unshare-user`/`unshare-ipc`/
|
||||
`unshare-pid`/`unshare-net`/`unshare-uts`/`unshare-cgroup`, one per
|
||||
`bwrap.cpp`'s own `namespace_probes` entry) controlling whether `-r/--run`
|
||||
requests each of bwrap's `--unshare-xxx` flags — every other long option is a
|
||||
one-shot flag, not a setting, so it doesn't belong in a persistent config file.
|
||||
Each `unshare-*` key accepts `"1"`/`"on"`/`"yes"`/`"true"` (enabled) or
|
||||
`"0"`/`"off"`/`"no"`/`"false"` (disabled), case-insensitively (`.cpp`-local
|
||||
`parse_bool_flag()`); an unset key defaults to enabled, and an unrecognized
|
||||
value logs a `spdlog::warn` and is treated as unset (default enabled) rather
|
||||
than failing the whole config load — consistent with this file's existing
|
||||
forward-compatible/ignore-malformed-entries policy (only malformed *YAML
|
||||
syntax* is a hard error). A missing file returns a default-constructed
|
||||
(empty) `AppConfig`, not an error; unknown sections/keys (and malformed
|
||||
individual volume entries) are likewise ignored for forward-compatibility.
|
||||
requests each of bwrap's `--unshare-xxx` flags; and two `with-<feature>` keys
|
||||
(`with-veth`/`with-ipv6`, `AppConfig::with_veth`/`with_ipv6`) giving
|
||||
`-n/--network`'s own creation-time `veth`/`ipv6` policy (`NetworkEntry`,
|
||||
above) a persistent default, used whenever the corresponding
|
||||
`--with-veth`/`--with-ipv6` CLI flag (`cli_args.{h,cpp}`, see above) isn't
|
||||
given — every other long option is a one-shot flag, not a setting, so it
|
||||
doesn't belong in a persistent config file. All eight of these boolean keys
|
||||
share one small `.cpp`-local `BoolGlobalKey {key, field}` pairing table (two
|
||||
arrays, `unshare_keys` and `network_default_keys`, both consumed by shared
|
||||
`load_bool_keys()`/`write_bool_keys()` helpers rather than repeating the same
|
||||
find-parse-or-warn / emit-if-set loop body per group) and accept
|
||||
`"1"`/`"on"`/`"yes"`/`"true"` (enabled) or `"0"`/`"off"`/`"no"`/`"false"`
|
||||
(disabled), case-insensitively — `parse_bool_flag()`, exported (not just this
|
||||
file's own internal helper) specifically so `cli_args.cpp`'s own
|
||||
`--with-ipv6`/`--with-veth` value parsing accepts exactly the same forms as
|
||||
the config file itself, rather than a second, drifting copy. An unset key
|
||||
defaults to enabled, and an unrecognized value logs a `spdlog::warn` and is
|
||||
treated as unset (default enabled) rather than failing the whole config load
|
||||
— consistent with this file's existing forward-compatible/ignore-malformed-
|
||||
entries policy (only malformed *YAML syntax* is a hard error). A missing file
|
||||
returns a default-constructed (empty) `AppConfig`, not an error; unknown
|
||||
sections/keys (and malformed individual volume entries) are likewise ignored
|
||||
for forward-compatibility.
|
||||
`main()` applies `config->log_level` (via the existing `apply_log_level()`)
|
||||
right after `spdlog::cfg::load_env_levels()` and before parsing CLI options,
|
||||
so an explicit `--log-level` on the command line always overwrites it
|
||||
@@ -2076,8 +2103,8 @@ Source layout (all under `src/`):
|
||||
document-building/emitter API, symmetric to the read side) — used by
|
||||
`-v/--volume` (`create_volume_command()`, `commands.cpp`) to persist a new
|
||||
`VolumeEntry {name, directory}` into the `volumes` section, preserving
|
||||
`global` (including any set `unshare-*` keys, re-serialized as canonical
|
||||
`"true"`/`"false"`) untouched. **`VolumeEntry`/the `volumes` section is a
|
||||
`global` (including any set `unshare-*`/`with-veth`/`with-ipv6` keys,
|
||||
re-serialized as canonical `"true"`/`"false"`) untouched. **`VolumeEntry`/the `volumes` section is a
|
||||
distinct concept from `OciImageConfig::volumes`**: this is a user-defined
|
||||
`name -> host directory` mapping created via `-v/--volume`, not an image's
|
||||
own declared mount points (still unconsumed, see `oci_image.{h,cpp}` above).
|
||||
@@ -2106,8 +2133,9 @@ Source layout (all under `src/`):
|
||||
`ipv6` (`parse_bool_flag()`, written as canonical `"true"`/`"false"`,
|
||||
always written regardless of value — unlike `subnet6`, there's no
|
||||
companion field whose presence depends on it) — see `network_bridge.h`'s
|
||||
`probe_veth_support()`/`should_use_veth()` above and `--no-veth`
|
||||
(`cli_args.{h,cpp}`) below for what it controls.
|
||||
`probe_veth_support()`/`should_use_veth()` above and `--with-veth`/
|
||||
`global.with-veth` (`cli_args.{h,cpp}`/`config_file.{h,cpp}`) below for
|
||||
what it controls.
|
||||
- `network_subnet.{h,cpp}` — pure CIDR arithmetic backing `-n/--network`'s
|
||||
subnet allocation and `network_bridge.{h,cpp}`'s (see below) gateway-address
|
||||
computation; no kernel/`ip`/`iptables` calls of its own. `is_valid_network_name()`
|
||||
@@ -2253,8 +2281,8 @@ Build directory is `buildDir/` (already configured).
|
||||
full flag list: `-m/--mount`, `-r/--run`, `-u/--umount`, `-c/--cleanup`,
|
||||
`-l/--list-images`, `-i/--inspect`, `-x/--exec`, `--kill`, `--no-nsenter`, `-D/--daemonize`,
|
||||
`--user`, `--group`, `--hostname`, `--env`, `--env-file`, `-v/--volume`, `--list-volumes`, `--delete-volume`,
|
||||
`--delete-volume-full`, `-n/--network`, `--extern`, `--intern`, `--subnet`, `--no-ipv6`, `--subnet6`,
|
||||
`--no-veth`, `--list-networks`, `--delete-network`, `-p/--port-forward`, `--no-dns`, `--list-processes`, `--clean-processes`,
|
||||
`--delete-volume-full`, `-n/--network`, `--extern`, `--intern`, `--subnet`, `--with-ipv6`, `--subnet6`,
|
||||
`--with-veth`, `--list-networks`, `--delete-network`, `-p/--port-forward`, `--no-dns`, `--list-processes`, `--clean-processes`,
|
||||
`-w/--write-config`, `-t/--test [-- <catch-command-line-options>]`, `--log-level`,
|
||||
`-h/--help`, `-V/--version`)
|
||||
- Run tests: `meson test -C buildDir` (the `[unit]` + safe `[integration]` categories
|
||||
|
||||
Reference in New Issue
Block a user