]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Flock: Machine adding code in parser
authorMaria Matejka <mq@ucw.cz>
Sat, 14 Sep 2024 20:34:09 +0000 (22:34 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 18:07:35 +0000 (19:07 +0100)
flock/Makefile
flock/container.c [new file with mode: 0644]
flock/ctl.c
flock/flock.h
flock/hypervisor.c

index c873e169e4412a125a15bc365b4b89cda27481a0..a108abbb8032e86ab3cd7109ffad7af13c802586 100644 (file)
@@ -1,4 +1,4 @@
-src := ctl.c flock.c hypervisor.c
+src := container.c ctl.c flock.c hypervisor.c
 obj := $(src-o-files)
 
 flock=$(exedir)/flock-sim
diff --git a/flock/container.c b/flock/container.c
new file mode 100644 (file)
index 0000000..f062095
--- /dev/null
@@ -0,0 +1,22 @@
+#include "lib/birdlib.h"
+#include "lib/cbor.h"
+#include "lib/io-loop.h"
+
+#include "flock/flock.h"
+
+#include <stdlib.h>
+
+void
+container_start(struct birdsock *s, struct flock_machine_container_config *cfg)
+{
+  log(L_INFO "Requested to start a container, name %s, base %s, work %s",
+      cfg->cf.name, cfg->basedir, cfg->workdir);
+
+  struct 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);
+}
index e2dc8f51ed9b1c69c69f991c0ae70c36cc38ca7b..0291e5c1f1d43287f277c15366b8f9a9398a8238 100644 (file)
@@ -15,7 +15,8 @@
  *   - 0 with NULL (7-22) = shutdown the hypervisor
  *   - 1 with NULL = open a telnet listener
  *   - 2 with NULL = close the telnet listener (if not used)
- *   - 3 with array of strings = run the given command inside the hypervisor
+ *   - 3 with one string = create a machine of this name
+ *   - 4 with array of strings = run the given command inside the hypervisor
  */
 
 struct cbor_parser_context {
@@ -45,6 +46,9 @@ struct cbor_parser_context {
 #define LOCAL_STACK_MAX_DEPTH 3
   u64 stack_countdown[LOCAL_STACK_MAX_DEPTH];
   uint stack_pos;
+
+  /* Specific */
+  union flock_machine_config cfg;
 };
 
 #define CBOR_PARSER_ERROR(...) do {            \
@@ -158,7 +162,7 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
            if (ctx->type != 0)
              CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type);
 
-           if (ctx->value >= 4)
+           if (ctx->value >= 5)
              CBOR_PARSER_ERROR("Command key too high, got %lu", ctx->value);
 
            ctx->major_state = ctx->value + 2;
@@ -201,10 +205,86 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
            ctx->major_state = 1;
            break;
 
-         case 5: /* process spawner */
+         case 5: /* machine creation request */
+           if (ctx->type != 5)
+             CBOR_PARSER_ERROR("Expected mapping, got %u", ctx->type);
+
+           ctx->major_state = 501;
+           break;
+
+         case 6: /* process spawner */
            CBOR_PARSER_ERROR("NOT IMPLEMENTED YET");
            break;
 
+         case 501: /* machine creation argument */
+           if (ctx->type != 0)
+             CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type);
+
+           if (ctx->value >= 5)
+             CBOR_PARSER_ERROR("Command key too high, got %lu", ctx->value);
+
+           ctx->major_state = ctx->value + 502;
+           break;
+
+         case 502: /* 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;
+
+         case 503: /* machine creation argument 1: type */
+           if (ctx->type != 0)
+             CBOR_PARSER_ERROR("Expected integer, got %u", ctx->type);
+
+           if (ctx->cfg.cf.type)
+             CBOR_PARSER_ERROR("Duplicate argument 1 / type, already have %d", ctx->cfg.cf.type);
+
+           if ((ctx->value < 1) && (ctx->value > 1) )
+             CBOR_PARSER_ERROR("Unexpected type, got %lu", ctx->value);
+
+           ctx->cfg.cf.type = ctx->value;
+           ctx->major_state = 501;
+           break;
+
+         case 504: /* machine creation argument 2: workdir */
+           if (ctx->type != 2)
+             CBOR_PARSER_ERROR("Expected bytestring, got %u", ctx->type);
+
+           if (value_is_special)
+             CBOR_PARSER_ERROR("Variable length string not supported yet");
+
+           if (ctx->cfg.container.workdir)
+             CBOR_PARSER_ERROR("Duplicate argument 2 / workdir");
+
+           ASSERT_DIE(!ctx->target_buf);
+           ctx->cfg.container.workdir = ctx->target_buf = lp_alloc(ctx->lp, ctx->value + 1);
+           ctx->target_len = ctx->value;
+           break;
+
+         case 505: /* machine creation argument 3: basedir */
+           if (ctx->type != 2)
+             CBOR_PARSER_ERROR("Expected bytestring, got %u", ctx->type);
+
+           if (value_is_special)
+             CBOR_PARSER_ERROR("Variable length string not supported yet");
+
+           if (ctx->cfg.container.basedir)
+             CBOR_PARSER_ERROR("Duplicate argument 3 / basedir");
+
+           ASSERT_DIE(!ctx->target_buf);
+           ctx->cfg.container.basedir = ctx->target_buf = lp_alloc(ctx->lp, ctx->value + 1);
+           ctx->target_len = ctx->value;
+           break;
+
          default:
            bug("invalid parser state");
        }
@@ -256,11 +336,20 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
            /* Actually not this one */
            CBOR_PARSER_ERROR("NOT IMPLEMENTED YET");
 
+         case 502:
+         case 504:
+         case 505:
+           ctx->major_state = 501;
+           break;
+
          default:
            bug("Unexpected state to end a (byte)string in");
          /* Code to run at the end of a (byte)string */
        }
 
+       ctx->target_buf = NULL;
+       ctx->partial_state = CPE_TYPE;
+
        exit_stack = !--ctx->stack_countdown[ctx->stack_pos];
     }
 
@@ -284,6 +373,23 @@ hcs_parse(struct cbor_parser_context *ctx, const byte *buf, s64 size)
          ctx->major_state = 1;
          break;
 
+       case 501:
+         if (!ctx->cfg.cf.type)
+           CBOR_PARSER_ERROR("Machine type not specified");
+
+         if (!ctx->cfg.cf.name)
+           CBOR_PARSER_ERROR("Machine name not specified");
+
+         if (!ctx->cfg.container.workdir)
+           CBOR_PARSER_ERROR("Machine workdir not specified");
+
+         if (!ctx->cfg.container.basedir)
+           CBOR_PARSER_ERROR("Machine basedir not specified");
+
+         container_start(ctx->sock, &ctx->cfg.container);
+         ctx->major_state = 1;
+         break;
+
        default:
          bug("Unexpected state to end a mapping in");
       }
index 076d71410b3faa05373351654887fa56f3335669..2263797520afb4298008f4485ada75f22489e06f 100644 (file)
@@ -27,6 +27,23 @@ bool hcs_complete(struct cbor_parser_context *ctx);
 
 void hexp_get_telnet(sock *, const char *name);
 
+union flock_machine_config {
+  struct flock_machine_common_config {
+    const char *name;
+    enum {
+      FLOCK_MACHINE_NONE = 0,
+      FLOCK_MACHINE_CONTAINER = 1,
+    } type;
+  } cf;
+  struct flock_machine_container_config {
+    struct flock_machine_common_config cf;
+    const char *workdir;
+    const char *basedir;
+  } container;
+};
+
+void container_start(sock *, struct flock_machine_container_config *);
+
 extern event reboot_event, poweroff_event;
 extern event_list shutdown_event_list;
 
index 9ec1d8600fab0f948a274983fca289dbd849f907..d69959ccbb0698b234985c73e3c27fb982781686 100644 (file)
@@ -108,7 +108,6 @@ hypervisor_control_socket(void)
   s->rbsize = 1024;
   s->tbsize = 1024;
 
-  unlink(flock_config.control_socket_path);
   if (sk_open_unix(s, loop, flock_config.control_socket_path) < 0)
     die("Can't create control socket %s: %m", flock_config.control_socket_path);