Write network configuration files

This commit is contained in:
reykfloeter 2018-08-14 09:55:17 +02:00
parent d9899d488a
commit 333f7ac6d7
3 changed files with 105 additions and 13 deletions

View file

@ -362,6 +362,7 @@ agent_free(struct system_config *sc)
log_debug("%s: unmounted %s", __func__, sc->sc_cdrom); log_debug("%s: unmounted %s", __func__, sc->sc_cdrom);
} }
free(sc->sc_args);
free(sc->sc_hostname); free(sc->sc_hostname);
free(sc->sc_username); free(sc->sc_username);
free(sc->sc_password); free(sc->sc_password);
@ -445,6 +446,9 @@ agent_getnetaddr(struct system_config *sc, struct net_addr *net)
continue; continue;
if (na->net_ifunit != net->net_ifunit) if (na->net_ifunit != net->net_ifunit)
continue; continue;
if (na->net_type == NET_DNS_DOMAIN &&
strcasecmp(na->net_value, net->net_value) != 0)
continue;
if (net->net_addr.ss_family != AF_UNSPEC) { if (net->net_addr.ss_family != AF_UNSPEC) {
if (na->net_addr.ss_family != if (na->net_addr.ss_family !=
net->net_addr.ss_family) net->net_addr.ss_family)
@ -476,6 +480,13 @@ agent_addnetaddr(struct system_config *sc, unsigned int unit,
net->net_type = type; net->net_type = type;
switch (type) { switch (type) {
case NET_DNS_DOMAIN:
if (strlen(value) >= NI_MAXHOST) {
log_debug("%s: if%u domain %s", __func__, unit, value);
free(net);
return (-1);
}
break;
case NET_MAC: case NET_MAC:
if (ether_aton(value) == NULL) { if (ether_aton(value) == NULL) {
log_debug("%s: if%u mac %s", __func__, unit, value); log_debug("%s: if%u mac %s", __func__, unit, value);
@ -516,17 +527,18 @@ agent_addnetaddr(struct system_config *sc, unsigned int unit,
net->net_addr.ss_family = res->ai_family; net->net_addr.ss_family = res->ai_family;
} }
/* Address already exists, ignore new entry */
if ((na = agent_getnetaddr(sc, net)) != NULL) {
free(net);
return (0);
}
if ((net->net_value = strdup(value)) == NULL) { if ((net->net_value = strdup(value)) == NULL) {
free(net); free(net);
return (-1); return (-1);
} }
/* Address already exists, ignore new entry */
if ((na = agent_getnetaddr(sc, net)) != NULL) {
free(net->net_value);
free(net);
return (0);
}
TAILQ_INSERT_TAIL(&sc->sc_netaddrs, net, net_entry); TAILQ_INSERT_TAIL(&sc->sc_netaddrs, net, net_entry);
return (0); return (0);
@ -794,6 +806,10 @@ agent_network(struct system_config *sc)
struct net_addr *net; struct net_addr *net;
char ift[16], ifname[16], line[1024], path[PATH_MAX]; char ift[16], ifname[16], line[1024], path[PATH_MAX];
const char *family; const char *family;
char domain[(NI_MAXHOST + 1) * 6 + 8]; /* up to 6 domains */
int has_domain = 0;
char ifidx[UINT16_MAX];
const char *comment = "# Generated by cloud-agent";
if (!sc->sc_network) if (!sc->sc_network)
return (0); return (0);
@ -802,21 +818,36 @@ agent_network(struct system_config *sc)
return (-1); return (-1);
ift[strcspn(ift, "0123456789")] = '\0'; ift[strcspn(ift, "0123456789")] = '\0';
memset(ifidx, 0, sizeof(ifidx));
snprintf(domain, sizeof(domain), "search ");
fileout(comment, "w", "/etc/mygate");
fileout(comment, "w", "/etc/resolv.conf");
TAILQ_FOREACH(net, &sc->sc_netaddrs, net_entry) { TAILQ_FOREACH(net, &sc->sc_netaddrs, net_entry) {
snprintf(ifname, sizeof(ifname), "%s%u", ift, net->net_ifunit); snprintf(ifname, sizeof(ifname), "%s%u", ift, net->net_ifunit);
switch (net->net_type) { switch (net->net_type) {
case NET_IP: case NET_IP:
family = net->net_addr.ss_family == AF_INET ? family = net->net_addr.ss_family == AF_INET ?
"inet" : "inet6"; "inet" : "inet6";
/* XXX prefix */ /* XXX prefix or mask */
/* hostname.if startup configuration */ /* hostname.if startup configuration */
snprintf(line, sizeof(line), "%s alias %s",
family, net->net_value);
snprintf(path, sizeof(path), snprintf(path, sizeof(path),
"/etc/hostname.%s", ifname); "/etc/hostname.%s", ifname);
if (!ifidx[net->net_ifunit])
fileout(comment, "w", path);
snprintf(line, sizeof(line), "%s alias %s",
family, net->net_value);
fileout(line, "a", path); fileout(line, "a", path);
if (!ifidx[net->net_ifunit]++ &&
net->net_ifunit == 0) {
snprintf(line, sizeof(line),
"!%s", sc->sc_args);
fileout(line, "a", path);
}
/* runtime configuration */ /* runtime configuration */
(void)shell("ifconfig", ifname, family, (void)shell("ifconfig", ifname, family,
"alias", net->net_value, NULL); "alias", net->net_value, NULL);
@ -829,11 +860,24 @@ agent_network(struct system_config *sc)
net->net_value); net->net_value);
fileout(line, "a", "/etc/resolv.conf"); fileout(line, "a", "/etc/resolv.conf");
break; break;
case NET_DNS_DOMAIN:
if (!has_domain++) {
/* use the first search domain as our own */
snprintf(line, sizeof(line), "domain %s",
net->net_value);
fileout(line, "a", "/etc/resolv.conf");
} else
(void)strlcat(domain, " ", sizeof(domain));
(void)strlcat(domain, net->net_value, sizeof(domain));
break;
default: default:
break; break;
} }
} }
if (has_domain)
fileout(domain, "a", "/etc/resolv.conf");
return (0); return (0);
} }
@ -1049,6 +1093,36 @@ usage(void)
exit(1); exit(1);
} }
static char *
get_args(int argc, char *const *argv)
{
char *args, path[PATH_MAX];
size_t argslen = 0;
int i;
/* Store args in a string */
for (i = 0; i < argc; i++) {
if (i == 0) {
realpath(argv[0], path);
argslen += strlen(path) + 1;
} else {
argslen += strlen(argv[i]) + 1;
}
}
if ((args = calloc(1, argslen + 1)) == NULL)
return (NULL);
for (i = 0; i < argc; i++) {
if (i == 0)
strlcat(args, path, argslen);
else {
strlcat(args, " ", argslen);
strlcat(args, argv[i], argslen);
}
}
return (args);
}
int int
main(int argc, char *const *argv) main(int argc, char *const *argv)
{ {
@ -1056,6 +1130,10 @@ main(int argc, char *const *argv)
int verbose = 0, dryrun = 0, unconfigure = 0; int verbose = 0, dryrun = 0, unconfigure = 0;
int ch, ret, timeout = CONNECT_TIMEOUT; int ch, ret, timeout = CONNECT_TIMEOUT;
const char *error = NULL; const char *error = NULL;
char *args;
if ((args = get_args(argc, argv)) == NULL)
fatalx("failed to save args");
while ((ch = getopt(argc, argv, "nvt:u")) != -1) { while ((ch = getopt(argc, argv, "nvt:u")) != -1) {
switch (ch) { switch (ch) {
@ -1098,6 +1176,7 @@ main(int argc, char *const *argv)
if ((sc = agent_init(argv[0], dryrun, timeout)) == NULL) if ((sc = agent_init(argv[0], dryrun, timeout)) == NULL)
fatalx("agent"); fatalx("agent");
sc->sc_args = args;
/* /*
* XXX Detect cloud with help from hostctl and sysctl * XXX Detect cloud with help from hostctl and sysctl

View file

@ -51,12 +51,13 @@ enum net_type {
NET_MTU, NET_MTU,
NET_GATEWAY, NET_GATEWAY,
NET_DNS, NET_DNS,
NET_DNS_DOMAIN,
NET_MAX NET_MAX
}; };
struct net_addr { struct net_addr {
enum net_type net_type; enum net_type net_type;
unsigned int net_ifunit; unsigned short net_ifunit;
char *net_value; char *net_value;
struct sockaddr_storage net_addr; struct sockaddr_storage net_addr;
unsigned int net_num; unsigned int net_num;
@ -67,6 +68,7 @@ TAILQ_HEAD(net_addrs, net_addr);
struct system_config { struct system_config {
const char *sc_stack; const char *sc_stack;
char *sc_args;
char *sc_hostname; char *sc_hostname;
char *sc_username; char *sc_username;

View file

@ -37,7 +37,7 @@ opennebula(struct system_config *sc)
char *hname = NULL; char *hname = NULL;
size_t len, lineno = 0, i; size_t len, lineno = 0, i;
int ret = -1; int ret = -1;
unsigned int unit; unsigned short unit;
/* Return silently without error */ /* Return silently without error */
if ((fp = fopen("/mnt/context.sh", "r")) == NULL) if ((fp = fopen("/mnt/context.sh", "r")) == NULL)
@ -99,7 +99,7 @@ opennebula(struct system_config *sc)
goto done; goto done;
} }
p[strcspn(p, "_")] = '\0'; p[strcspn(p, "_")] = '\0';
unit = strtonum(p, 0, UINT32_MAX, &errstr); unit = strtonum(p, 0, UINT16_MAX, &errstr);
free(p); free(p);
if (errstr != NULL) { if (errstr != NULL) {
log_debug("%s: %s", __func__, k); log_debug("%s: %s", __func__, k);
@ -118,6 +118,14 @@ opennebula(struct system_config *sc)
v, AF_UNSPEC, NET_DNS)) != 0) v, AF_UNSPEC, NET_DNS)) != 0)
break; break;
} }
} else if (strcasecmp("SEARCH_DOMAIN", k) == 0) {
for (p = v; *p != '\0'; v = p) {
p = v + strcspn(v, " \t");
*p++ = '\0';
if ((ret = agent_addnetaddr(sc, 0,
v, AF_UNSPEC, NET_DNS_DOMAIN)) != 0)
break;
}
} else if (strcasecmp("IP", k) == 0) { } else if (strcasecmp("IP", k) == 0) {
ret = agent_addnetaddr(sc, unit, ret = agent_addnetaddr(sc, unit,
v, AF_INET, NET_IP); v, AF_INET, NET_IP);
@ -166,9 +174,12 @@ opennebula(struct system_config *sc)
__func__, k); __func__, k);
goto done; goto done;
} }
} else if (strcasecmp("HOSTNAME", k) == 0) {
if ((hname = strdup(v)) == NULL)
log_warnx("failed to set hostname");
} else if (strcasecmp("SSH_PUBLIC_KEY", k) == 0) { } else if (strcasecmp("SSH_PUBLIC_KEY", k) == 0) {
if (agent_addpubkey(sc, v, NULL) != 0) if (agent_addpubkey(sc, v, NULL) != 0)
log_warnx("failed to ssh pubkey"); log_warnx("failed to set ssh pubkey");
} }
free(line); free(line);