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:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -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
|
||||
|
||||
2
const.go
2
const.go
@@ -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"
|
||||
)
|
||||
|
||||
71
container.go
71
container.go
@@ -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()
|
||||
|
||||
46
examples/list_snapshots.go
Normal file
46
examples/list_snapshots.go
Normal 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
50
examples/restore.go
Normal 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
48
examples/snapshot.go
Normal 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
32
lxc.c
@@ -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
10
lxc.h
@@ -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
13
util.go
@@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user