Write network configuration files
This commit is contained in:
parent
d9899d488a
commit
333f7ac6d7
3 changed files with 105 additions and 13 deletions
97
agent/main.c
97
agent/main.c
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue