Compare commits
4 commits
5f58a2ebb2
...
20451db88c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20451db88c | ||
|
|
927db90791 | ||
|
|
dc583da67e | ||
|
|
6dcd2a370a |
4 changed files with 179 additions and 36 deletions
|
|
@ -7,6 +7,8 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include <linux/vm_sockets.h>
|
||||||
|
|
||||||
struct msghdr mk_msghdr();
|
struct msghdr mk_msghdr();
|
||||||
int ch_connect(const char*, const char*);
|
int ch_connect(const char*, const char*);
|
||||||
ssize_t send_fd(int, int);
|
ssize_t send_fd(int, int);
|
||||||
|
|
@ -18,7 +20,8 @@ void print_usage() {
|
||||||
"Usage:\n"
|
"Usage:\n"
|
||||||
"\tch-proxy uvm/$USER_VM_NAME [PORT]\n"
|
"\tch-proxy uvm/$USER_VM_NAME [PORT]\n"
|
||||||
"\tch-proxy uuvm/$VM_NAME [PORT]\n"
|
"\tch-proxy uuvm/$VM_NAME [PORT]\n"
|
||||||
"\tch-proxy vsock-mux%$PATH [PORT]\n");
|
"\tch-proxy vsock-mux%$PATH [PORT]\n"
|
||||||
|
"\tch-proxy vsock/cid[:port]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *extract_vsock_mux(const char *host_string) {
|
char *extract_vsock_mux(const char *host_string) {
|
||||||
|
|
@ -67,6 +70,50 @@ char *extract_muvm(const char *host_string) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int extract_cid(const char *host, int *cid, int *port) {
|
||||||
|
if (errno != 0) {
|
||||||
|
perror("extract_cid(...): errno unclean");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char PREFIX[] = "vsock/";
|
||||||
|
const ssize_t PREFIX_LEN = sizeof(PREFIX) - 1;
|
||||||
|
|
||||||
|
if (strncmp(host, PREFIX, PREFIX_LEN) != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *in = NULL;
|
||||||
|
const char *end = host + strlen(host);
|
||||||
|
const char *sCid = host + PREFIX_LEN;
|
||||||
|
|
||||||
|
long x;
|
||||||
|
x = strtol(sCid, &in, 10);
|
||||||
|
if (errno != 0) {
|
||||||
|
perror("strtol(cid, ...)");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
*cid = (int) x;
|
||||||
|
|
||||||
|
if (in == end) {
|
||||||
|
*port = 22;
|
||||||
|
return 0;
|
||||||
|
} else if (in[0] != ':') {
|
||||||
|
perror("extract_cid(...): expected a string of the form cid[:port]");
|
||||||
|
perror(host);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *sPort = in + 1;
|
||||||
|
x = strtol(sPort, &in, 10);
|
||||||
|
if (errno != 0) {
|
||||||
|
perror("strtol(port, ...)");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
*port = (int) x;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
if (!(2 <= argc && argc <= 3)) {
|
if (!(2 <= argc && argc <= 3)) {
|
||||||
fprintf(stderr, "%s: Wrong # of arguments: %d\n", argv[0], argc);
|
fprintf(stderr, "%s: Wrong # of arguments: %d\n", argv[0], argc);
|
||||||
|
|
@ -79,21 +126,47 @@ int main(int argc, char** argv) {
|
||||||
const char *ssh_host = argv[1];
|
const char *ssh_host = argv[1];
|
||||||
const char *port_string = argc == 3 ? argv[2] : PORT_DEFAULT;
|
const char *port_string = argc == 3 ? argv[2] : PORT_DEFAULT;
|
||||||
|
|
||||||
char *path_un;
|
int cid = -1, port = -1;
|
||||||
|
char *path_un = NULL;
|
||||||
if ((path_un = extract_uvm(ssh_host)) != NULL) {
|
if ((path_un = extract_uvm(ssh_host)) != NULL) {
|
||||||
} else if ((path_un = extract_muvm(ssh_host)) != NULL) {
|
} else if ((path_un = extract_muvm(ssh_host)) != NULL) {
|
||||||
} else if ((path_un = extract_vsock_mux(ssh_host)) != NULL) {
|
} else if ((path_un = extract_vsock_mux(ssh_host)) != NULL) {
|
||||||
|
} else if (extract_cid(ssh_host, &cid, &port) == 0) {
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "ch-proxy/main: unexpected host stirng format: %s\n", ssh_host);
|
fprintf(stderr, "ch-proxy/main: unexpected host string format: %s\n", ssh_host);
|
||||||
print_usage();
|
print_usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int s = ch_connect(path_un, port_string);
|
int s = -1;
|
||||||
|
|
||||||
|
if (path_un != NULL) {
|
||||||
|
s = ch_connect(path_un, port_string);
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
perror("ssh-vsock-proxy/main/ch_connect");
|
perror("ssh-vsock-proxy/main/ch_connect");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
};
|
};
|
||||||
|
} else if (cid != -1 && port != -1) {
|
||||||
|
struct sockaddr_vm sa = {
|
||||||
|
.svm_family = AF_VSOCK,
|
||||||
|
.svm_reserved1 = 0,
|
||||||
|
.svm_port = port,
|
||||||
|
.svm_cid = cid,
|
||||||
|
};
|
||||||
|
memset(sa.svm_zero, 0, sizeof(sa.svm_zero));
|
||||||
|
s = socket(AF_VSOCK, SOCK_STREAM, 0);
|
||||||
|
if (s == -1) {
|
||||||
|
perror("socket(AF_VSOCK, ...)");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) != 0) {
|
||||||
|
perror("connect(socket(AF_VSOCK, ...), ...)");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
perror("Couldn't parse neither uuvm/ strings nor vsock/cid[:port]");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (send_fd(1, s) == -1) {
|
if (send_fd(1, s) == -1) {
|
||||||
perror("ssh-vsock-proxy/main/send_fd");
|
perror("ssh-vsock-proxy/main/send_fd");
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
lib,
|
lib,
|
||||||
newScope,
|
newScope,
|
||||||
makeDesktopItem,
|
makeDesktopItem,
|
||||||
|
writeShellScript,
|
||||||
writeShellScriptBin,
|
writeShellScriptBin,
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
|
@ -18,12 +19,17 @@ lib.makeScope newScope (self: {
|
||||||
mkRunInVM = vmName: lib.getExe (self.mkRunInVMPkg vmName);
|
mkRunInVM = vmName: lib.getExe (self.mkRunInVMPkg vmName);
|
||||||
mkRunInVMPkg =
|
mkRunInVMPkg =
|
||||||
vmName:
|
vmName:
|
||||||
writeShellScriptBin "run-in-${vmName}" ''
|
lib.warn "Use `\${runInVM} foobar` instead of `\${mkRunInVMPkg foobar}`" (
|
||||||
|
writeShellScriptBin "run-in-${vmName}" "${lib.getExe self.runInVM} ${vmName} $@"
|
||||||
|
);
|
||||||
|
runInVM = writeShellScriptBin "run-in" ''
|
||||||
|
vmName=$1
|
||||||
|
shift
|
||||||
localArgs=(
|
localArgs=(
|
||||||
${lib.optionalString self.useSessionUnits "--user"}
|
${lib.optionalString self.useSessionUnits "--user"}
|
||||||
--property=Requires=${self.vmUnitPrefix}${vmName}.service
|
--property=Requires="${self.vmUnitPrefix}$vmName".service
|
||||||
--property=After=${self.vmUnitPrefix}${vmName}.service
|
--property=After="${self.vmUnitPrefix}$vmName".service
|
||||||
--property=SyslogIdentifier="$1 (${vmName})"
|
--property=SyslogIdentifier="$1 ($vmName)"
|
||||||
)
|
)
|
||||||
remoteArgs=(
|
remoteArgs=(
|
||||||
systemd-run
|
systemd-run
|
||||||
|
|
@ -38,7 +44,7 @@ lib.makeScope newScope (self: {
|
||||||
)
|
)
|
||||||
systemd-run \
|
systemd-run \
|
||||||
"''${localArgs[@]}" \
|
"''${localArgs[@]}" \
|
||||||
ssh ${self.vmUser}@${self.vmSshPrefix}${vmName} \
|
ssh "${self.vmUser}@${self.vmSshPrefix}$vmName" \
|
||||||
"''${remoteArgs[@]}" $@
|
"''${remoteArgs[@]}" $@
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
|
||||||
63
pkgs/request-usb/package.nix
Normal file
63
pkgs/request-usb/package.nix
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
{ writeShellScriptBin }:
|
||||||
|
|
||||||
|
writeShellScriptBin "request-usb" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
parseArgs() {
|
||||||
|
N_CONSTRAINTS=0
|
||||||
|
while [[ -n "''${1:-}" ]]; do
|
||||||
|
local x=
|
||||||
|
case "$1" in
|
||||||
|
"--manufacturer" )
|
||||||
|
N_CONSTRAINTS=$(( $N_CONSTRAINTS + 1 ))
|
||||||
|
MANUFACTURER="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
"--manufacturer="* )
|
||||||
|
N_CONSTRAINTS=$(( $N_CONSTRAINTS + 1 ))
|
||||||
|
MANUFACTURER=''${1#--manufacturer=}
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
"--" )
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printUsage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
printUsage() {
|
||||||
|
echo "$(caller)" >&2
|
||||||
|
echo "Usage: request-usb [--manufacturer=MANUFACTURER]" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
findFirst() {
|
||||||
|
local d=
|
||||||
|
|
||||||
|
[[ ''${N_CONSTRAINTS:-0} != 0 ]] || printUsage
|
||||||
|
for d in /sys/bus/usb/devices/* ; do
|
||||||
|
[[ -e "$d/manufacturer" ]] || continue
|
||||||
|
[[ -e "$d/uevent" ]] || continue
|
||||||
|
|
||||||
|
read -r x < "$d/manufacturer"
|
||||||
|
if ! [[ -z "''${MANUFACTURER:-}" || "$MANUFACTURER" = "$x" ]] ; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# NOTE: Other predicates here
|
||||||
|
# ...
|
||||||
|
|
||||||
|
echo -n "$d"
|
||||||
|
return
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
parseArgs $@
|
||||||
|
d=$(findFirst)
|
||||||
|
export $( cat "$d/uevent" )
|
||||||
|
sudo chown "$USER" /dev/bus/usb/"$BUSNUM"/"$DEVNUM"
|
||||||
|
echo -n /dev/bus/usb/"$BUSNUM"/"$DEVNUM"
|
||||||
|
''
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
inherit (config._module.args) inputs;
|
||||||
cfg = config.vmapps;
|
cfg = config.vmapps;
|
||||||
desktopItems' = pkgs.callPackage ../pkgs/desktopAdapters.nix { };
|
desktopItems' = pkgs.callPackage ../pkgs/desktopAdapters.nix { };
|
||||||
desktopItems = desktopItems'.overrideScope (
|
desktopItems = desktopItems'.overrideScope (
|
||||||
|
|
@ -28,8 +29,8 @@ let
|
||||||
modules = extraModules ++ [
|
modules = extraModules ++ [
|
||||||
{
|
{
|
||||||
microvm.hypervisor = "cloud-hypervisor";
|
microvm.hypervisor = "cloud-hypervisor";
|
||||||
microvm.hotpluggedMem = 128;
|
microvm.hotpluggedMem = lib.mkDefault 128;
|
||||||
microvm.hotplugMem = 512;
|
microvm.hotplugMem = lib.mkDefault 512;
|
||||||
microvm.shares = [
|
microvm.shares = [
|
||||||
{
|
{
|
||||||
source = "send";
|
source = "send";
|
||||||
|
|
@ -50,10 +51,10 @@ let
|
||||||
./uvms-guest.nix
|
./uvms-guest.nix
|
||||||
./vsock-connect-guest.nix
|
./vsock-connect-guest.nix
|
||||||
(modulesPath + "/profiles/minimal.nix")
|
(modulesPath + "/profiles/minimal.nix")
|
||||||
(config._module.args.inputs."microvm.nix" + "/nixos-modules/microvm")
|
(inputs."microvm.nix" + "/nixos-modules/microvm")
|
||||||
];
|
];
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit (config._module.args) inputs;
|
inherit inputs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
runner = evaluated.config.microvm.declaredRunner;
|
runner = evaluated.config.microvm.declaredRunner;
|
||||||
|
|
@ -239,7 +240,7 @@ in
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
(desktopItems.mkRunInVMPkg "browser")
|
(desktopItems.runInVM)
|
||||||
(pkgs.makeDesktopItem (
|
(pkgs.makeDesktopItem (
|
||||||
desktopItems.toBrowser (
|
desktopItems.toBrowser (
|
||||||
(desktopItems.toVM "browser" {
|
(desktopItems.toVM "browser" {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue