Hallelujah
This commit is contained in:
parent
4e86dfc567
commit
ddb2fa0d4b
18
Makefile
18
Makefile
|
@ -73,32 +73,24 @@ endif
|
|||
|
||||
IMAGE_HASH := -e RIJU_IMAGE_HASH="$$(docker inspect riju:$(LANG_TAG) | jq '.[0].Config.Labels["riju.image-hash"]' -r)"
|
||||
|
||||
shell: # I=<shell> [L=<lang>] [E=1] [P1|P2=<port>] : Launch Docker image with shell
|
||||
shell: # I=<shell> [L=<lang>] [E[E]=1] [P1|P2=<port>] : Launch Docker image with shell
|
||||
@: $${I}
|
||||
ifneq (,$(filter $(I),admin ci))
|
||||
@mkdir -p $(HOME)/.aws $(HOME)/.docker $(HOME)/.ssh $(HOME)/.terraform.d
|
||||
docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/docker.sock:/var/run/docker.sock -v $(HOME)/.aws:/var/riju/.aws -v $(HOME)/.docker:/var/riju/.docker -v $(HOME)/.ssh:/var/riju/.ssh -v $(HOME)/.terraform.d:/var/riju/.terraform.d -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e DOCKER_USERNAME -e DOCKER_PASSWORD -e DEPLOY_SSH_PRIVATE_KEY -e DOCKER_REPO -e S3_BUCKET -e DOMAIN -e VOLUME_MOUNT=$(VOLUME_MOUNT) $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) --network host riju:$(I) $(BASH_CMD)
|
||||
docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/docker.sock:/var/run/docker.sock -v $(HOME)/.aws:/var/run/riju/.aws -v $(HOME)/.docker:/var/run/riju/.docker -v $(HOME)/.ssh:/var/run/riju/.ssh -v $(HOME)/.terraform.d:/var/run/riju/.terraform.d -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e DOCKER_USERNAME -e DOCKER_PASSWORD -e DEPLOY_SSH_PRIVATE_KEY -e DOCKER_REPO -e S3_BUCKET -e DOMAIN -e VOLUME_MOUNT=$(VOLUME_MOUNT) $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) --network host riju:$(I) $(BASH_CMD)
|
||||
else ifeq ($(I),app)
|
||||
docker run -it --rm --hostname $(I) $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(I) $(BASH_CMD)
|
||||
docker run -it --rm --hostname $(I) -v /var/run/riju:/var/run/riju -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(I) $(BASH_CMD)
|
||||
else ifneq (,$(filter $(I),base lang))
|
||||
ifeq ($(I),lang)
|
||||
@: $${L}
|
||||
endif
|
||||
docker run -it --rm --hostname $(LANG_TAG) -v $(VOLUME_MOUNT):/src --label riju-install-target=yes $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(LANG_TAG) $(BASH_CMD)
|
||||
docker run -it --rm --hostname $(LANG_TAG) -v $(VOLUME_MOUNT):/src $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(LANG_TAG) $(BASH_CMD)
|
||||
else ifeq ($(I),runtime)
|
||||
docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(I) $(BASH_CMD)
|
||||
docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/riju:/var/run/riju -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(I) $(BASH_CMD)
|
||||
else
|
||||
docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(I) $(BASH_CMD)
|
||||
endif
|
||||
|
||||
## This is equivalent to 'make pkg' in a fresh packaging container
|
||||
## followed by 'make install' in a persistent runtime container.
|
||||
|
||||
repkg: script # L=<lang> T=<type> : Build fresh .deb and install into live container
|
||||
@: $${L} $${T}
|
||||
$(MAKE_QUIETLY) shell I=packaging CMD="make pkg L=$(L) T=$(T)"
|
||||
ctr="$$(docker container ls -f label="riju-install-target=yes" -l -q)"; test "$${ctr}" || (echo "no valid container is live"; exit 1); docker exec "$${ctr}" make install L=$(L) T=$(T)
|
||||
|
||||
### Build packaging scripts
|
||||
|
||||
script: # L=<lang> T=<type> : Generate a packaging script
|
||||
|
|
|
@ -48,7 +48,6 @@ export class Session {
|
|||
};
|
||||
|
||||
privilegedSession = () => util.privilegedSession(this.context);
|
||||
privilegedWait = () => util.privilegedWait(this.context);
|
||||
privilegedExec = (cmdline) =>
|
||||
util.privilegedExec(this.context, bash(cmdline));
|
||||
privilegedPty = (cmdline) =>
|
||||
|
@ -64,13 +63,6 @@ export class Session {
|
|||
this.container = {
|
||||
pty: containerPty,
|
||||
};
|
||||
containerPty.on("data", (data) =>
|
||||
this.send({
|
||||
event: "serviceLog",
|
||||
service: "container",
|
||||
output: data.toString("utf8"),
|
||||
})
|
||||
);
|
||||
containerPty.on("close", (code, signal) =>
|
||||
this.send({
|
||||
event: "serviceFailed",
|
||||
|
@ -85,7 +77,26 @@ export class Session {
|
|||
error: `${err}`,
|
||||
})
|
||||
);
|
||||
await this.run(this.privilegedWait(this.context));
|
||||
let buffer = "";
|
||||
await new Promise((resolve) => {
|
||||
containerPty.on("data", (data) => {
|
||||
buffer += data;
|
||||
let idx;
|
||||
while ((idx = buffer.indexOf("\r\n")) !== -1) {
|
||||
const line = buffer.slice(0, idx);
|
||||
buffer = buffer.slice(idx + 2);
|
||||
if (line === "riju: container ready") {
|
||||
resolve();
|
||||
} else {
|
||||
this.send({
|
||||
event: "serviceLog",
|
||||
service: "container",
|
||||
output: line + "\n",
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
if (this.config.setup) {
|
||||
await this.run(this.privilegedExec(this.config.setup));
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
privilegedExec,
|
||||
privilegedPty,
|
||||
privilegedSession,
|
||||
privilegedWait,
|
||||
quote,
|
||||
run,
|
||||
} from "./util.js";
|
||||
|
@ -38,7 +37,22 @@ async function main() {
|
|||
const session = pty.spawn(sessionArgs[0], sessionArgs.slice(1), {
|
||||
name: "xterm-color",
|
||||
});
|
||||
await run(privilegedWait({ uuid }), log);
|
||||
let buffer = "";
|
||||
await new Promise((resolve) => {
|
||||
session.on("data", (data) => {
|
||||
buffer += data;
|
||||
let idx;
|
||||
while ((idx = buffer.indexOf("\r\n")) !== -1) {
|
||||
const line = buffer.slice(0, idx);
|
||||
buffer = buffer.slice(idx + 2);
|
||||
if (line === "riju: container ready") {
|
||||
resolve();
|
||||
} else {
|
||||
console.error(line);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
const args = privilegedPty(
|
||||
{ uuid },
|
||||
bash(
|
||||
|
|
|
@ -51,10 +51,6 @@ export function privilegedSession({ uuid, lang }) {
|
|||
return [rijuSystemPrivileged, "session", uuid, lang];
|
||||
}
|
||||
|
||||
export function privilegedWait({ uuid }) {
|
||||
return [rijuSystemPrivileged, "wait", uuid];
|
||||
}
|
||||
|
||||
export function privilegedExec({ uuid }, args) {
|
||||
return [rijuSystemPrivileged, "exec", uuid].concat(args);
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ RUN /tmp/install.bash
|
|||
WORKDIR /src
|
||||
COPY docker/shared/my_init /usr/local/sbin/
|
||||
COPY docker/shared/admin-pid1.bash /usr/local/sbin/pid1.bash
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--", "/usr/local/sbin/pid1.bash"]
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--skip-runit", "--", "/usr/local/sbin/pid1.bash"]
|
||||
CMD ["bash"]
|
||||
|
|
|
@ -24,7 +24,7 @@ COPY langs ./langs/
|
|||
|
||||
FROM riju:runtime
|
||||
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--"]
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--skip-runit","--"]
|
||||
RUN useradd -p '!' -m -l -s /usr/bin/bash riju
|
||||
COPY --chown=riju:riju --from=build /src ./
|
||||
RUN chown root:riju system/out/*-privileged && chmod a=,g=rx,u=rwxs system/out/*-privileged
|
||||
|
|
|
@ -8,5 +8,5 @@ RUN runuser -u riju -- mkdir /home/riju/src
|
|||
WORKDIR /home/riju/src
|
||||
|
||||
COPY docker/shared/my_init /usr/local/sbin/
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--"]
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--skip-runit", "--"]
|
||||
CMD ["bash"]
|
||||
|
|
|
@ -6,5 +6,5 @@ RUN /tmp/install.bash
|
|||
WORKDIR /src
|
||||
COPY docker/shared/my_init /usr/local/sbin/
|
||||
COPY docker/shared/admin-pid1.bash /usr/local/sbin/pid1.bash
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--", "/usr/local/sbin/pid1.bash"]
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--skip-runit", "--", "/usr/local/sbin/pid1.bash"]
|
||||
CMD ["bash"]
|
||||
|
|
|
@ -5,5 +5,5 @@ RUN /tmp/install.bash
|
|||
|
||||
WORKDIR /src
|
||||
COPY docker/shared/my_init docker/packaging/pid1.bash /usr/local/sbin/
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--", "/usr/local/sbin/pid1.bash"]
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--skip-runit", "--", "/usr/local/sbin/pid1.bash"]
|
||||
CMD ["bash"]
|
||||
|
|
|
@ -4,7 +4,7 @@ COPY docker/runtime/install.bash /tmp/
|
|||
RUN /tmp/install.bash
|
||||
|
||||
COPY docker/shared/my_init docker/runtime/pid1.bash /usr/local/sbin/
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--", "/usr/local/sbin/pid1.bash"]
|
||||
ENTRYPOINT ["/usr/local/sbin/my_init", "--quiet", "--skip-runit", "--", "/usr/local/sbin/pid1.bash"]
|
||||
|
||||
WORKDIR /src
|
||||
CMD ["bash"]
|
||||
|
|
|
@ -7,10 +7,10 @@ tee -a /etc/hosts >/dev/null <<< "127.0.0.1 $(hostname)"
|
|||
groupadd -g "$(stat -c %g "$PWD")" -o -p '!' -r riju
|
||||
useradd -u "$(stat -c %u "$PWD")" -g "$(stat -c %g "$PWD")" -o -p '!' -m -N -l -s /usr/bin/bash -G sudo riju
|
||||
|
||||
runuser -u riju -- ln -sT /var/riju/.aws /home/riju/.aws
|
||||
runuser -u riju -- ln -sT /var/riju/.docker /home/riju/.docker
|
||||
runuser -u riju -- ln -sT /var/riju/.ssh /home/riju/.ssh
|
||||
runuser -u riju -- ln -sT /var/riju/.terraform.d /home/riju/.terraform.d
|
||||
runuser -u riju -- ln -sT /var/run/riju/.aws /home/riju/.aws
|
||||
runuser -u riju -- ln -sT /var/run/riju/.docker /home/riju/.docker
|
||||
runuser -u riju -- ln -sT /var/run/riju/.ssh /home/riju/.ssh
|
||||
runuser -u riju -- ln -sT /var/run/riju/.terraform.d /home/riju/.terraform.d
|
||||
|
||||
runuser -u riju -- touch /home/riju/.sudo_as_admin_successful
|
||||
runuser -u riju -- tee -a /home/riju/.bashrc >/dev/null <<"EOF"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <signal.h>
|
||||
|
@ -8,6 +9,7 @@
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -21,7 +23,6 @@ void die_with_usage()
|
|||
{
|
||||
die("usage:\n"
|
||||
" riju-system-privileged session UUID LANG\n"
|
||||
" riju-system-privileged wait UUID\n"
|
||||
" riju-system-privileged exec UUID CMDLINE...\n"
|
||||
" riju-system-privileged pty UUID CMDLINE...");
|
||||
}
|
||||
|
@ -43,72 +44,88 @@ char *parseLang(char *lang) {
|
|||
return lang;
|
||||
}
|
||||
|
||||
void session(char *uuid, char *lang)
|
||||
{
|
||||
char *image, *container, *hostname;
|
||||
if (asprintf(&image, "riju:lang-%s", lang) < 0)
|
||||
die("asprintf failed");
|
||||
if (asprintf(&container, "riju-session-%s", uuid) < 0)
|
||||
die("asprintf failed");
|
||||
if (asprintf(&hostname, "HOSTNAME=%s", lang) < 0)
|
||||
die("asprintf failed");
|
||||
char *argv[] = {
|
||||
"docker",
|
||||
"run",
|
||||
"--rm", "-it",
|
||||
"-e", "HOME=/home/riju",
|
||||
"-e", hostname,
|
||||
"-e", "LANG=C.UTF-8",
|
||||
"-e", "LC_ALL=C.UTF-8",
|
||||
"-e", "LOGNAME=riju",
|
||||
"-e", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin",
|
||||
"-e", "PWD=/home/riju/src",
|
||||
"-e", "SHELL=/usr/bin/bash",
|
||||
"-e", "TERM=xterm-256color",
|
||||
"-e", "TMPDIR=/tmp",
|
||||
"-e", "USER=riju",
|
||||
"-e", "USERNAME=riju",
|
||||
"--hostname", lang,
|
||||
"--name", container,
|
||||
image, "cat", NULL,
|
||||
};
|
||||
execvp(argv[0], argv);
|
||||
die("execvp failed");
|
||||
}
|
||||
|
||||
void wait_alarm(int signum)
|
||||
{
|
||||
(void)signum;
|
||||
die("container did not come up within 1 second");
|
||||
}
|
||||
|
||||
void wait(char *uuid)
|
||||
void session(char *uuid, char *lang)
|
||||
{
|
||||
char *cmdline;
|
||||
if (asprintf(&cmdline, "docker inspect riju-session-%s >/dev/null 2>&1", uuid) < 0)
|
||||
char *image, *container, *hostname, *volume, *fifo;
|
||||
if (asprintf(&image, "riju:lang-%s", lang) < 0)
|
||||
die("asprintf failed");
|
||||
struct timespec ts;
|
||||
if (asprintf(&container, "riju-session-%s", uuid) < 0)
|
||||
die("asprintf failed");
|
||||
if (asprintf(&hostname, "HOSTNAME=%s", lang) < 0)
|
||||
die("asprintf failed");
|
||||
int rv = mkdir("/var/run/riju/sentinels", 0700);
|
||||
if (rv < 0 && errno != EEXIST)
|
||||
die("mkdir failed");
|
||||
char tmpdir[] = "/var/run/riju/sentinels/XXXXXX";
|
||||
if (mkdtemp(tmpdir) == NULL)
|
||||
die("mkdtemp failed");
|
||||
if (asprintf(&volume, "%s:/var/run/riju/sentinel", tmpdir) < 0)
|
||||
die("asprintf failed");
|
||||
if (asprintf(&fifo, "%s/fifo", tmpdir) < 0)
|
||||
die("asprintf failed");
|
||||
if (mknod(fifo, 0700 | S_IFIFO, 0) < 0)
|
||||
die("mknod failed");
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
die("fork failed");
|
||||
else if (pid == 0) {
|
||||
char *argv[] = {
|
||||
"docker",
|
||||
"run",
|
||||
"--rm",
|
||||
"-v", volume,
|
||||
"-e", "HOME=/home/riju",
|
||||
"-e", hostname,
|
||||
"-e", "LANG=C.UTF-8",
|
||||
"-e", "LC_ALL=C.UTF-8",
|
||||
"-e", "LOGNAME=riju",
|
||||
"-e", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin",
|
||||
"-e", "PWD=/home/riju/src",
|
||||
"-e", "SHELL=/usr/bin/bash",
|
||||
"-e", "TERM=xterm-256color",
|
||||
"-e", "TMPDIR=/tmp",
|
||||
"-e", "USER=riju",
|
||||
"-e", "USERNAME=riju",
|
||||
"--user", "root",
|
||||
"--hostname", lang,
|
||||
"--name", container,
|
||||
image, "cat", "/var/run/riju/sentinel/fifo", NULL,
|
||||
};
|
||||
execvp(argv[0], argv);
|
||||
die("execvp failed");
|
||||
}
|
||||
struct timespec ts; // 10ms
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1000 * 1000 * 10;
|
||||
signal(SIGALRM, wait_alarm);
|
||||
alarm(1);
|
||||
int fd;
|
||||
while (1) {
|
||||
FILE *proc = popen(cmdline, "r");
|
||||
if (proc == NULL)
|
||||
die("popen failed");
|
||||
char buf[1024];
|
||||
while (fgets(buf, 1024, proc) != NULL);
|
||||
if (ferror(proc))
|
||||
die("fgets failed");
|
||||
int status = pclose(proc);
|
||||
if (status < 0)
|
||||
die("pclose failed");
|
||||
if (WEXITSTATUS(status) == 0)
|
||||
fd = open(fifo, O_WRONLY);
|
||||
if (fd >= 0)
|
||||
break;
|
||||
if (errno != ENXIO)
|
||||
die("open failed");
|
||||
int rv = nanosleep(&ts, NULL);
|
||||
if (rv != 0 && rv != EINTR)
|
||||
if (rv != 0 && errno != EINTR)
|
||||
die("nanosleep failed");
|
||||
}
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
if (unlink(fifo) < 0)
|
||||
die("unlink failed");
|
||||
if (rmdir(tmpdir) < 0)
|
||||
die("rmdir failed");
|
||||
printf("riju: container ready\n"); // magic string
|
||||
if (waitpid(pid, NULL, 0) <= 0)
|
||||
die("waitpid failed");
|
||||
if (close(fd) < 0)
|
||||
die("close failed");
|
||||
}
|
||||
|
||||
void exec(char *uuid, int argc, char **cmdline, bool pty)
|
||||
|
@ -119,6 +136,7 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
|||
char *argvPrefix[] = {
|
||||
"docker",
|
||||
"exec",
|
||||
"--user", "riju",
|
||||
pty ? "-it" : "-i",
|
||||
container,
|
||||
};
|
||||
|
@ -134,8 +152,8 @@ void exec(char *uuid, int argc, char **cmdline, bool pty)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (setuid(0) != 0)
|
||||
die("setuid failed");
|
||||
if (seteuid(0) != 0)
|
||||
die("seteuid failed");
|
||||
if (argc < 2)
|
||||
die_with_usage();
|
||||
if (!strcmp(argv[1], "session")) {
|
||||
|
@ -146,13 +164,6 @@ int main(int argc, char **argv)
|
|||
session(uuid, lang);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[1], "wait")) {
|
||||
if (argc != 3)
|
||||
die_with_usage();
|
||||
char *uuid = parseUUID(argv[2]);
|
||||
wait(uuid);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[1], "exec")) {
|
||||
if (argc < 4)
|
||||
die_with_usage();
|
||||
|
|
Loading…
Reference in New Issue