mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Flock: Stopping containers from CLI
This commit is contained in:
parent
f1519fc9b7
commit
d36ad6af6a
@ -31,7 +31,7 @@ struct container_runtime {
|
||||
uint hash;
|
||||
pid_t pid;
|
||||
sock *s;
|
||||
struct container_created_callback {
|
||||
struct container_operation_callback {
|
||||
callback cb;
|
||||
sock *s;
|
||||
void *data;
|
||||
@ -60,6 +60,19 @@ container_child_sighandler(int signo UNUSED)
|
||||
|
||||
static int container_forker_fd = -1;
|
||||
|
||||
static void
|
||||
container_poweroff(int fd, int sig)
|
||||
{
|
||||
byte outbuf[128];
|
||||
linpool *lp = lp_new(&root_pool);
|
||||
struct cbor_writer *cw = cbor_init(outbuf, sizeof outbuf, lp);
|
||||
cbor_open_block_with_length(cw, 1);
|
||||
cbor_add_int(cw, -4);
|
||||
cbor_add_int(cw, sig);
|
||||
ASSERT_DIE(write(fd, outbuf, cw->pt) == cw->pt);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
container_mainloop(int fd)
|
||||
{
|
||||
@ -83,15 +96,27 @@ container_mainloop(int fd)
|
||||
int res = ppoll(&pfd, 1, NULL, &newmask);
|
||||
|
||||
if (poweroff)
|
||||
container_poweroff(fd, poweroff);
|
||||
|
||||
if (pfd.revents & POLLIN)
|
||||
{
|
||||
byte outbuf[128];
|
||||
linpool *lp = lp_new(&root_pool);
|
||||
struct cbor_writer *cw = cbor_init(outbuf, sizeof outbuf, lp);
|
||||
cbor_open_block_with_length(cw, 1);
|
||||
cbor_add_int(cw, -4);
|
||||
cbor_add_int(cw, poweroff);
|
||||
ASSERT_DIE(write(fd, outbuf, cw->pt) == cw->pt);
|
||||
exit(0);
|
||||
byte buf[128];
|
||||
ssize_t sz = read(fd, buf, sizeof buf);
|
||||
if (sz < 0)
|
||||
{
|
||||
log(L_ERR "error reading data from control socket: %m");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ASSERT_DIE(sz >= 3);
|
||||
ASSERT_DIE(buf[0] == 0xa1);
|
||||
switch (buf[1]) {
|
||||
case 0:
|
||||
ASSERT_DIE(buf[2] == 0xf6);
|
||||
container_poweroff(fd, 0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: check for telnet socket */
|
||||
@ -203,6 +228,14 @@ container_start(void)
|
||||
|
||||
/* The Parent */
|
||||
|
||||
static void
|
||||
container_cleanup(struct container_runtime *crt)
|
||||
{
|
||||
HASH_REMOVE(hcf.hash, CRT, crt);
|
||||
sk_close(crt->s);
|
||||
mb_free(crt);
|
||||
}
|
||||
|
||||
static int
|
||||
hypervisor_container_rx(sock *sk, uint _sz UNUSED)
|
||||
{
|
||||
@ -215,7 +248,25 @@ hypervisor_container_rx(sock *sk, uint _sz UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
log(L_INFO "received %u data from %p (container_rx)", sz, sk);
|
||||
struct container_runtime *crt = sk->data;
|
||||
ASSERT_DIE(crt->s == sk);
|
||||
|
||||
ASSERT_DIE(sz >= 3);
|
||||
ASSERT_DIE(buf[0] == 0xa1);
|
||||
|
||||
switch (buf[1]) {
|
||||
case 0x23:
|
||||
log(L_INFO "container %s ended by signal %d", crt->ccf.hostname, buf[2]);
|
||||
if (crt->ccc)
|
||||
callback_activate(&crt->ccc->cb);
|
||||
container_cleanup(crt);
|
||||
break;
|
||||
|
||||
default:
|
||||
log(L_ERR "container %s sent a weird message 0x%02x sz %d", crt->ccf.hostname, buf[1], sz);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -267,18 +318,23 @@ hypervisor_container_forker_rx(sock *sk, uint _sz UNUSED)
|
||||
skl->type = SK_MAGIC;
|
||||
skl->rx_hook = hypervisor_container_rx;
|
||||
skl->fd = sfd;
|
||||
sk_set_tbsize(skl, 1024);
|
||||
|
||||
if (sk_open(skl, sk->loop) < 0)
|
||||
bug("Machine control socket: sk_open failed");
|
||||
|
||||
ASSERT_DIE(birdloop_inside(hcf.loop));
|
||||
|
||||
ASSERT_DIE(hcf.cur_crt);
|
||||
skl->data = hcf.cur_crt;
|
||||
|
||||
hcf.cur_crt->pid = pid;
|
||||
hcf.cur_crt->s = skl;
|
||||
if (hcf.cur_crt->ccc)
|
||||
callback_activate(&hcf.cur_crt->ccc->cb);
|
||||
hcf.cur_crt->ccc = NULL;
|
||||
hcf.cur_crt = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -303,7 +359,7 @@ crt_err(sock *s, int err UNUSED)
|
||||
static void
|
||||
container_created(callback *cb)
|
||||
{
|
||||
SKIP_BACK_DECLARE(struct container_created_callback, ccc, cb, cb);
|
||||
SKIP_BACK_DECLARE(struct container_operation_callback, ccc, cb, cb);
|
||||
|
||||
sock *s = ccc->s;
|
||||
linpool *lp = lp_new(s->pool);
|
||||
@ -363,8 +419,8 @@ hypervisor_container_request(sock *s, const char *name, const char *basedir, con
|
||||
|
||||
crt->hash = h;
|
||||
|
||||
struct container_created_callback *ccc = mb_alloc(s->pool, sizeof *ccc);
|
||||
*ccc = (struct container_created_callback) {
|
||||
struct container_operation_callback *ccc = mb_alloc(s->pool, sizeof *ccc);
|
||||
*ccc = (struct container_operation_callback) {
|
||||
.s = s,
|
||||
.data = s->data,
|
||||
};
|
||||
@ -397,6 +453,72 @@ hypervisor_container_request(sock *s, const char *name, const char *basedir, con
|
||||
birdloop_leave(hcf.loop);
|
||||
}
|
||||
|
||||
static void
|
||||
container_stopped(callback *cb)
|
||||
{
|
||||
SKIP_BACK_DECLARE(struct container_operation_callback, ccc, cb, cb);
|
||||
|
||||
sock *s = ccc->s;
|
||||
linpool *lp = lp_new(s->pool);
|
||||
struct cbor_writer *cw = cbor_init(s->tbuf, s->tbsize, lp);
|
||||
cbor_open_block_with_length(cw, 1);
|
||||
cbor_add_int(cw, -1);
|
||||
cbor_add_string(cw, "OK");
|
||||
sk_send(s, cw->pt);
|
||||
rfree(lp);
|
||||
|
||||
s->data = ccc->data;
|
||||
sk_resume_rx(s->loop, s);
|
||||
|
||||
mb_free(ccc);
|
||||
}
|
||||
|
||||
void
|
||||
hypervisor_container_shutdown(sock *s, const char *name)
|
||||
{
|
||||
birdloop_enter(hcf.loop);
|
||||
|
||||
uint h = mem_hash(name, strlen(name));
|
||||
struct container_runtime *crt = HASH_FIND(hcf.hash, CRT, name, h);
|
||||
|
||||
linpool *lp = lp_new(hcf.p);
|
||||
|
||||
if (!crt || !crt->s)
|
||||
{
|
||||
struct cbor_writer *cw = cbor_init(s->tbuf, s->tbsize, lp);
|
||||
cbor_open_block_with_length(cw, 1);
|
||||
cbor_add_int(cw, -127);
|
||||
cbor_add_string(cw, "BAD: Not found");
|
||||
|
||||
sk_send(s, cw->pt);
|
||||
rfree(lp);
|
||||
birdloop_leave(hcf.loop);
|
||||
return;
|
||||
}
|
||||
|
||||
struct cbor_writer *cw = cbor_init(crt->s->tbuf, crt->s->tbsize, lp);
|
||||
cbor_open_block_with_length(cw, 1);
|
||||
cbor_add_int(cw, 0);
|
||||
write_item(cw, 7, 22);
|
||||
|
||||
sk_send(crt->s, cw->pt);
|
||||
rfree(lp);
|
||||
|
||||
struct container_operation_callback *ccc = mb_alloc(s->pool, sizeof *ccc);
|
||||
*ccc = (struct container_operation_callback) {
|
||||
.s = s,
|
||||
.data = s->data,
|
||||
};
|
||||
callback_init(&ccc->cb, container_stopped, s->loop);
|
||||
crt->ccc = ccc;
|
||||
|
||||
s->err_paused = crt_err;
|
||||
s->data = crt;
|
||||
sk_pause_rx(s->loop, s);
|
||||
|
||||
birdloop_leave(hcf.loop);
|
||||
}
|
||||
|
||||
struct cbor_parser_context {
|
||||
linpool *lp;
|
||||
|
||||
|
47
flock/ctl.c
47
flock/ctl.c
@ -212,7 +212,14 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
|
||||
ctx->major_state = 501;
|
||||
break;
|
||||
|
||||
case 6: /* process spawner */
|
||||
case 6: /* machine shutdown request */
|
||||
if (ctx->type != 5)
|
||||
CBOR_PARSER_ERROR("Expecting mapping, got %u", ctx->type);
|
||||
|
||||
ctx->major_state = 601;
|
||||
break;
|
||||
|
||||
case 7: /* process spawner */
|
||||
CBOR_PARSER_ERROR("NOT IMPLEMENTED YET");
|
||||
break;
|
||||
|
||||
@ -285,6 +292,31 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
|
||||
ctx->target_len = ctx->value;
|
||||
break;
|
||||
|
||||
case 601: /* machine shutdown argument */
|
||||
if (ctx->type != 0)
|
||||
CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type);
|
||||
|
||||
if (ctx->value >= 1)
|
||||
CBOR_PARSER_ERROR("Command key too high, got %lu", ctx->value);
|
||||
|
||||
ctx->major_state = ctx->value + 602;
|
||||
break;
|
||||
|
||||
case 602: /* machine creation argument 0: name */
|
||||
if (ctx->type != 3)
|
||||
CBOR_PARSER_ERROR("Expected string, got %u", ctx->type);
|
||||
|
||||
if (value_is_special)
|
||||
CBOR_PARSER_ERROR("Variable length string not supported yet");
|
||||
|
||||
if (ctx->cfg.cf.name)
|
||||
CBOR_PARSER_ERROR("Duplicate argument 0 / name");
|
||||
|
||||
ASSERT_DIE(!ctx->target_buf);
|
||||
ctx->cfg.cf.name = ctx->target_buf = lp_alloc(ctx->lp, ctx->value + 1);
|
||||
ctx->target_len = ctx->value;
|
||||
break;
|
||||
|
||||
default:
|
||||
bug("invalid parser state");
|
||||
}
|
||||
@ -342,6 +374,10 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
|
||||
ctx->major_state = 501;
|
||||
break;
|
||||
|
||||
case 602:
|
||||
ctx->major_state = 601;
|
||||
break;
|
||||
|
||||
default:
|
||||
bug("Unexpected state to end a (byte)string in");
|
||||
/* Code to run at the end of a (byte)string */
|
||||
@ -395,6 +431,15 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
|
||||
ctx->major_state = 1;
|
||||
break;
|
||||
|
||||
case 601:
|
||||
if (!ctx->cfg.cf.name)
|
||||
CBOR_PARSER_ERROR("Machine name not specified");
|
||||
|
||||
hypervisor_container_shutdown(ctx->sock, ctx->cfg.cf.name);
|
||||
|
||||
ctx->major_state = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
bug("Unexpected state to end a mapping in");
|
||||
}
|
||||
|
@ -100,6 +100,11 @@ def container_start(hypervisor: str, name: str):
|
||||
}}).items():
|
||||
print(k,v)
|
||||
|
||||
@handler
|
||||
def container_stop(hypervisor: str, name: str):
|
||||
for k,v in msg(hypervisor, { 4: { 0: name, }}).items():
|
||||
print(k,v)
|
||||
|
||||
try:
|
||||
binname = sys.argv.pop(0)
|
||||
except Exception as e:
|
||||
|
@ -47,6 +47,7 @@ union flock_machine_config {
|
||||
|
||||
|
||||
void hypervisor_container_request(sock *s, const char *name, const char *basedir, const char *workdir);
|
||||
void hypervisor_container_shutdown(sock *s, const char *name);
|
||||
|
||||
extern event reboot_event, poweroff_event;
|
||||
extern event_list shutdown_event_list;
|
||||
|
Loading…
Reference in New Issue
Block a user