More work on pull and list subcmds

This commit is contained in:
Radon Rosborough 2022-10-10 21:51:25 -07:00
parent a703944915
commit 31b0185505
2 changed files with 106 additions and 14 deletions

View File

@ -86,6 +86,14 @@ export async function run(args, log, options) {
});
}
export function privilegedList() {
return [rijuSystemPrivileged, "list"];
}
export function privilegedPull({ repo, tag }) {
return [rijuSystemPrivileged, "pull", repo, tag];
}
export function privilegedSession({ uuid, lang }) {
const cmdline = [rijuSystemPrivileged, "session", uuid, lang];
if (imageHashes[lang]) {

View File

@ -30,7 +30,8 @@ void init() { sentinel_bash[sentinel_bash_len - 1] = '\0'; }
void die_with_usage()
{
die("usage:\n"
" riju-system-privileged pull REPO:TAG\n"
" riju-system-privileged list\n"
" riju-system-privileged pull REPO TAG\n"
" riju-system-privileged session UUID LANG [IMAGE-HASH]\n"
" riju-system-privileged exec UUID CMDLINE...\n"
" riju-system-privileged pty UUID CMDLINE...\n"
@ -118,15 +119,26 @@ char *parseImageHash(char *imageHash)
return imageHash;
}
char *parseImage(char *image)
char *parseRepo(char *repo)
{
if (strnlen(image, 1025) > 1024)
die("illegal image name");
for (char *ptr = image; *ptr; ++ptr)
if (strnlen(repo, 501) > 500)
die("illegal repo name");
for (char *ptr = repo; *ptr; ++ptr)
if (!((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') ||
*ptr == ':' || *ptr == '/' || *ptr == '.' || *ptr == '-'))
die("illegal image name");
return image;
*ptr == '/' || *ptr == '.' || *ptr == '-' || *ptr == '_'))
die("illegal repo name");
return repo;
}
char *parseTag(char *tag)
{
if (strnlen(tag, 501) > 500)
die("illegal tag name");
for (char *ptr = tag; *ptr; ++ptr)
if (!((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= '0' && *ptr <= '9') ||
*ptr == '.' || *ptr == '-' || *ptr == '_'))
die("illegal tag name");
return tag;
}
char *timeout_msg;
@ -144,10 +156,75 @@ void sigalrm_kill_parent(int signum)
exit(EXIT_FAILURE);
}
void cmd_pull(char *image)
void cmd_list()
{
// This command prints a bunch of empty lines because there is no
// way to filter to a desired set of images. Caller is expected to
// remove empty lines because it's easier in JS than C.
char *argv[] = {
"docker", "pull", "--", image, NULL,
"docker",
"image",
"ls",
"--format",
"{{ if eq .Repository \"riju\" }}{{ .Tag }}{{ end }}",
NULL,
};
execvp(argv[0], argv);
die("execvp failed");
}
void cmd_pull(char *repo, char *tag)
{
char *localImage, *remoteImage;
if (asprintf(&remoteImage, "%s:%s", repo, tag) < 0)
die("asprintf failed");
if (asprintf(&localImage, "riju:%s", tag) < 0)
die("asprintf failed");
pid_t orig_ppid = getpid();
pid_t pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (freopen("/dev/null", "w", stdout) == NULL)
die("freopen failed");
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
char *argv[] = {
"docker", "inspect", "--", localImage, NULL,
};
execvp(argv[0], argv);
die("execvp failed");
}
siginfo_t info;
if (waitid(P_PID, pid, &info, WEXITED) < 0)
die("waitid failed");
if (info.si_status == 0) {
// Image exists already, no need to pull. It is only appropriate
// to use cmd_pull with immutable images.
return;
}
orig_ppid = getpid();
pid = fork();
if (pid < 0)
die("fork failed");
else if (pid == 0) {
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
die("prctl failed");
if (getppid() != orig_ppid)
exit(EXIT_FAILURE);
char *argv[] = {
"docker", "pull", "--", remoteImage, NULL,
};
execvp(argv[0], argv);
}
if (waitid(P_PID, pid, &info, WEXITED) < 0)
die("waitid failed");
if (info.si_status != 0)
die("child process failed");
char *argv[] = {
"docker", "tag", "--", remoteImage, localImage,
};
execvp(argv[0], argv);
die("execvp failed");
@ -512,11 +589,18 @@ int main(int argc, char **argv)
die("seteuid failed");
if (argc < 2)
die_with_usage();
if (!strcmp(argv[1], "pull")) {
if (argc != 3)
if (!strcmp(argv[1], "list")) {
if (argc != 2)
die_with_usage();
char *image = parseImage(argv[2]);
cmd_pull(image);
cmd_list();
return 0;
}
if (!strcmp(argv[1], "pull")) {
if (argc != 4)
die_with_usage();
char *repo = parseRepo(argv[2]);
char *tag = parseTag(argv[3]);
cmd_pull(repo, tag);
return 0;
}
if (!strcmp(argv[1], "session")) {