Add "-r rootdisk" growdisk support
This commit is contained in:
parent
a8490a757f
commit
8dfa3c843a
5 changed files with 193 additions and 21 deletions
|
@ -1,6 +1,7 @@
|
||||||
PROG= cloud-agent
|
PROG= cloud-agent
|
||||||
SRCS= http.c json.c jsmn.c log.c main.c xml.c
|
SRCS= http.c json.c jsmn.c log.c main.c xml.c
|
||||||
SRCS+= azure.c cloudinit.c opennebula.c openstack.c
|
SRCS+= azure.c cloudinit.c opennebula.c openstack.c
|
||||||
|
SRCS+= growdisk.c
|
||||||
BINDIR= /usr/local/libexec
|
BINDIR= /usr/local/libexec
|
||||||
MANDIR= /usr/local/man/man
|
MANDIR= /usr/local/man/man
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm cloud-agent
|
.Nm cloud-agent
|
||||||
.Op Fl nuv
|
.Op Fl nuv
|
||||||
|
.Op Fl r Ar rootdisk
|
||||||
.Op Fl t Ar timeout
|
.Op Fl t Ar timeout
|
||||||
.Op Fl U Ar username
|
.Op Fl U Ar username
|
||||||
.Ar interface
|
.Ar interface
|
||||||
|
@ -53,6 +54,10 @@ configuration.
|
||||||
Using
|
Using
|
||||||
.Dq root
|
.Dq root
|
||||||
is supported, but not recommended.
|
is supported, but not recommended.
|
||||||
|
.It Fl r Ar rootdisk
|
||||||
|
Automatically grow the last
|
||||||
|
.Ox
|
||||||
|
FFS partition of the root disk to use all the available space.
|
||||||
.It Fl u
|
.It Fl u
|
||||||
Deprovision and unconfigure the system.
|
Deprovision and unconfigure the system.
|
||||||
This deletes keys, passwords, and logs files without asking for permission.
|
This deletes keys, passwords, and logs files without asking for permission.
|
||||||
|
@ -64,11 +69,12 @@ Enable
|
||||||
.Nm
|
.Nm
|
||||||
in the
|
in the
|
||||||
.Xr hostname.if 5
|
.Xr hostname.if 5
|
||||||
of the VM's primary networking interface:
|
of the VM's primary networking interface and automatically the last
|
||||||
|
partition of the root disk:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
# cat /etc/hostname.hvn0
|
# cat /etc/hostname.hvn0
|
||||||
dhcp
|
dhcp
|
||||||
!/usr/local/libexec/cloud-agent "\e$if"
|
!/usr/local/libexec/cloud-agent -r sd0 "\e$if"
|
||||||
.Ed
|
.Ed
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width "/usr/local/libexec/cloud-agentX" -compact
|
.Bl -tag -width "/usr/local/libexec/cloud-agentX" -compact
|
||||||
|
|
149
agent/growdisk.c
Normal file
149
agent/growdisk.c
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Reyk Floeter <reyk@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h> /* DEV_BSIZE */
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/dkio.h>
|
||||||
|
#define DKTYPENAMES
|
||||||
|
#include <sys/disklabel.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <util.h>
|
||||||
|
#include <err.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
static uint16_t dkcksum(struct disklabel *);
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
dkcksum(struct disklabel *lp)
|
||||||
|
{
|
||||||
|
uint16_t *start, *end, sum;
|
||||||
|
start = (uint16_t *)lp;
|
||||||
|
end = (uint16_t *)&lp->d_partitions[lp->d_npartitions];
|
||||||
|
for (sum = 0; start < end;)
|
||||||
|
sum ^= *start++;
|
||||||
|
return (sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
growdisk(struct system_config *sc)
|
||||||
|
{
|
||||||
|
char c, last_part = 0, *out, *path = NULL;
|
||||||
|
int ret = -1, i, errfd, outfd;
|
||||||
|
struct partition *pp, *p = NULL;
|
||||||
|
struct disklabel lp;
|
||||||
|
int fd;
|
||||||
|
uint16_t cksum;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grow the OpenBSD MBR partition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX this is a bit ugly but easier to do */
|
||||||
|
if (shellout("e 3\n\n\n\n*\nw\nq\n", &out,
|
||||||
|
"fdisk", "-e", sc->sc_rootdisk, NULL) != 0) {
|
||||||
|
log_warnx("failed to grow OpenBSD partition");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
free(out);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grow the last partition in the disklabel
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((fd = opendev(sc->sc_rootdisk,
|
||||||
|
O_RDWR, OPENDEV_PART, NULL)) == -1) {
|
||||||
|
log_warn("failed to open %s", sc->sc_rootdisk);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(fd, DIOCGDINFO, &lp) == -1) {
|
||||||
|
log_warn("failed to get disklabel");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp.d_magic != DISKMAGIC || lp.d_magic2 != DISKMAGIC) {
|
||||||
|
log_warnx("invalid disklabel magic bytes");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cksum = lp.d_checksum;
|
||||||
|
lp.d_checksum = 0;
|
||||||
|
|
||||||
|
if (dkcksum(&lp) != cksum) {
|
||||||
|
log_warnx("invalid disklabel checksum");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp = lp.d_partitions;
|
||||||
|
for (i = 0, pp = lp.d_partitions; i < lp.d_npartitions; i++, pp++) {
|
||||||
|
if (!DL_GETPSIZE(pp))
|
||||||
|
continue;
|
||||||
|
c = 'a' + i;
|
||||||
|
if (pp->p_fstype == FS_BSDFFS) {
|
||||||
|
last_part = c;
|
||||||
|
p = pp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_part == 0) {
|
||||||
|
log_warnx("last BSD partition not found");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update OpenBSD boundaries */
|
||||||
|
DL_SETBEND(&lp, DL_GETDSIZE(&lp) - DL_GETBSTART(&lp));
|
||||||
|
|
||||||
|
/* Update the size of the last partition */
|
||||||
|
DL_SETPSIZE(p, DL_GETBEND(&lp) - DL_GETPOFFSET(p));
|
||||||
|
|
||||||
|
lp.d_checksum = dkcksum(&lp);
|
||||||
|
|
||||||
|
if (ioctl(fd, DIOCWDINFO, &lp) == -1) {
|
||||||
|
log_warn("failed to write disklabel");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grow the filesystem
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (asprintf(&path, "/dev/%s%c", sc->sc_rootdisk, last_part) == -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
errfd = disable_output(sc, STDERR_FILENO);
|
||||||
|
outfd = disable_output(sc, STDOUT_FILENO);
|
||||||
|
|
||||||
|
(void)shell("umount", "-f", path, NULL);
|
||||||
|
(void)shell("growfs", "-yq", path, NULL);
|
||||||
|
if ((ret = shell("fsck", "-y", path, NULL)) != 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
enable_output(sc, STDERR_FILENO, errfd);
|
||||||
|
enable_output(sc, STDOUT_FILENO, outfd);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
done:
|
||||||
|
free(path);
|
||||||
|
close(fd);
|
||||||
|
return (ret);
|
||||||
|
}
|
32
agent/main.c
32
agent/main.c
|
@ -43,7 +43,8 @@
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
|
|
||||||
__dead void usage(void);
|
__dead void usage(void);
|
||||||
static struct system_config *agent_init(const char *, int, int);
|
static struct system_config
|
||||||
|
*agent_init(const char *, const char *, int, int);
|
||||||
static int agent_configure(struct system_config *);
|
static int agent_configure(struct system_config *);
|
||||||
static int agent_network(struct system_config *);
|
static int agent_network(struct system_config *);
|
||||||
static void agent_free(struct system_config *);
|
static void agent_free(struct system_config *);
|
||||||
|
@ -306,7 +307,7 @@ get_word(const unsigned char *ptr, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct system_config *
|
static struct system_config *
|
||||||
agent_init(const char *ifname, int dryrun, int timeout)
|
agent_init(const char *ifname, const char *rootdisk, int dryrun, int timeout)
|
||||||
{
|
{
|
||||||
struct system_config *sc;
|
struct system_config *sc;
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
|
@ -318,6 +319,7 @@ agent_init(const char *ifname, int dryrun, int timeout)
|
||||||
sc->sc_cdrom = "/dev/cd0c";
|
sc->sc_cdrom = "/dev/cd0c";
|
||||||
sc->sc_dryrun = dryrun ? 1 : 0;
|
sc->sc_dryrun = dryrun ? 1 : 0;
|
||||||
sc->sc_timeout = agent_timeout = timeout < 1 ? -1 : timeout * 1000;
|
sc->sc_timeout = agent_timeout = timeout < 1 ? -1 : timeout * 1000;
|
||||||
|
sc->sc_rootdisk = rootdisk;
|
||||||
TAILQ_INIT(&sc->sc_pubkeys);
|
TAILQ_INIT(&sc->sc_pubkeys);
|
||||||
TAILQ_INIT(&sc->sc_netaddrs);
|
TAILQ_INIT(&sc->sc_netaddrs);
|
||||||
|
|
||||||
|
@ -1089,8 +1091,8 @@ usage(void)
|
||||||
{
|
{
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
fprintf(stderr, "usage: %s [-nuv] [-t 3] [-U puffy] interface\n",
|
fprintf(stderr, "usage: %s [-nuv] [-r rootdisk] [-t 3] [-U puffy] "
|
||||||
__progname);
|
"interface\n", __progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1130,19 +1132,19 @@ main(int argc, char *const *argv)
|
||||||
struct system_config *sc;
|
struct system_config *sc;
|
||||||
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, *rootdisk = NULL;
|
||||||
char *args, *username = NULL;
|
char *args, *username = NULL;
|
||||||
|
|
||||||
if ((args = get_args(argc, argv)) == NULL)
|
if ((args = get_args(argc, argv)) == NULL)
|
||||||
fatalx("failed to save args");
|
fatalx("failed to save args");
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "nvt:U:u")) != -1) {
|
while ((ch = getopt(argc, argv, "nr:t:U:uv")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'n':
|
case 'n':
|
||||||
dryrun = 1;
|
dryrun = 1;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'r':
|
||||||
verbose += 2;
|
rootdisk = optarg;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
timeout = strtonum(optarg, -1, 86400, &error);
|
timeout = strtonum(optarg, -1, 86400, &error);
|
||||||
|
@ -1156,6 +1158,9 @@ main(int argc, char *const *argv)
|
||||||
case 'u':
|
case 'u':
|
||||||
unconfigure = 1;
|
unconfigure = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose += 2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
@ -1176,11 +1181,18 @@ main(int argc, char *const *argv)
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
if (pledge("stdio cpath rpath wpath exec proc dns inet", NULL) == -1)
|
if (pledge(rootdisk == NULL ?
|
||||||
|
"stdio cpath rpath wpath exec proc dns inet" :
|
||||||
|
"stdio cpath rpath wpath exec proc dns inet disklabel",
|
||||||
|
NULL) == -1)
|
||||||
fatal("pledge");
|
fatal("pledge");
|
||||||
|
|
||||||
if ((sc = agent_init(argv[0], dryrun, timeout)) == NULL)
|
if ((sc = agent_init(argv[0], rootdisk, dryrun, timeout)) == NULL)
|
||||||
fatalx("agent");
|
fatalx("agent");
|
||||||
|
|
||||||
|
if (rootdisk != NULL && growdisk(sc) == -1)
|
||||||
|
fatalx("failed to grow %s", rootdisk);
|
||||||
|
|
||||||
sc->sc_args = args;
|
sc->sc_args = args;
|
||||||
if (username != NULL) {
|
if (username != NULL) {
|
||||||
free(sc->sc_username);
|
free(sc->sc_username);
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct system_config {
|
||||||
const char *sc_ovfenv;
|
const char *sc_ovfenv;
|
||||||
const char *sc_interface;
|
const char *sc_interface;
|
||||||
const char *sc_cdrom;
|
const char *sc_cdrom;
|
||||||
|
const char *sc_rootdisk;
|
||||||
int sc_mount;
|
int sc_mount;
|
||||||
|
|
||||||
struct source sc_addr;
|
struct source sc_addr;
|
||||||
|
@ -129,6 +130,9 @@ int opennebula(struct system_config *);
|
||||||
/* openstack.c */
|
/* openstack.c */
|
||||||
int openstack(struct system_config *);
|
int openstack(struct system_config *);
|
||||||
|
|
||||||
|
/* growdisk.c */
|
||||||
|
int growdisk(struct system_config *);
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
int shell(const char *, ...);
|
int shell(const char *, ...);
|
||||||
int shellout(const char *, char **, const char *, ...);
|
int shellout(const char *, char **, const char *, ...);
|
||||||
|
|
Loading…
Reference in a new issue