commit - bd2d269200403f8168de26b8229d7c30de792d3b
commit + af490b2c935de6beea6095b770c38ce7bde92a8e
blob - 00820a53c513998384af2849c1311c660ceeef6f
blob + d3405c5db2e7a48954a166f23e2cb17daa59a9bf
--- gotsys/gotsys.1
+++ gotsys/gotsys.1
.Nm
are as follows:
.Bl -tag -width Ds
-.It Cm apply Oo Fl c Ar commit Oc Oo Fl f Ar socket Oc Oo Fl r Ar repository-path Oc Oo Ar file Oc
+.It Cm apply Oo Fl c Ar commit Oc Oo Fl f Ar socket Oc Oo Fl r Ar repository-path Oc Oo Fl w Oc Oo Ar file Oc
Trigger system configuration tasks based on the
.Xr gotsys.conf 5
configuration
If not specified, the repository path
.Pa /git/gotsys.git
will be used.
+.It Fl w
+Wait until
+.Xr gotsysd 8
+is done trying to apply the configuration and report the result.
.El
.It Cm check Oo Fl q Oc Oo Fl f Ar file Oc
Read a
blob - ba69385c1f238933082336acee61d9a579768e9e
blob + 584ac4aa540ecb67f99cf1c3451ceab525de382e
--- gotsys/gotsys.c
+++ gotsys/gotsys.c
usage_apply(void)
{
fprintf(stderr, "usage: %s apply [-f socket] [-r repository] "
- "[-c commit] [filename]", getprogname());
+ "[-c commit] [-w] [filename]", getprogname());
exit(1);
}
const char *filename = GOTSYSD_SYSCONF_FILENAME;
const char *socket_path = GOTSYSD_UNIX_SOCKET;
struct got_commit_object *commit = NULL;
- int ch, ret, fd = -1, sysconf_fd = -1, gotsysd_sock = -1;
+ int ch, ret, fd = -1, sysconf_fd = -1, gotsysd_sock = -1, wait = 0;
FILE *sysconf_file = NULL;
struct got_object_id *commit_id = NULL;
struct gotsysd_imsg_cmd_sysconf sysconf_cmd;
memset(&ibuf, 0, sizeof(ibuf));
- while ((ch = getopt(argc, argv, "f:c:r:")) != -1) {
+ while ((ch = getopt(argc, argv, "f:c:r:w")) != -1) {
switch (ch) {
case 'c':
commit_id_str = optarg;
}
got_path_strip_trailing_slashes(repo_path);
break;
+ case 'w':
+ wait = 1;
+ break;
default:
usage_apply();
/* NOTREACHED */
goto done;
}
#endif
- n = imsgbuf_read(&ibuf);
- if (n == -1) {
- err = got_error_from_errno("imsgbuf_read");
- goto done;
- }
- if (n == 0) {
- err = got_error(GOT_ERR_EOF);
- goto done;
- }
+ do {
+ n = imsgbuf_read(&ibuf);
+ if (n == -1) {
+ err = got_error_from_errno("imsgbuf_read");
+ goto done;
+ }
+ if (n == 0) {
+ err = got_error(GOT_ERR_EOF);
+ goto done;
+ }
- n = imsg_get(&ibuf, &imsg);
- if (n == -1) {
- err = got_error_from_errno("imsg_get");
- goto done;
- }
- if (n == 0) {
- err = got_error(GOT_ERR_PRIVSEP_READ);
- goto done;
- }
+ n = imsg_get(&ibuf, &imsg);
+ if (n == -1) {
+ err = got_error_from_errno("imsg_get");
+ goto done;
+ }
+ if (n == 0) {
+ err = got_error(GOT_ERR_PRIVSEP_READ);
+ goto done;
+ }
- switch (imsg.hdr.type) {
- case GOTSYSD_IMSG_ERROR:
- err = recv_error(&imsg);
- break;
- case GOTSYSD_IMSG_SYSCONF_STARTED:
- break;
- default:
- err = got_error(GOT_ERR_PRIVSEP_MSG);
- break;
- }
+ switch (imsg.hdr.type) {
+ case GOTSYSD_IMSG_ERROR:
+ err = recv_error(&imsg);
+ break;
+ case GOTSYSD_IMSG_SYSCONF_STARTED:
+ break;
+ case GOTSYSD_IMSG_SYSCONF_SUCCESS:
+ printf("sysconf success\n");
+ wait = 0;
+ break;
+ case GOTSYSD_IMSG_SYSCONF_FAILURE:
+ err = got_error_fmt(GOT_ERR_ON_SERVER_SIDE,
+ "sysconf failure");
+ break;
+ default:
+ err = got_error(GOT_ERR_PRIVSEP_MSG);
+ break;
+ }
- imsg_free(&imsg);
+ imsg_free(&imsg);
+ } while (err == NULL && wait);
done:
imsgbuf_clear(&ibuf);
free(repo_path);
blob - e82a68f6c011d5ed50ce21ff9ea6ea50c3beb9e6
blob + 8628a270bcaa8929d1e004abd3806a8d7a407f26
--- gotsysd/gotsysd.c
+++ gotsysd/gotsysd.c
int pipe[2];
struct gotsysd_imsgev iev;
struct event tmo;
+ uint32_t client_id;
TAILQ_ENTRY(gotsysd_child_proc) entry;
};
enum gotsysd_client_state {
GOTSYSD_CLIENT_STATE_NEW = -1,
GOTSYSD_CLIENT_STATE_ACCESS_GRANTED = 1,
+ GOTSYSD_CLIENT_STATE_SYSCONF_STARTED,
};
struct gotsysd_client {
}
static void
+client_sysconf_done(uint32_t client_id, int exit_status)
+{
+ struct gotsysd_client *client;
+ int imsg_code;
+
+ client = find_client(client_id);
+ if (client == NULL)
+ return;
+
+ if (client->state != GOTSYSD_CLIENT_STATE_SYSCONF_STARTED)
+ return;
+
+ if (exit_status == 0)
+ imsg_code = GOTSYSD_IMSG_SYSCONF_SUCCESS;
+ else
+ imsg_code = GOTSYSD_IMSG_SYSCONF_FAILURE;
+
+ if (gotsysd_imsg_compose_event(&client->iev, imsg_code,
+ GOTSYSD_PROC_GOTSYSD, -1, NULL, 0) == -1)
+ log_warn("imsg compose %d", imsg_code);
+}
+
+static void
disconnect(struct gotsysd_client *client)
{
struct gotsysd_imsg_disconnect idisconnect;
}
static const struct got_error *
-start_sysconf_child(int sysconf_fd, struct got_object_id *commit_id)
+start_sysconf_child(int sysconf_fd, struct got_object_id *commit_id,
+ uint32_t client_id)
{
const struct got_error *err = NULL;
struct gotsysd_child_proc *proc;
evtimer_set(&proc->tmo, kill_proc_timeout, proc);
proc->type = GOTSYSD_PROC_SYSCONF;
+ proc->client_id = client_id;
log_debug("running system configuration tasks for gotsys.conf from "
"gotsys.git commit %s", commit_id_str);
STAILQ_REMOVE_HEAD(&gotsysd.sysconf_pending, entry);
- err = start_sysconf_child(cmd->fd, &cmd->commit_id);
+ err = start_sysconf_child(cmd->fd, &cmd->commit_id, cmd->client_id);
if (err) {
log_warn("could not start sysconf child process: %s",
err->msg);
return got_error(GOT_ERR_PRIVSEP_MSG);
if (gotsysd.sysconf_proc == NULL) {
- err = start_sysconf_child(sysconf_fd, &sysconf_cmd.commit_id);
+ err = start_sysconf_child(sysconf_fd, &sysconf_cmd.commit_id,
+ client->id);
if (err) {
close(sysconf_fd);
return err;
cmd->fd = sysconf_fd;
memcpy(&cmd->commit_id, &sysconf_cmd.commit_id,
sizeof(cmd->commit_id));
+ cmd->client_id = client->id;
STAILQ_INSERT_TAIL(&gotsysd.sysconf_pending, cmd, entry);
evtimer_add(&gotsysd.sysconf_tmo, &tv);
}
GOTSYSD_IMSG_SYSCONF_STARTED,
GOTSYSD_PROC_GOTSYSD, -1, NULL, 0) == -1) {
err = got_error_from_errno("imsg compose SYSCONF_STARTED");
- }
+ } else
+ client->state = GOTSYSD_CLIENT_STATE_SYSCONF_STARTED;
return NULL;
}
" signal %d", pid, WTERMSIG(status));
}
+ if (proc->type == GOTSYSD_PROC_SYSCONF) {
+ client_sysconf_done(proc->client_id,
+ WEXITSTATUS(status));
+ }
+
if (proc == gotsysd.sysconf_proc) {
gotsysd.sysconf_proc = NULL;
if (gotsysd.sysconf_fd != -1) {
blob - 6d37103e663e08e88c395b8e01b66320b5c4bc2f
blob + f72e5f0ff065e99ca9f7e168dbd69ae18ba02940
--- gotsysd/gotsysd.h
+++ gotsysd/gotsysd.h
STAILQ_ENTRY(gotsysd_pending_sysconf_cmd) entry;
int fd;
struct got_object_id commit_id;
+ uint32_t client_id;
};
STAILQ_HEAD(gotsysd_pending_sysconf_cmd_list,
gotsysd_pending_sysconf_cmd);
GOTSYSD_IMSG_INFO,
GOTSYSD_IMSG_CMD_SYSCONF,
GOTSYSD_IMSG_SYSCONF_STARTED,
+ GOTSYSD_IMSG_SYSCONF_SUCCESS,
+ GOTSYSD_IMSG_SYSCONF_FAILURE,
/* Internal sysconf messages. */
GOTSYSD_IMSG_SYSCONF_READY,
GOTSYSD_IMSG_SYSCONF_FD,
- GOTSYSD_IMSG_SYSCONF_SUCCESS,
/* Child processes management. */
GOTSYSD_IMSG_CONNECT_PROC,
blob - 870e76a6fec7cb1fd96cdd2f47457c6ab86988d8
blob + d9cb7ba02a04c7708ffd8b434a1ff6d2b567e681
--- include/got_error.h
+++ include/got_error.h
#define GOT_ERR_GROUP_EXISTS 179
#define GOT_ERR_AUTHORIZED_KEY 180
#define GOT_ERR_CONNECTION_LIMIT 190
+#define GOT_ERR_ON_SERVER_SIDE 191
struct got_error {
int code;
blob - 922cdad6e22538c24d67ad78bf152e9edef33f49
blob + 8140daf14f5dd531f79f071964fa9ecc20349c17
--- lib/error.c
+++ lib/error.c
{ GOT_ERR_GROUP_EXISTS, "group already exists" },
{ GOT_ERR_AUTHORIZED_KEY, "no authorized key found" },
{ GOT_ERR_CONNECTION_LIMIT, "connection limit exceeded" },
+ { GOT_ERR_ON_SERVER_SIDE, "see server-side logs for error details" },
};
static struct got_custom_error {