1
0
mirror of https://github.com/lxc/go-lxc.git synced 2026-02-05 15:47:17 +01:00

introduce snapshot support v1

This commit is contained in:
S.Çağlar Onur
2013-10-11 17:16:41 -04:00
parent d135b7dce3
commit 1d18ad1cc4
9 changed files with 270 additions and 5 deletions

3
.gitignore vendored
View File

@@ -14,8 +14,11 @@ examples/interfaces
examples/ipaddress
examples/limit
examples/list
examples/list_snapshots
examples/reboot
examples/restore
examples/shutdown
examples/snapshot
examples/start
examples/stats
examples/stop

View File

@@ -74,4 +74,6 @@ const (
errStartFailed = "starting the container %q failed"
errStopFailed = "stopping the container %q failed"
errUnfreezeFailed = "unfreezing the container %q failed"
errSnapshotFailed = "snapshotting the container %q failed"
errRestoreFailed = "restoring the container %q failed"
)

View File

@@ -44,6 +44,14 @@ type Container struct {
sync.RWMutex
}
// Snapshot struct
type Snapshot struct {
Name string
CommentPath string
Timestamp string
Path string
}
func (lxc *Container) ensureDefinedAndRunning() error {
if !lxc.Defined() {
return fmt.Errorf(errNotDefined, C.GoString(lxc.container.name))
@@ -98,6 +106,69 @@ func (lxc *Container) MayControl() bool {
return bool(C.lxc_container_may_control(lxc.container))
}
// Snapshot creates a new snapshot
func (lxc *Container) Snapshot() error {
if err := lxc.ensureDefinedButNotRunning(); err != nil {
return err
}
lxc.Lock()
defer lxc.Unlock()
if int(C.lxc_container_snapshot(lxc.container)) < 0 {
return fmt.Errorf(errSnapshotFailed, C.GoString(lxc.container.name))
}
return nil
}
// Restore creates a new snapshot
func (lxc *Container) Restore(snapshot Snapshot, name string) error {
if !lxc.Defined() {
return fmt.Errorf(errNotDefined, C.GoString(lxc.container.name))
}
lxc.Lock()
defer lxc.Unlock()
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
csnapname := C.CString(snapshot.Name)
defer C.free(unsafe.Pointer(csnapname))
if !bool(C.lxc_container_snapshot_restore(lxc.container, csnapname, cname)) {
return fmt.Errorf(errRestoreFailed, C.GoString(lxc.container.name))
}
return nil
}
// ListSnapshots lists the snapshot of given container
func (lxc *Container) ListSnapshots() ([]Snapshot, error) {
if !lxc.Defined() {
return nil, fmt.Errorf(errNotDefined, C.GoString(lxc.container.name))
}
lxc.Lock()
defer lxc.Unlock()
var snapshots []Snapshot
size := int(C.lxc_container_snapshot_list_size(lxc.container))
if size < 1 {
return nil, fmt.Errorf("%s has no snapshots", C.GoString(lxc.container.name))
}
snapshot := C.lxc_container_snapshot_list(lxc.container)
defer freeSnapshots(snapshot, size)
p := uintptr(unsafe.Pointer(snapshot))
for i := 0; i < size; i++ {
z := (*C.struct_lxc_snapshot)(unsafe.Pointer(p))
s := &Snapshot{Name: C.GoString(z.name), Timestamp: C.GoString(z.timestamp), CommentPath: C.GoString(z.comment_pathname), Path: C.GoString(z.lxcpath)}
snapshots = append(snapshots, *s)
p += unsafe.Sizeof(*snapshot)
}
return snapshots, nil
}
// State returns the container's state
func (lxc *Container) State() State {
lxc.RLock()

View File

@@ -0,0 +1,46 @@
/*
* list_snapshots.go
*
* Copyright © 2013, S.Çağlar Onur
*
* Authors:
* S.Çağlar Onur <caglar@10ur.org>
*
* This library 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.
*/
package main
import (
"fmt"
"github.com/caglar10ur/lxc"
)
func main() {
for _, v := range lxc.Containers() {
fmt.Printf("%s\n", v.Name())
l, err := v.ListSnapshots()
if err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
}
for _, s := range l {
fmt.Printf("Name: %s\n", s.Name)
fmt.Printf("Comment path: %s\n", s.CommentPath)
fmt.Printf("Timestamp: %s\n", s.Timestamp)
fmt.Printf("LXC path: %s\n", s.Path)
fmt.Println()
}
}
}

50
examples/restore.go Normal file
View File

@@ -0,0 +1,50 @@
/*
* snapshot.go
*
* Copyright © 2013, S.Çağlar Onur
*
* Authors:
* S.Çağlar Onur <caglar@10ur.org>
*
* This library 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.
*/
package main
import (
"flag"
"fmt"
"github.com/caglar10ur/lxc"
)
var (
name string
)
func init() {
flag.StringVar(&name, "name", "rubik", "Name of the container")
flag.Parse()
}
func main() {
c := lxc.NewContainer(name)
defer lxc.PutContainer(c)
fmt.Printf("Restoring the container...\n")
snapshot := lxc.Snapshot{Name: "snap0"}
if err := c.Restore(snapshot, "rubik-restore"); err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
}
}

48
examples/snapshot.go Normal file
View File

@@ -0,0 +1,48 @@
/*
* snapshot.go
*
* Copyright © 2013, S.Çağlar Onur
*
* Authors:
* S.Çağlar Onur <caglar@10ur.org>
*
* This library 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.
*/
package main
import (
"flag"
"fmt"
"github.com/caglar10ur/lxc"
)
var (
name string
)
func init() {
flag.StringVar(&name, "name", "rubik", "Name of the container")
flag.Parse()
}
func main() {
c := lxc.NewContainer(name)
defer lxc.PutContainer(c)
fmt.Printf("Snapshoting the container...\n")
if err := c.Snapshot(); err != nil {
fmt.Printf("ERROR: %s\n", err.Error())
}
}

32
lxc.c
View File

@@ -243,3 +243,35 @@ int lxc_container_attach_run_wait(struct lxc_container *c, char **argv) {
bool lxc_container_may_control(struct lxc_container *c) {
return c->may_control(c);
}
int lxc_container_snapshot(struct lxc_container *c) {
return c->snapshot(c, NULL);
}
bool lxc_container_snapshot_restore(struct lxc_container *c, char *snapname, char *newname) {
return c->snapshot_restore(c, snapname, newname);
}
int lxc_container_snapshot_list_size(struct lxc_container *c) {
int i;
struct lxc_snapshot *s;
int n = c->snapshot_list(c, &s);
if (n < 1)
return 0;
for (i = 0; i < n; i++) {
s[i].free(&s[i]);
}
free(s);
return n;
}
struct lxc_snapshot* lxc_container_snapshot_list(struct lxc_container *c) {
struct lxc_snapshot *s;
int n = c->snapshot_list(c, &s);
if (n < 1)
return NULL;
return s;
}

10
lxc.h
View File

@@ -56,8 +56,8 @@ extern void lxc_container_want_daemonize(struct lxc_container *);
extern bool lxc_container_want_close_all_fds(struct lxc_container *);
extern bool lxc_container_may_control(struct lxc_container *);
//FIXME: Missing API functionality
// snapshot
// int (*snapshot)(struct lxc_container *c, char *commentfile);
// int (*snapshot_list)(struct lxc_container *, struct lxc_snapshot **);
// bool (*snapshot_restore)(struct lxc_container *c, char *snapname, char *newname);
extern int lxc_container_snapshot(struct lxc_container *);
extern bool lxc_container_snapshot_restore(struct lxc_container *, char *, char *);
extern struct lxc_snapshot* lxc_container_snapshot_list(struct lxc_container *);
extern int lxc_container_snapshot_list_size(struct lxc_container *);

13
util.go
View File

@@ -25,6 +25,7 @@ package lxc
/*
#include <stdlib.h>
#include <lxc/lxccontainer.h>
static char** makeCharArray(int size) {
return calloc(sizeof(char*), size);
@@ -40,6 +41,14 @@ static void freeCharArray(char **array, int size) {
free(array[i]);
free(array);
}
static void freeSnapshotArray(struct lxc_snapshot *s, int size) {
int i;
for (i = 0; i < size; i++) {
s[i].free(&s[i]);
}
free(s);
}
*/
import "C"
@@ -80,3 +89,7 @@ func convertArgs(cArgs **C.char) []string {
return s
}
func freeSnapshots(snapshots *C.struct_lxc_snapshot, size int) {
C.freeSnapshotArray(snapshots, C.int(size))
}