Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions codchi/src/config/codchi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ pub struct CodchiConfig {
#[serde(default)]
pub enable_wsl_vpnkit: bool,

/// Isolate the network of each code machine
#[cfg(target_os = "windows")]
#[serde(default = "def_true")]
pub enable_wsl_netns: bool,

// $XDG_DATA_HOME/codchi by default
pub data_dir: Option<String>,
}
Expand Down Expand Up @@ -104,6 +109,11 @@ impl ConfigMut {
self.doc["enable_wsl_vpnkit"] = value(enable);
}

#[cfg(target_os = "windows")]
pub fn enable_wsl_netns(&mut self, enable: bool) {
self.doc["enable_wsl_netns"] = value(enable);
}

#[cfg(target_os = "windows")]
pub fn vcxsrv_enable(&mut self, enable: bool) {
self.doc["vcxsrv"]["enable"] = value(enable);
Expand Down
16 changes: 14 additions & 2 deletions codchi/src/platform/machine.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{platform::HostImpl, Host, LinuxCommandBuilder, LinuxCommandTarget, LinuxUser};
use crate::{
cli::{CODCHI_DRIVER_MODULE, DEBUG},
config::{ConfigResult, FlakeLocation, MachineConfig},
config::{CodchiConfig, ConfigResult, FlakeLocation, MachineConfig},
consts::{self, host, ToPath},
logging::{hide_progress, log_progress, set_progress_status},
platform::{self, CommandExt, Driver, Store},
Expand Down Expand Up @@ -277,6 +277,18 @@ fi
if *DEBUG { "1" } else { "" }.to_string(),
);
env.insert("MACHINE_NAME".to_string(), self.config.name.clone());
#[cfg(target_os = "windows")]
{
env.insert(
"ENABLE_NETNS".to_string(),
if CodchiConfig::get().enable_wsl_netns {
"1"
} else {
""
}
.to_string(),
);
}

let mut env_file = File::options()
.write(true)
Expand Down Expand Up @@ -346,7 +358,7 @@ if [ ! -e system ]; then
ndd $NIX_VERBOSITY profile install --option warn-dirty false --profile system \
'.#nixosConfigurations.default.config.system.build.toplevel'
else
ndd $NIX_VERBOSITY profile upgrade --option warn-dirty false --profile system '.*'
ndd $NIX_VERBOSITY profile upgrade --option warn-dirty false --profile system --all
fi
pwd
git add flake.*
Expand Down
9 changes: 8 additions & 1 deletion codchi/src/platform/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,19 @@ impl MachineDriver for Machine {

fn start(&self) -> Result<()> {
{
let cfg = CodchiConfig::get();
let mut env = self.config.secrets.clone();

// TODO consolidate with Machine::write_env_file
env.insert(
"DEBUG".to_string(),
if *DEBUG { "1" } else { "" }.to_string(),
);
env.insert("MACHINE_NAME".to_string(), self.config.name.clone());
env.insert(
"ENABLE_NETNS".to_string(),
if cfg.enable_wsl_netns { "1" } else { "" }.to_string(),
);

// machine must run to write env file into it...
let env_path = machine::CODCHI_ENV_TMP.to_host_path(&machine_name(&self.config.name));
Expand Down Expand Up @@ -564,6 +570,7 @@ impl LinuxCommandTarget for LinuxCommandDriver {
cwd: &Option<LinuxPath>,
_env: &HashMap<String, String>,
) -> std::process::Command {
let cfg = CodchiConfig::get();
let mut cmd = wsl_command();
cmd.args(["-d", &self.instance_name]);
cmd.args(["--cd", &cwd.clone().map(|p| p.0).unwrap_or("/".to_string())]);
Expand All @@ -585,7 +592,7 @@ impl LinuxCommandTarget for LinuxCommandDriver {
wslenv.push(
"CODCHI_DEBUG:CODCHI_MACHINE_NAME:CODCHI_IS_STORE:WSL_CODCHI_DIR_CONFIG/up:WSL_CODCHI_DIR_DATA/up",
);
if CodchiConfig::get().vcxsrv.enable {
if cfg.vcxsrv.enable {
cmd.env("CODCHI_WSL_USE_VCXSRV", "1");
wslenv.push(":CODCHI_WSL_USE_VCXSRV");
}
Expand Down
5 changes: 5 additions & 0 deletions codchi/src/tray/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ pub fn run() -> Result<()> {
},
],
});
settings.push(mk_checkbox(
"Isolate the network of each code machine (requires restarting machines)",
|config| config.enable_wsl_netns,
|cfg, enabled| cfg.enable_wsl_vpnkit(enabled),
));
settings.push(mk_checkbox(
"Enable wsl-vpnkit",
|config| config.enable_wsl_vpnkit,
Expand Down
6 changes: 5 additions & 1 deletion nix/container/consts.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{ consts, ... }: {

_module.args.consts = {
store = {
store = rec {
DIR_CONFIG = "/config";
DIR_CONFIG_STORE = "${consts.store.DIR_CONFIG}/store";
PROFILE_STORE = "${consts.store.DIR_CONFIG_STORE}/profile";
Expand All @@ -17,11 +17,15 @@
# WSL tricks
DIR_MACHINE_DATA = "/machine-data";
DIR_MACHINE_DATA_MACHINE = "${consts.store.DIR_MACHINE_DATA}/machine/$CODCHI_MACHINE_NAME";

NETNS_SUBNET_BASE = "10.6.3";
NETNS_BRIDGE_ADDR = "${NETNS_SUBNET_BASE}.1";
};
machine = {
USER = "codchi";
INIT_ENV = "/etc/codchi-env";
};

};


Expand Down
7 changes: 6 additions & 1 deletion nix/container/machine/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ in
''
set -euo pipefail

# allows ip netns exec in WSL
exec_systemd() {
exec "$@"
}

# Use config.system.binPackages and PATH from host
export LANG="C.UTF-8" HOME=/root PATH="/bin:$PATH"
${cfg.init.hostSetup}
Expand Down Expand Up @@ -81,7 +86,7 @@ in
# TODO ?? Reset the logging file descriptors.

echo "starting systemd..."
exec /run/current-system/systemd/lib/systemd/systemd "--log-target=kmsg" "$@"
exec_systemd /run/current-system/systemd/lib/systemd/systemd "--log-target=kmsg" "$@"
'';
};

Expand Down
70 changes: 70 additions & 0 deletions nix/container/machine/wsl.nix
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ in
systemctl is-system-running | grep -E "running|degraded"
'';

# for netns
binPackages = with pkgs.pkgsStatic; [ iproute2 fping ];

machine.init.hostSetup = /* bash */ ''
[ -d /etc ] || mkdir /etc

Expand Down Expand Up @@ -87,6 +90,73 @@ in

exec 1> >(tee -i "${INIT_LOG}" >&2) 2>&1

setup_namespace() {
echo "Searching for unused IP..." >&2
BR_ADDR="${consts.store.NETNS_BRIDGE_ADDR}"
VPEER_ADDR="$(fping -c 1 -i 1 -r 0 -u -t 100 -g "${consts.store.NETNS_SUBNET_BASE}.0/24" 2>/dev/null |
grep "timed out" |
grep -v "$BR_ADDR" |
head -n1 |
cut -d' ' -f1)"

if [ -n "$VPEER_ADDR" ]; then
BR_DEV="codchibr"

NS="cns$(echo "$VPEER_ADDR" | cut -d'.' -f4)"
VETH="veth$NS"
VPEER="vpeer$NS"

echo "Using IP $VPEER_ADDR for namespace $NS" >&2

if [ ! -d /var/run/netns ]; then
mkdir -p /var/run
mount -t tmpfs -o size=10m tmpfs /var/run
mkdir /var/run/netns || true
fi

# setup namespace
ip netns del "$NS" &>/dev/null || true
ip netns add "$NS"

# setup veth link
ip link add "$VETH" type veth peer name "$VPEER"
ip link set "$VETH" up

# assign veth pairs to bridge
ip link set "$VETH" master "$BR_DEV"

# add peers to ns
ip link set "$VPEER" netns "$NS"

# setup loopback interface
ip netns exec "$NS" ip link set lo up

# setup peer ns interface
ip netns exec "$NS" ip link set "$VPEER" up

# assign ip address to ns interfaces
ip netns exec "$NS" ip addr add "$VPEER_ADDR/24" dev "$VPEER"

# add default routes for ns
ip netns exec "$NS" ip route add default via "$BR_ADDR"

exec_systemd() {
exec ip netns exec "$NS" "$@"
}
else
echo "Couldn't find IP. Disabling network namespace" >&2
return 1
fi
}

if [ -n "''${CODCHI_ENABLE_NETNS:-}" ]; then
echo "Enabling network namespaces for this machine" >&2
setup_namespace || echo "Failed creating namespace. Continuing without network isolation..." >&2
else
env >&2
echo "NOT enabling network namespaces for this machine" >&2
fi

mkMnt() {
src="$1"
target="$2"
Expand Down
2 changes: 2 additions & 0 deletions nix/container/store/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ in
# user & groups required for minimal linux + `nix daemon`
"/etc/group" = ./etc/group;
"/etc/passwd" = ./etc/passwd;
"/etc/protocols" = "${pkgs.iana-etc}/etc/protocols";
"/etc/services" = "${pkgs.iana-etc}/etc/services";
# required for dns / other information lookup systems (mainly glibc)
"/etc/nsswitch.conf" = ./etc/nsswitch.conf;
# nix settings
Expand Down
21 changes: 21 additions & 0 deletions nix/container/store/wsl.nix
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,27 @@ in
runtimePackages = with pkgs; [ daemonize ];

store.init.services = lib.mkForce /* bash */ ''
setup_bridge() {
echo "Creating codchibr..." >&2
BR_ADDR="${consts.store.NETNS_BRIDGE_ADDR}"
BR_DEV="codchibr"

# setup bridge
ip link delete "$BR_DEV" &>/dev/null || true
ip link add "$BR_DEV" type bridge
ip link set "$BR_DEV" up
ip addr add "$BR_ADDR/24" dev "$BR_DEV"

# enable ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# flush & apply nat rules
nix run nixpkgs#iptables -- -t nat -F
nix run nixpkgs#iptables -- -t nat -A POSTROUTING -s "$BR_ADDR/24" ! -o "$BR_DEV" -j MASQUERADE
}

setup_bridge || echo "Failed to setup codchibr. Network namespaces will be disabled." >&2

daemonize $(which nix) daemon
'';
};
Expand Down
Loading