diff --git a/include/create.h b/include/create.h index 8f88c58..ba0a00f 100644 --- a/include/create.h +++ b/include/create.h @@ -23,5 +23,7 @@ struct mod_action; int vps_create(vps_handler *h, envid_t veid, vps_param *vps_p, vps_param *cmd_p, struct mod_action *action); +int vps_reinstall(vps_handler *h, envid_t veid, vps_param *vps_p, vps_param *cmd_p, + struct mod_action *action); #endif diff --git a/include/vzctl.h b/include/vzctl.h index 2c3d67c..344cea1 100644 --- a/include/vzctl.h +++ b/include/vzctl.h @@ -40,6 +40,7 @@ typedef enum { ACTION_QUOTAOFF, ACTION_QUOTAINIT, ACTION_CONSOLE, + ACTION_REINSTALL, #ifdef HAVE_PLOOP ACTION_CONVERT, ACTION_SNAPSHOT_CREATE, diff --git a/src/lib/create.c b/src/lib/create.c index c5e54f9..eb8ebd4 100644 --- a/src/lib/create.c +++ b/src/lib/create.c @@ -28,6 +28,7 @@ #include #include +#include "env.h" #include "list.h" #include "logger.h" #include "vzconfig.h" @@ -302,6 +303,78 @@ static void cleanup_destroy_file(void *data) unlink(data); } +// Reinstall VE +int vps_reinstall(vps_handler *h, envid_t veid, vps_param *vps_p, vps_param *cmd_p, struct mod_action *action) { + int ret = 0; + + tmpl_param *tmpl_from_param = &vps_p->res.tmpl; + char dst[STR_SIZE]; + + get_vps_conf_path(veid, dst, sizeof(dst)); + + if (check_var(vps_p->res.fs.private, "VE_PRIVATE is not set")) { + return VZ_VE_PRIVATE_NOTSET; + } + + if (check_var(vps_p->res.fs.root, "VE_ROOT is not set")) { + return VZ_VE_ROOT_NOTSET; + } + + if (vps_is_run(h, veid)) { + logger(0, 0, "Container is currently running. Stop it first."); + return VZ_VE_RUNNING; + } + + if (vps_is_mounted(vps_p->res.fs.root, vps_p->res.fs.private) == 1) { + logger(0, 0, "Container is currently mounted (umount first)"); + return VZ_FS_MOUNTED; + } + + if (cmd_p->res.tmpl.ostmpl == NULL) { + // If we have't any params on command line we use ostemplate from CT + if (tmpl_from_param->ostmpl == NULL) { + logger(0, 0, "Can't get ostemplate from container"); + return VZ_VE_TMPL_NOTSET; + } + + // use tmpl_from_param->ostmpl + } else { + tmpl_from_param->ostmpl = strdup(cmd_p->res.tmpl.ostmpl); + } + + logger(0, 0, "Start container reinstall to os: %s", tmpl_from_param->ostmpl); + + if ((ret = vps_destroy_dir(veid, vps_p->res.fs.private))) { + logger(-1, errno, "Can't remove private folder"); + return 200; + } + + cpt_param* cpt = &vps_p->res.cpt; + if (destroy_dump(veid, cpt != NULL ? cpt->dumpdir : NULL) < 0) { + logger(-1, errno, "Warning: failed to remove dump file"); + return 201; + } + + if (rmdir(vps_p->res.fs.root) < 0) { + logger(-1, errno, "Warning: failed to remove %s", vps_p->res.fs.root); + return 202; + } + + // TODO: this function is so unify and will be fine to get external function for checking and downloading templates + ret = fs_create(veid, h, vps_p); + if (ret) { + logger(-1, errno, "Can't create fs"); + return 203; + } + + if ((ret = vps_save_config(veid, dst, cmd_p, vps_p, action))) { + logger(-1, errno, "Can't create vps config"); + return 204; + } + + return 0; +} + int vps_create(vps_handler *h, envid_t veid, vps_param *vps_p, vps_param *cmd_p, struct mod_action *action) { diff --git a/src/vzctl-actions.c b/src/vzctl-actions.c index e538857..412780c 100644 --- a/src/vzctl-actions.c +++ b/src/vzctl-actions.c @@ -227,6 +227,24 @@ static int parse_opt(envid_t veid, int argc, char *argv[], struct option *opt, return 0; } +static int parse_reinstall_opt(envid_t veid, int argc, char **argv, vps_param *param) { + int ret; + struct option *opt; + struct option reinstall_options[] = { + {"ostemplate", required_argument, NULL, PARAM_OSTEMPLATE}, + { NULL, 0, NULL, 0 } + }; + + opt = mod_make_opt(reinstall_options, &g_action, NULL); + if (opt == NULL) + return VZ_RESOURCE_ERROR; + + ret = parse_opt(veid, argc, argv, opt, reinstall_options, param); + free(opt); + + return ret; +} + static int parse_startstop_opt(int argc, char **argv, vps_param *param, int start, int stop) { @@ -394,6 +412,14 @@ static int stop(vps_handler *h, envid_t veid, vps_param *g_p, vps_param *cmd_p) return ret; } +static int reinstall(vps_handler *h, envid_t veid, vps_param *vps_p, vps_param *cmd_p) { + int ret; + + ret = vps_reinstall(h, veid, vps_p, cmd_p, &g_action); + + return ret; +} + static int restart(vps_handler *h, envid_t veid, vps_param *g_p, vps_param *cmd_p) { @@ -1529,6 +1555,9 @@ int parse_action_opt(envid_t veid, act_t action, int argc, char *argv[], case ACTION_CREATE: ret = parse_create_opt(veid, argc, argv, param); break; + case ACTION_REINSTALL: + ret = parse_reinstall_opt(veid, argc, argv, param); + break; #ifdef HAVE_PLOOP case ACTION_CONVERT: ret = parse_convert_opt(veid, argc, argv, param); @@ -1694,6 +1723,9 @@ int run_action(envid_t veid, act_t action, vps_param *g_p, vps_param *vps_p, case ACTION_RESTART: ret = restart(h, veid, g_p, cmd_p); break; + case ACTION_REINSTALL: + ret = reinstall(h, veid, g_p, cmd_p); + break; #ifdef HAVE_PLOOP case ACTION_CONVERT: ret = convert(h, veid, g_p, cmd_p); diff --git a/src/vzctl.c b/src/vzctl.c index b53c1b8..1c96f39 100644 --- a/src/vzctl.c +++ b/src/vzctl.c @@ -202,6 +202,9 @@ int main(int argc, char *argv[], char *envp[]) } else if (!strcmp(argv[1], "create")) { init_modules(&g_action, "create"); action = ACTION_CREATE; + } else if (!strcmp(argv[1], "reinstall")) { + init_modules(&g_action, "reinstall"); + action = ACTION_REINSTALL; } else if (!strcmp(argv[1], "start")) { init_modules(&g_action, "set"); action = ACTION_START;