Skip to content

Commit 49f204d

Browse files
committed
feat(cfg): Hyper.Cfg.Jails facade (cgroup, uid_gid_range)
1 parent 612d103 commit 49f204d

4 files changed

Lines changed: 62 additions & 7 deletions

File tree

lib/hyper/cfg/jails.ex

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
defmodule Hyper.Cfg.Jails do
2+
@moduledoc """
3+
VM confinement settings from the `[jails]` table — `config.toml`-only because
4+
the setuid helper enforces the same `uid_gid_range` it reads from this file.
5+
"""
6+
7+
import Hyper.Cfg, only: [get_cfg: 1]
8+
9+
@default_range {900_000, 999_999}
10+
11+
@doc "Parent cgroup for every VM cgroup. `[jails] cgroup`, default `\"hyper\"`."
12+
@spec cgroup :: String.t()
13+
def cgroup, do: get_cfg(toml: "jails.cgroup", default: "hyper")
14+
15+
@doc "UID/GID allocation band each VM jail draws from. `[jails] uid_gid_range`."
16+
@spec uid_gid_range :: {integer(), integer()}
17+
def uid_gid_range do
18+
case Hyper.Cfg.Toml.fetch("jails.uid_gid_range") do
19+
{:ok, v} -> range_from(v)
20+
:error -> @default_range
21+
end
22+
end
23+
24+
@doc false
25+
@spec range_from(term()) :: {integer(), integer()}
26+
def range_from([min, max]) when is_integer(min) and is_integer(max), do: {min, max}
27+
def range_from(_), do: @default_range
28+
end

lib/hyper/node/fire_vmm/jailer.ex

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ defmodule Hyper.Node.FireVMM.Jailer do
3636
first failure.
3737
"""
3838

39-
alias Hyper.Config
40-
4139
@doc "Run every pre-requisite check, halting at the first failure."
4240
@spec run() :: :ok | {:error, term()}
4341
def run do
@@ -63,7 +61,7 @@ defmodule Hyper.Node.FireVMM.Jailer do
6361
end
6462

6563
defp parent_cgroup_present do
66-
if Sys.Linux.Cgroup.V2.named_exists?(Config.parent_cgroup()),
64+
if Sys.Linux.Cgroup.V2.named_exists?(Hyper.Cfg.Jails.cgroup()),
6765
do: :ok,
6866
else: {:error, :missing_parent_cgroup}
6967
end
@@ -108,7 +106,7 @@ defmodule Hyper.Node.FireVMM.Jailer do
108106
"--cgroup-version",
109107
"2",
110108
"--parent-cgroup",
111-
Hyper.Config.parent_cgroup()
109+
Hyper.Cfg.Jails.cgroup()
112110
] ++
113111
cgroup_flags(opts.type) ++
114112
["--", "--api-sock", "/" <> @jail_socket]
@@ -145,7 +143,7 @@ defmodule Hyper.Node.FireVMM.Jailer do
145143
"""
146144
@spec cgroup_dir(Hyper.Vm.id()) :: Path.t()
147145
def cgroup_dir(id) do
148-
Path.join(["/sys/fs/cgroup", Hyper.Config.parent_cgroup(), exec_name(), id])
146+
Path.join(["/sys/fs/cgroup", Hyper.Cfg.Jails.cgroup(), exec_name(), id])
149147
end
150148

151149
@doc """

lib/hyper/node/users.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ defmodule Hyper.Node.Users do
7777
def test_system do
7878
alias Sys.Linux.Subid
7979

80-
{min, max} = Hyper.Config.uid_gid_range()
80+
{min, max} = Hyper.Cfg.Jails.uid_gid_range()
8181

8282
cond do
8383
passwd_conflicts(min, max) != [] ->
@@ -99,7 +99,7 @@ defmodule Hyper.Node.Users do
9999

100100
@impl true
101101
def init(_opts) do
102-
{min, max} = Hyper.Config.uid_gid_range()
102+
{min, max} = Hyper.Cfg.Jails.uid_gid_range()
103103
{:ok, %State{max: max, next: min}}
104104
end
105105

test/hyper/cfg/jails_test.exs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
defmodule Hyper.Cfg.JailsTest do
2+
use ExUnit.Case, async: false
3+
4+
alias Hyper.Cfg.Jails
5+
alias Hyper.Cfg.Toml
6+
7+
setup do
8+
Toml.put_cache(%{})
9+
on_exit(fn -> Toml.reload() end)
10+
:ok
11+
end
12+
13+
test "defaults match the helper's compiled-in defaults" do
14+
assert Jails.cgroup() == "hyper"
15+
assert Jails.uid_gid_range() == {900_000, 999_999}
16+
end
17+
18+
test "reads the [jails] table when present" do
19+
Toml.put_cache(%{"jails" => %{"cgroup" => "fleet", "uid_gid_range" => [800_000, 899_999]}})
20+
assert Jails.cgroup() == "fleet"
21+
assert Jails.uid_gid_range() == {800_000, 899_999}
22+
end
23+
24+
test "uid_gid_range parses a TOML [min, max] array into a tuple" do
25+
assert Jails.range_from([800_000, 899_999]) == {800_000, 899_999}
26+
assert Jails.range_from(nil) == {900_000, 999_999}
27+
assert Jails.range_from("garbage") == {900_000, 999_999}
28+
end
29+
end

0 commit comments

Comments
 (0)