Hopefully someone else will come in and spruce it up :) This version is as simple as can be
lxc-snapshot -n a1 create a snapshot of a1 echo "second commit" > /tmp/a lxc-snapshot -n a1 -c /tmp/a create a snapshot of a1 with /tmp/a as a commit comment lxc-snapshot -n a1 -L list a1's snapshots lxc-snapshot -n a1 -L -C list a1's snapshots along with commit comments lxc-snapshot -n a1 -r snap0 a2 restore snapshot 0 of a1 as container a2 Some easy nice-to-haves: 1. sort snapshots in the list 2. allow a comment to be given in-line 3. an option to remove a snapshot? Removing a snapshot can just as well be done with lxc-destroy -P /var/lib/lxcsnaps/c1 -n snap2 so I leave it to others to decide whether they really want it, and provide the patch if so. Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com> --- src/lxc/Makefile.am | 4 +- src/lxc/lxc_snapshot.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/lxc/lxc_snapshot.c diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index da5ff15..35ec2a3 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -171,7 +171,8 @@ bin_PROGRAMS = \ lxc-config \ lxc-destroy \ lxc-create \ - lxc-user-nic + lxc-user-nic \ + lxc-snapshot if HAVE_NEWUIDMAP bin_PROGRAMS += lxc-usernsexec @@ -207,6 +208,7 @@ lxc_unshare_SOURCES = lxc_unshare.c lxc_wait_SOURCES = lxc_wait.c lxc_kill_SOURCES = lxc_kill.c lxc_create_SOURCES = lxc_create.c +lxc_snapshot_SOURCES = lxc_snapshot.c lxc_usernsexec_SOURCES = lxc_usernsexec.c lxc_user_nic_SOURCES = lxc_user_nic.c diff --git a/src/lxc/lxc_snapshot.c b/src/lxc/lxc_snapshot.c new file mode 100644 index 0000000..2222972 --- /dev/null +++ b/src/lxc/lxc_snapshot.c @@ -0,0 +1,201 @@ +/* + * + * Copyright © 2013 Serge Hallyn <serge.hal...@ubuntu.com>. + * Copyright © 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../lxc/lxccontainer.h" + +#include <stdio.h> +#include <libgen.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/types.h> + +#include <lxc/lxc.h> +#include <lxc/log.h> +#include <lxc/bdev.h> + +#include "arguments.h" +#include "utils.h" + +lxc_log_define(lxc_snapshot, lxc); + +char *newname; +char *snapshot; + +#define DO_SNAP 0 +#define DO_LIST 1 +#define DO_RESTORE 2 +int action; +int print_comments; +char *commentfile; + +int do_snapshot(struct lxc_container *c) +{ + int ret; + + ret = c->snapshot(c, commentfile); + if (ret < 0) { + ERROR("Error creating a snapshot"); + return -1; + } + + INFO("Created snapshot snap%d\n", ret); + return 0; +} + +void print_file(char *path) +{ + if (!path) + return; + FILE *f = fopen(path, "r"); + char *line = NULL; + size_t sz = 0; + if (!f) + return; + while (getline(&line, &sz, f) != -1) { + printf("%s", line); + } + if (line) + free(line); + fclose(f); +} + +int do_list_snapshots(struct lxc_container *c) +{ + struct lxc_snapshot *s; + int i, n; + + n = c->snapshot_list(c, &s); + if (n < 0) { + ERROR("Error listing snapshots"); + return -1; + } + if (n == 0) { + printf("No snapshots\n"); + return 0; + } + for (i=0; i<n; i++) { + printf("%s (%s) %s\n", s[i].name, s[i].lxcpath, s[i].timestamp); + if (print_comments) + print_file(s[i].comment_pathname); + s[i].free(&s[i]); + } + free(s); + return 0; +} + +int do_restore_snapshots(struct lxc_container *c, char *snap, char *new) +{ + if (c->snapshot_restore(c, snapshot, newname)) + return 0; + + ERROR("Error restoring snapshot %s", snapshot); + return -1; +} + +static int my_parser(struct lxc_arguments* args, int c, char* arg) +{ + switch (c) { + case 'L': action = DO_LIST; break; + case 'r': snapshot = arg; action = DO_RESTORE; break; + case 'c': commentfile = arg; break; + case 'C': print_comments = true; break; + } + return 0; +} + +static const struct option my_longopts[] = { + {"list", no_argument, 0, 'L'}, + {"restore", required_argument, 0, 'r'}, + {"comment", required_argument, 0, 'c'}, + {"showcomments", no_argument, 0, 'C'}, + LXC_COMMON_OPTIONS +}; + + +static struct lxc_arguments my_args = { + .progname = "lxc-create", + .help = "\ +--name=NAME [-w] [-r] [-t timeout] [-P lxcpath]\n\ +\n\ +lxc-create creates a container\n\ +\n\ +Options :\n\ + -L, --list list snapshots\n\ + -C, --showcomments show snapshot comments in list\n\ + -c, --comment=file add file as a comment\n\ + -r, --restore=name restore snapshot name, i.e. 'snap0'\n", + .options = my_longopts, + .parser = my_parser, + .checker = NULL, +}; + +/* + * lxc-snapshot -P lxcpath -n container + * lxc-snapshot -P lxcpath -n container -l + * lxc-snapshot -P lxcpath -n container -r snap3 recovered_1 + */ + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 0; + + if (lxc_arguments_parse(&my_args, argc, argv)) + exit(1); + + if (my_args.argc > 1) { + ERROR("Too many arguments"); + return -1; + } + if (my_args.argc == 1) + newname = my_args.argv[0]; + + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + exit(1); + + if (geteuid()) { + if (access(my_args.lxcpath[0], O_RDWR) < 0) { + fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]); + exit(1); + } + } + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + fprintf(stderr, "System error loading container\n"); + exit(1); + } + + switch(action) { + case DO_SNAP: + ret = do_snapshot(c); + break; + case DO_LIST: + ret = do_list_snapshots(c); + break; + case DO_RESTORE: + ret = do_restore_snapshots(c, snapshot, newname); + break; + } + + lxc_container_put(c); + + exit(ret); +} -- 1.8.1.2 ------------------------------------------------------------------------------ Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58041391&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel