Codebase list golang-gopkg-lxc-go-lxc.v2 / 6d861971-9faf-4e0e-9078-e5e466c800c5/main lxc-binding.go
6d861971-9faf-4e0e-9078-e5e466c800c5/main

Tree @6d861971-9faf-4e0e-9078-e5e466c800c5/main (Download .tar.gz)

lxc-binding.go @6d861971-9faf-4e0e-9078-e5e466c800c5/main

e9a64ee
8378f3f
 
dbb8a0e
271bee3
948e26f
d29686b
 
2718c68
52defc1
57209a5
86ba6ed
 
 
d29686b
 
5964977
c61cc4d
3b71609
455e623
5964977
 
d29686b
e5d59f7
c60d393
b1e9b3b
 
 
d29686b
 
16396d4
b1e9b3b
 
 
 
 
 
 
 
 
a322340
2ca1c85
a322340
5964977
 
 
6aabb10
 
ec940a5
 
d7bad84
 
 
e5d59f7
0dfb165
 
ec940a5
 
d7bad84
0dfb165
 
e5d59f7
462f7d6
c61cc4d
cbff440
 
 
455e623
c61cc4d
cbff440
c61cc4d
6aabb10
 
e5d59f7
4cd4028
 
 
 
 
 
 
e5d59f7
462f7d6
4cd4028
d29686b
b679635
e5d59f7
d7eaff3
ca32ab1
d7eaff3
 
e5d59f7
d7eaff3
0027928
d7eaff3
 
b1e9b3b
 
 
 
 
 
 
 
 
 
 
 
 
 
16396d4
b1e9b3b
 
 
 
 
 
d9a744e
 
c60d393
379087f
 
b1e9b3b
 
d9a744e
379087f
16396d4
b679635
d9a744e
b1e9b3b
b679635
 
b1e9b3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9a744e
 
c60d393
379087f
 
b679635
b1e9b3b
d9a744e
379087f
a322340
b679635
d9a744e
b679635
 
750307c
 
b1e9b3b
 
 
750307c
b1e9b3b
 
 
 
 
 
 
 
 
 
 
 
750307c
b1e9b3b
750307c
 
d9a744e
 
c60d393
379087f
 
750307c
b1e9b3b
d9a744e
379087f
a322340
750307c
d9a744e
750307c
 
52defc1
7b6d52d
52defc1
 
 
 
 
 
8a9d53a
7b6d52d
8a9d53a
802f80e
 
 
 
8a9d53a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a9c896
7b6d52d
0a9c896
 
 
c532dc9
0a9c896
bbbfb83
3b71609
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bbbfb83
d7bad84
bbbfb83
d7bad84
 
 
 
 
3b71609
 
 
 
 
 
bbbfb83
// Copyright © 2013, 2014, The Go-LXC Authors. All rights reserved.
// Use of this source code is governed by a LGPLv2.1
// license that can be found in the LICENSE file.

// +build linux,cgo

package lxc

// #include <lxc/lxccontainer.h>
// #include <lxc/version.h>
// #include "lxc-binding.h"
// #ifndef LXC_DEVEL
// #define LXC_DEVEL 0
// #endif
import "C"

import (
	"fmt"
	"strconv"
	"strings"
	"unsafe"
)

// NewContainer returns a new container struct.
// Caller needs to call Release() on the returned container to release its resources.
func NewContainer(name string, lxcpath ...string) (*Container, error) {
	var container *C.struct_lxc_container

	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		container = C.lxc_container_new(cname, clxcpath)
	} else {
		container = C.lxc_container_new(cname, nil)
	}

	if container == nil {
		return nil, ErrNewFailed
	}
	c := &Container{container: container, verbosity: Quiet}

	return c, nil
}

// Acquire increments the reference counter of the container object.
func Acquire(c *Container) bool {
	c.mu.RLock()
	defer c.mu.RUnlock()

	return C.lxc_container_get(c.container) == 1
}

// Release decrements the reference counter of the container object.
func Release(c *Container) bool {
	return c.Release() == nil
}

// Version returns the LXC version.
func Version() string {
	version := C.GoString(C.lxc_get_version())

	// New liblxc versions append "-devel" when LXC_DEVEL is set.
	if strings.HasSuffix(version, "-devel") {
		return fmt.Sprintf("%s (devel)", version[:(len(version)-len("-devel"))])
	}

	return version
}

// GlobalConfigItem returns the value of the given global config key.
func GlobalConfigItem(name string) string {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	return C.GoString(C.lxc_get_global_config_item(cname))
}

// DefaultConfigPath returns default config path.
func DefaultConfigPath() string {
	return GlobalConfigItem("lxc.lxcpath")
}

// DefaultLvmVg returns the name of the default LVM volume group.
func DefaultLvmVg() string {
	return GlobalConfigItem("lxc.bdev.lvm.vg")
}

// DefaultZfsRoot returns the name of the default ZFS root.
func DefaultZfsRoot() string {
	return GlobalConfigItem("lxc.bdev.zfs.root")
}

// ContainerNames returns the names of defined and active containers on the system.
func ContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_all_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_all_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// Containers returns the defined and active containers on the system. Only
// containers that could retrieved successfully are returned.
// Caller needs to call Release() on the returned containers to release resources.
func Containers(lxcpath ...string) []*Container {
	var containers []*Container

	for _, v := range ContainerNames(lxcpath...) {
		if container, err := NewContainer(v, lxcpath...); err == nil {
			containers = append(containers, container)
		}
	}

	return containers
}

// DefinedContainerNames returns the names of the defined containers on the system.
func DefinedContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_defined_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_defined_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// DefinedContainers returns the defined containers on the system.  Only
// containers that could retrieved successfully are returned.
// Caller needs to call Release() on the returned containers to release resources.
func DefinedContainers(lxcpath ...string) []*Container {
	var containers []*Container

	for _, v := range DefinedContainerNames(lxcpath...) {
		if container, err := NewContainer(v, lxcpath...); err == nil {
			containers = append(containers, container)
		}
	}

	return containers
}

// ActiveContainerNames returns the names of the active containers on the system.
func ActiveContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_active_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_active_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// ActiveContainers returns the active containers on the system. Only
// containers that could retrieved successfully are returned.
// Caller needs to call Release() on the returned containers to release resources.
func ActiveContainers(lxcpath ...string) []*Container {
	var containers []*Container

	for _, v := range ActiveContainerNames(lxcpath...) {
		if container, err := NewContainer(v, lxcpath...); err == nil {
			containers = append(containers, container)
		}
	}

	return containers
}

// VersionNumber returns the LXC version.
func VersionNumber() (major int, minor int) {
	major = C.LXC_VERSION_MAJOR
	minor = C.LXC_VERSION_MINOR

	return
}

// VersionAtLeast returns true when the tested version >= current version.
func VersionAtLeast(major int, minor int, micro int) bool {
	if C.LXC_DEVEL == 1 {
		return true
	}

	if major > C.LXC_VERSION_MAJOR {
		return false
	}

	if major == C.LXC_VERSION_MAJOR &&
		minor > C.LXC_VERSION_MINOR {
		return false
	}

	if major == C.LXC_VERSION_MAJOR &&
		minor == C.LXC_VERSION_MINOR &&
		micro > C.LXC_VERSION_MICRO {
		return false
	}

	return true
}

// IsSupportedConfigItem returns true if the key belongs to a supported config item.
func IsSupportedConfigItem(key string) bool {
	configItem := C.CString(key)
	defer C.free(unsafe.Pointer(configItem))
	return bool(C.go_lxc_config_item_is_supported(configItem))
}

// runtimeLiblxcVersionAtLeast checks if the system's liblxc matches the
// provided version requirement
func runtimeLiblxcVersionAtLeast(major int, minor int, micro int) bool {
	version := Version()
	version = strings.Replace(version, " (devel)", "-devel", 1)
	parts := strings.Split(version, ".")
	partsLen := len(parts)
	if partsLen == 0 {
		return false
	}

	develParts := strings.Split(parts[partsLen-1], "-")
	if len(develParts) == 2 && develParts[1] == "devel" {
		return true
	}

	maj := -1
	min := -1
	mic := -1

	for i, v := range parts {
		if i > 2 {
			break
		}

		num, err := strconv.Atoi(v)
		if err != nil {
			return false
		}

		switch i {
		case 0:
			maj = num
		case 1:
			min = num
		case 2:
			mic = num
		}
	}

	/* Major version is greater. */
	if maj > major {
		return true
	}

	if maj < major {
		return false
	}

	/* Minor number is greater.*/
	if min > minor {
		return true
	}

	if min < minor {
		return false
	}

	/* Patch number is greater. */
	if mic > micro {
		return true
	}

	if mic < micro {
		return false
	}

	return true
}

// HasApiExtension returns true if the extension is supported.
// Deprecated: Please use HasAPIExtension instead.
func HasApiExtension(extension string) bool {
	return HasAPIExtension(extension)
}

// HasAPIExtension returns true if the extension is supported.
func HasAPIExtension(extension string) bool {
	if runtimeLiblxcVersionAtLeast(3, 1, 0) {
		apiExtension := C.CString(extension)
		defer C.free(unsafe.Pointer(apiExtension))
		return bool(C.go_lxc_has_api_extension(apiExtension))
	}
	return false
}