nbos

nbos

https://git.tonybtw.com/nbos.git git://git.tonybtw.com/nbos.git
3,483 bytes raw
1
#define _GNU_SOURCE
2
#include <stdint.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
7
#include "../include/nbos.h"
8
#include "activate.h"
9
#include "arena.h"
10
#include "error.h"
11
#include "realize.h"
12
#include "resolve.h"
13
#include "validate.h"
14
15
extern const system_cfg CFG;
16
17
static uint32_t next_generation_number(void) {
18
    return 1;
19
}
20
21
static int cmd_switch(void) {
22
    if (CFG.schema_version != NBOS_SCHEMA_VERSION) {
23
        fprintf(stderr,
24
                "nb: config schema version %u does not match nb %u\n",
25
                CFG.schema_version, NBOS_SCHEMA_VERSION);
26
        return 1;
27
    }
28
29
    arena *a = arena_create(1 << 20);
30
    if (a == nullptr) {
31
        fprintf(stderr, "nb: arena alloc failed\n");
32
        return 1;
33
    }
34
35
    fprintf(stderr, "nb: validating config\n");
36
    if (!validate(&CFG)) {
37
        arena_destroy(a);
38
        return 1;
39
    }
40
41
    fprintf(stderr, "nb: resolving %zu packages\n", CFG.pkgs.len);
42
    resolved_list resolved = {0};
43
    resolve_error rerr = resolve(a, &CFG, &resolved);
44
    if (rerr.kind != RESOLVE_OK) {
45
        resolve_error_print(&rerr);
46
        arena_destroy(a);
47
        return 1;
48
    }
49
50
    fprintf(stderr, "nb: realizing\n");
51
    realize_error realerr = realize(a, &CFG.pkgs, &resolved);
52
    if (realerr.kind != REALIZE_OK) {
53
        realize_error_print(&realerr);
54
        arena_destroy(a);
55
        return 1;
56
    }
57
58
    uint32_t gen = next_generation_number();
59
    fprintf(stderr, "nb: activating generation %u\n", gen);
60
    int aerr = activate(a, &CFG, &resolved, gen);
61
    if (aerr != 0) {
62
        fprintf(stderr, "nb: activation failed: %s\n", strerror(aerr));
63
        arena_destroy(a);
64
        return 1;
65
    }
66
67
    fprintf(stderr, "nb: switch complete (generation %u)\n", gen);
68
    arena_destroy(a);
69
    return 0;
70
}
71
72
static int cmd_validate(void) {
73
    if (CFG.schema_version != NBOS_SCHEMA_VERSION) {
74
        fprintf(stderr, "nb: schema version mismatch\n");
75
        return 1;
76
    }
77
    if (!validate(&CFG)) return 1;
78
79
    arena *a = arena_create(1 << 20);
80
    if (a == nullptr) return 1;
81
82
    resolved_list resolved = {0};
83
    resolve_error rerr = resolve(a, &CFG, &resolved);
84
    if (rerr.kind != RESOLVE_OK) {
85
        resolve_error_print(&rerr);
86
        arena_destroy(a);
87
        return 1;
88
    }
89
90
    fprintf(stderr, "nb: config is valid (%zu pkgs, %zu services, %zu users)\n",
91
            CFG.pkgs.len, CFG.services.len, CFG.users.len);
92
    arena_destroy(a);
93
    return 0;
94
}
95
96
static int cmd_rollback(void) {
97
    arena *a = arena_create(1 << 16);
98
    if (a == nullptr) return 1;
99
    int rc = activate_rollback(a);
100
    arena_destroy(a);
101
    return rc == 0 ? 0 : 1;
102
}
103
104
static void usage(void) {
105
    fprintf(stderr,
106
        "usage: nb <command>\n"
107
        "\n"
108
        "commands:\n"
109
        "  switch     build and activate the current config\n"
110
        "  validate   check the current config without activating\n"
111
        "  rollback   activate the previous generation\n"
112
        "  diff       diff two generations (default: previous vs current)\n"
113
        "  gc         remove store paths not referenced by any generation\n"
114
    );
115
}
116
117
int main(int argc, char **argv) {
118
    if (argc < 2) { usage(); return 1; }
119
120
    const char *cmd = argv[1];
121
122
    if (strcmp(cmd, "switch") == 0)   return cmd_switch();
123
    if (strcmp(cmd, "validate") == 0) return cmd_validate();
124
    if (strcmp(cmd, "rollback") == 0) return cmd_rollback();
125
126
    fprintf(stderr, "nb: unknown command '%s'\n", cmd);
127
    usage();
128
    return 1;
129
}