tree-wide: remove python3 bindings

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2018-02-14 11:53:18 +01:00
parent b52a5bef6f
commit e144a06bd7
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D
13 changed files with 1 additions and 3062 deletions

4
.gitignore vendored
View File

@ -67,10 +67,6 @@ src/lxc/version.h
src/lxc/cmd/lxc-checkconfig src/lxc/cmd/lxc-checkconfig
src/lxc/cmd/lxc-update-config src/lxc/cmd/lxc-update-config
src/python-lxc/build/
src/python-lxc/lxc/__pycache__/
src/python-lxc/lxc.egg-info/
src/tests/lxc-test-device-add-remove src/tests/lxc-test-device-add-remove
src/tests/lxc-test-attach src/tests/lxc-test-attach
src/tests/lxc-test-apparmor src/tests/lxc-test-apparmor

View File

@ -13,10 +13,6 @@ EXTRA_DIST = \
RPMARGS = RPMARGS =
if ENABLE_PYTHON
RPMARGS += --with python
endif
pcdatadir = $(libdir)/pkgconfig pcdatadir = $(libdir)/pkgconfig
pcdata_DATA = lxc.pc pcdata_DATA = lxc.pc

View File

@ -363,29 +363,6 @@ AC_ARG_ENABLE([examples],
[], [enable_examples=yes]) [], [enable_examples=yes])
AM_CONDITIONAL([ENABLE_EXAMPLES], [test "x$enable_examples" = "xyes"]) AM_CONDITIONAL([ENABLE_EXAMPLES], [test "x$enable_examples" = "xyes"])
# Python3 module and scripts
AC_ARG_ENABLE([python],
[AC_HELP_STRING([--enable-python], [enable python binding [default=auto]])],
[], [enable_python=auto])
if test "x$enable_python" = "xauto"; then
PKG_CHECK_MODULES([PYTHONDEV], [python3 >= 3.2],[enable_python=yes],[enable_python=no])
if test "$CC" = "clang"; then
enable_python=no
fi
fi
if test "x$enable_python" = "xyes" && test "$CC" = "clang"; then
AC_MSG_ERROR([Python3 is incompatible with the clang compiler])
fi
AM_CONDITIONAL([ENABLE_PYTHON], [test "x$enable_python" = "xyes"])
AM_COND_IF([ENABLE_PYTHON],
[AM_PATH_PYTHON([3.2], [], [AC_MSG_ERROR([You must install python3])])
PKG_CHECK_MODULES([PYTHONDEV], [python3 >= 3.2],[],[AC_MSG_ERROR([You must install python3-dev])])
AC_DEFINE_UNQUOTED([ENABLE_PYTHON], 1, [Python3 is available])])
# Enable dumping stack traces # Enable dumping stack traces
AC_ARG_ENABLE([mutex-debugging], AC_ARG_ENABLE([mutex-debugging],
[AC_HELP_STRING([--enable-mutex-debugging], [Makes mutexes to report error and provide stack trace [default=no]])], [AC_HELP_STRING([--enable-mutex-debugging], [Makes mutexes to report error and provide stack trace [default=no]])],
@ -894,7 +871,6 @@ AC_CONFIG_FILES([
src/lxc/cmd/lxc-checkconfig src/lxc/cmd/lxc-checkconfig
src/lxc/cmd/lxc-update-config src/lxc/cmd/lxc-update-config
src/lxc/version.h src/lxc/version.h
src/python-lxc/Makefile
src/tests/Makefile src/tests/Makefile
src/tests/lxc-test-usernic src/tests/lxc-test-usernic
@ -957,9 +933,6 @@ PAM:
- PAM module: $enable_pam - PAM module: $enable_pam
- cgroup PAM module: $pamdir - cgroup PAM module: $pamdir
Bindings:
- python3: $enable_python
Documentation: Documentation:
- examples: $enable_examples - examples: $enable_examples
- API documentation: $enable_api_docs - API documentation: $enable_api_docs

View File

@ -41,13 +41,6 @@ man_MANS = \
\ \
lxc.7 lxc.7
if ENABLE_DEPRECATED
man_MANS += lxc-clone.1
if ENABLE_PYTHON
man_MANS += lxc-start-ephemeral.1
endif
endif
%.1 : %.sgml %.1 : %.sgml
$(db2xman) --encoding=UTF-8 $< $(db2xman) --encoding=UTF-8 $<
test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true

View File

@ -20,8 +20,6 @@
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
%global with_python %{?_with_python: 1} %{?!_with_python: 0}
# Set with_systemd on distros that use it, so we can install the service # Set with_systemd on distros that use it, so we can install the service
# file, otherwise the sysvinit script will be installed # file, otherwise the sysvinit script will be installed
%if 0%{?fedora} >= 14 || 0%{?rhel} >= 7 || 0%{?suse_version} >= 1210 %if 0%{?fedora} >= 14 || 0%{?rhel} >= 7 || 0%{?suse_version} >= 1210
@ -93,12 +91,6 @@ BuildRequires: libseccomp-devel
%endif %endif
%endif %endif
%if %{with_python}
Requires: python3
BuildRequires: python3-devel
BuildRequires: python3-setuptools
%endif
%description %description
Containers are insulated areas inside a system, which have their own namespace Containers are insulated areas inside a system, which have their own namespace
for filesystem, network, PID, IPC, CPU and memory allocation and which can be for filesystem, network, PID, IPC, CPU and memory allocation and which can be
@ -127,9 +119,6 @@ development of the Linux containers.
%setup -q -n %{name}-%{version}%{?beta_dot} %setup -q -n %{name}-%{version}%{?beta_dot}
%build %build
PATH=$PATH:/usr/sbin:/sbin %configure $args \ PATH=$PATH:/usr/sbin:/sbin %configure $args \
%if %{with_python}
--enable-python \
%endif
%if "x%{_unitdir}" != "x" %if "x%{_unitdir}" != "x"
--with-systemdsystemunitdir=%{_unitdir} \ --with-systemdsystemunitdir=%{_unitdir} \
%endif %endif
@ -266,10 +255,6 @@ fi
%attr(555,root,root) %{_libexecdir}/%{name}/lxc-containers %attr(555,root,root) %{_libexecdir}/%{name}/lxc-containers
%endif %endif
%if %{with_python}
%{python3_sitearch}/*
%endif
%files devel %files devel
%defattr(-,root,root) %defattr(-,root,root)
%{_includedir}/%{name}/* %{_includedir}/%{name}/*

View File

@ -1 +1 @@
SUBDIRS = lxc tests python-lxc SUBDIRS = lxc tests

View File

@ -1,35 +0,0 @@
if ENABLE_PYTHON
if HAVE_DEBIAN
DISTSETUPOPTS=--install-layout=deb
else
DISTSETUPOPTS=
endif
if ENABLE_RPATH
RPATHOPTS=-R $(libdir)
else
RPATHOPTS=
endif
CALL_SETUP_PY := cd @srcdir@ && $(PYTHON) setup.py build -b @abs_builddir@/build egg_info -e @abs_builddir@
all:
$(CALL_SETUP_PY) build_ext -I @abs_top_srcdir@/src -L @abs_top_builddir@/src/lxc/.libs/ $(RPATHOPTS) --no-pkg-config
DESTDIR = / # default
install:
$(CALL_SETUP_PY) install --prefix=$(prefix) --no-compile $(DISTSETUPOPTS) --root=$(DESTDIR)
clean-local:
rm -rf @builddir@/build
endif
EXTRA_DIST = \
setup.py \
lxc.c \
lxc/__init__.py \
examples/api_test.py \
examples/pyconsole.py \
examples/pyconsole-vte.py

View File

@ -1,207 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# api_test.py: Test/demo of the python3-lxc API
#
# (C) Copyright Canonical Ltd. 2012
#
# Authors:
# Stéphane Graber <stgraber@ubuntu.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
# USA
#
import lxc
import uuid
import os
import subprocess
import sys
import time
# Let's pick a random name, avoiding clashes
CONTAINER_NAME = str(uuid.uuid1())
CLONE_NAME = str(uuid.uuid1())
RENAME_NAME = str(uuid.uuid1())
## Instantiate the container instance
print("Getting instance for '%s'" % CONTAINER_NAME)
container = lxc.Container(CONTAINER_NAME)
# A few basic checks of the current state
assert(container.config_file_name == "%s/%s/config" %
(lxc.default_config_path, CONTAINER_NAME))
assert(not container.defined)
assert(container.init_pid == -1)
assert(container.name == CONTAINER_NAME)
assert(not container.running)
assert(container.state == "STOPPED")
# Try to get the host architecture for dpkg systems
arch = "i386"
try:
with open(os.path.devnull, "w") as devnull:
dpkg = subprocess.Popen(['dpkg', '--print-architecture'],
stderr=devnull, stdout=subprocess.PIPE,
universal_newlines=True)
if dpkg.wait() == 0:
arch = dpkg.stdout.read().strip()
except:
pass
## Create a rootfs
print("Creating rootfs using 'download', arch=%s" % arch)
container.create("download", 0,
{"dist": "ubuntu",
"release": "xenial",
"arch": arch})
assert(container.defined)
assert(container.name == CONTAINER_NAME
== container.get_config_item("lxc.uts.name"))
assert(container.name in lxc.list_containers())
## Test the config
print("Testing the configuration")
capdrop = container.get_config_item("lxc.cap.drop")
container.clear_config_item("lxc.cap.drop")
container.set_config_item("lxc.cap.drop", capdrop[:-1])
container.append_config_item("lxc.cap.drop", capdrop[-1])
container.save_config()
# A few basic checks of the current state
assert(isinstance(capdrop, list))
assert(capdrop == container.get_config_item("lxc.cap.drop"))
## Test the networking
print("Testing the networking")
# A few basic checks of the current state
assert("name" in container.get_keys("lxc.net.0"))
assert(len(container.network) == 1)
## Starting the container
print("Starting the container")
container.start()
container.wait("RUNNING", 3)
# A few basic checks of the current state
assert(container.init_pid > 1)
assert(container.running)
assert(container.state == "RUNNING")
## Checking IP address
print("Getting the interface names")
assert(set(container.get_interfaces()) == set(('lo', 'eth0')))
## Checking IP address
print("Getting the IP addresses")
count = 0
ips = []
while not ips or count == 10:
ips = container.get_ips()
time.sleep(1)
count += 1
if os.geteuid():
container.attach_wait(lxc.attach_run_command, ["ifconfig", "eth0"],
namespaces=(lxc.CLONE_NEWUSER + lxc.CLONE_NEWNET
+ lxc.CLONE_NEWUTS))
else:
container.attach_wait(lxc.attach_run_command, ["ifconfig", "eth0"],
namespaces=(lxc.CLONE_NEWNET + lxc.CLONE_NEWUTS))
# A few basic checks of the current state
assert(len(ips) > 0)
## Test running config
assert(container.name == CONTAINER_NAME
== container.get_config_item("lxc.uts.name")
== container.get_running_config_item("lxc.uts.name"))
## Testing cgroups a bit
print("Testing cgroup API")
max_mem = container.get_cgroup_item("memory.max_usage_in_bytes")
current_limit = container.get_cgroup_item("memory.limit_in_bytes")
assert(container.set_cgroup_item("memory.limit_in_bytes", max_mem))
assert(container.get_cgroup_item("memory.limit_in_bytes") != current_limit)
## Freezing the container
print("Freezing the container")
container.freeze()
container.wait("FROZEN", 3)
# A few basic checks of the current state
assert(container.init_pid > 1)
assert(container.running)
assert(container.state == "FROZEN")
## Unfreezing the container
print("Unfreezing the container")
container.unfreeze()
container.wait("RUNNING", 3)
# A few basic checks of the current state
assert(container.init_pid > 1)
assert(container.running)
assert(container.state == "RUNNING")
if len(sys.argv) > 1 and sys.argv[1] == "--with-console":
## Attaching to tty1
print("Attaching to tty1")
container.console(tty=1)
## Shutting down the container
print("Shutting down the container")
if not container.shutdown(3):
container.stop()
if container.running:
print("Stopping the container")
container.stop()
container.wait("STOPPED", 3)
# A few basic checks of the current state
assert(container.init_pid == -1)
assert(not container.running)
assert(container.state == "STOPPED")
## Snapshotting the container
print("Snapshotting the container")
assert(not container.snapshot_list())
assert(container.snapshot() == "snap0")
assert(len(container.snapshot_list()) == 1)
assert(container.snapshot_restore("snap0") is True)
assert(container.snapshot_destroy("snap0") is True)
## Cloning the container
print("Cloning the container as '%s'" % CLONE_NAME)
clone = container.clone(CLONE_NAME)
assert(clone is not False)
print ("Renaming the clone to '%s'" % RENAME_NAME)
rename = clone.rename(RENAME_NAME)
rename.start()
rename.stop()
rename.destroy()
## Destroy the container
print("Destroying the container")
container.destroy()
assert(not container.defined)

View File

@ -1,79 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# pyconsole-vte: Example program showing use of console functions
# in the lxc python binding
#
# (C) Copyright Oracle. 2013
#
# Authors:
# Dwight Engen <dwight.engen@oracle.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
# USA
#
import gtk
import vte
import lxc
import sys
def gtk_exit_cb(terminal):
gtk.main_quit()
def vte_con(ct, ttynum):
print("Doing console in a VTE widget...")
masterfd = ct.console_getfd(ttynum)
term = vte.Terminal()
term.set_cursor_blinks(True)
term.set_scrollback_lines(1000)
term.connect('eof', gtk_exit_cb)
term.set_pty(masterfd)
term.feed_child('\n')
#term.feed_child('ps aux\n')
vscrollbar = gtk.VScrollbar()
vscrollbar.set_adjustment(term.get_adjustment())
hbox = gtk.HBox()
hbox.pack_start(term)
hbox.pack_start(vscrollbar)
window = gtk.Window()
window.add(hbox)
window.connect('delete-event', lambda window, event: gtk.main_quit())
window.show_all()
gtk.main()
print("Console done")
if __name__ == '__main__':
ttynum = -1
if len(sys.argv) < 2:
sys.exit("Usage: %s container-name [ttynum]" % sys.argv[0])
if len(sys.argv) > 2:
ttynum = int(sys.argv[2])
ct = lxc.Container(sys.argv[1])
print("Container:%s tty:%d" % (ct.name, ttynum))
if not ct.defined:
sys.exit("Container %s not defined" % ct.name)
if not ct.running:
sys.exit("Container %s not running" % ct.name)
vte_con(ct, ttynum)

View File

@ -1,53 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# pyconsole: Example program showing use of console functions
# in the lxc python binding
#
# (C) Copyright Oracle. 2013
#
# Authors:
# Dwight Engen <dwight.engen@oracle.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
# USA
#
import lxc
import sys
import time
if __name__ == '__main__':
ttynum = -1
escape = 1
if len(sys.argv) < 2:
sys.exit("Usage: %s container-name [ttynum [escape]]" % sys.argv[0])
if len(sys.argv) > 2:
ttynum = int(sys.argv[2])
if len(sys.argv) > 3:
escape = ord(sys.argv[3]) - ord('a') + 1
ct = lxc.Container(sys.argv[1])
print("Container:%s tty:%d Ctrl-%c q to quit" %
(ct.name, ttynum, ord('a') + escape-1))
time.sleep(1)
if not ct.defined:
sys.exit("Container %s not defined" % ct.name)
if not ct.running:
sys.exit("Container %s not running" % ct.name)
ct.console(ttynum, 0, 1, 2, escape)
print("Console done")

File diff suppressed because it is too large Load Diff

View File

@ -1,510 +0,0 @@
#
# -*- coding: utf-8 -*-
# python-lxc: Python bindings for LXC
#
# (C) Copyright Canonical Ltd. 2012
#
# Authors:
# Stéphane Graber <stgraber@ubuntu.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
# USA
#
import _lxc
import os
import subprocess
import time
default_config_path = _lxc.get_global_config_item("lxc.lxcpath")
get_global_config_item = _lxc.get_global_config_item
version = _lxc.get_version()
class ContainerNetwork(object):
props = {}
def __init__(self, container, index):
self.container = container
self.index = index
for key in self.container.get_keys("lxc.net.%s" % self.index):
if "." in key:
self.props[key.replace(".", "_")] = key
else:
self.props[key] = key
if not self.props:
return False
def __delattr__(self, key):
if key in ["container", "index", "props"]:
return object.__delattr__(self, key)
if key not in self.props:
raise AttributeError("'%s' network has no attribute '%s'" % (
self.__get_network_item("type"), key))
return self.__clear_network_item(self.props[key])
def __dir__(self):
return sorted(self.props.keys())
def __getattr__(self, key):
if key in ["container", "index", "props"]:
return object.__getattribute__(self, key)
if key not in self.props:
raise AttributeError("'%s' network has no attribute '%s'" % (
self.__get_network_item("type"), key))
return self.__get_network_item(self.props[key])
def __hasattr__(self, key):
if key in ["container", "index", "props"]:
return object.__hasattr__(self, key)
if key not in self.props:
raise AttributeError("'%s' network has no attribute '%s'" % (
self.__get_network_item("type"), key))
return True
def __repr__(self):
return "'%s' network at index '%s'" % (
self.__get_network_item("type"), self.index)
def __setattr__(self, key, value):
if key in ["container", "index", "props"]:
return object.__setattr__(self, key, value)
if key not in self.props:
raise AttributeError("'%s' network has no attribute '%s'" % (
self.__get_network_item("type"), key))
return self.__set_network_item(self.props[key], value)
def __clear_network_item(self, key):
if key in ("ipv4", "ipv6"):
return self.container.clear_config_item("lxc.net.%s.%s" % (
self.index, key))
else:
return self.container.set_config_item("lxc.net.%s.%s" % (
self.index, key), "")
def __get_network_item(self, key):
return self.container.get_config_item("lxc.net.%s.%s" % (
self.index, key))
def __set_network_item(self, key, value):
return self.container.set_config_item("lxc.net.%s.%s" % (
self.index, key), value)
class ContainerNetworkList():
def __init__(self, container):
self.container = container
def __getitem__(self, index):
if index >= len(self):
raise IndexError("list index out of range")
return ContainerNetwork(self.container, index)
def __len__(self):
values = self.container.get_config_item("lxc.net")
if values:
return len(values)
else:
return 0
def add(self, network_type):
index = len(self)
return self.container.set_config_item("lxc.net.%s.type" % index,
network_type)
def remove(self, index):
count = len(self)
if index >= count:
raise IndexError("list index out of range")
return self.container.clear_config_item("lxc.net.%s" % index)
class Container(_lxc.Container):
def __init__(self, name, config_path=None):
"""
Creates a new Container instance.
"""
if config_path:
_lxc.Container.__init__(self, name, config_path)
else:
_lxc.Container.__init__(self, name)
self.network = ContainerNetworkList(self)
def add_device_net(self, name, destname=None):
"""
Add network device to running container.
"""
if not self.running:
return False
if os.path.exists("/sys/class/net/%s/phy80211/name" % name):
with open("/sys/class/net/%s/phy80211/name" % name) as fd:
phy = fd.read().strip()
if subprocess.call(['iw', 'phy', phy, 'set', 'netns',
str(self.init_pid)]) != 0:
return False
if destname:
def rename_interface(args):
old, new = args
return subprocess.call(['ip', 'link', 'set',
'dev', old, 'name', new])
return self.attach_wait(rename_interface, (name, destname),
namespaces=(CLONE_NEWNET)) == 0
return True
if not destname:
destname = name
if not os.path.exists("/sys/class/net/%s/" % name):
return False
return subprocess.call(['ip', 'link', 'set',
'dev', name,
'netns', str(self.init_pid),
'name', destname]) == 0
def append_config_item(self, key, value):
"""
Append 'value' to 'key', assuming 'key' is a list.
If 'key' isn't a list, 'value' will be set as the value of 'key'.
"""
return _lxc.Container.set_config_item(self, key, value)
def create(self, template=None, flags=0, args=(), bdevtype=None):
"""
Create a new rootfs for the container.
"template" if passed must be a valid template name.
"flags" (optional) is an integer representing the optional
create flags to be passed.
"args" (optional) is a tuple of arguments to pass to the
template. It can also be provided as a dict.
"""
if isinstance(args, dict):
tmp_args = []
for item in args.items():
tmp_args.append("--%s" % item[0])
tmp_args.append("%s" % item[1])
args = tmp_args
template_args = {}
if template:
template_args['template'] = template
template_args['flags'] = flags
template_args['args'] = tuple(args)
if bdevtype:
template_args['bdevtype'] = bdevtype
return _lxc.Container.create(self, **template_args)
def clone(self, newname, config_path=None, flags=0, bdevtype=None,
bdevdata=None, newsize=0, hookargs=()):
"""
Clone the current container.
"""
args = {}
args['newname'] = newname
args['flags'] = flags
args['newsize'] = newsize
args['hookargs'] = hookargs
if config_path:
args['config_path'] = config_path
if bdevtype:
args['bdevtype'] = bdevtype
if bdevdata:
args['bdevdata'] = bdevdata
if _lxc.Container.clone(self, **args):
return Container(newname, config_path=config_path)
else:
return False
def console(self, ttynum=-1, stdinfd=0, stdoutfd=1, stderrfd=2, escape=1):
"""
Attach to console of running container.
"""
if not self.running:
return False
return _lxc.Container.console(self, ttynum, stdinfd, stdoutfd,
stderrfd, escape)
def console_getfd(self, ttynum=-1):
"""
Attach to console of running container.
"""
if not self.running:
return False
return _lxc.Container.console_getfd(self, ttynum)
def get_cgroup_item(self, key):
"""
Returns the value for a given cgroup entry.
A list is returned when multiple values are set.
"""
value = _lxc.Container.get_cgroup_item(self, key)
if value is False:
return False
else:
return value.rstrip("\n")
def get_config_item(self, key):
"""
Returns the value for a given config key.
A list is returned when multiple values are set.
"""
value = _lxc.Container.get_config_item(self, key)
if value is False:
return False
elif value.endswith("\n"):
return value.rstrip("\n").split("\n")
else:
return value
def get_keys(self, key=None):
"""
Returns a list of valid sub-keys.
"""
if key:
value = _lxc.Container.get_keys(self, key)
else:
value = _lxc.Container.get_keys(self)
if value is False:
return False
elif value.endswith("\n"):
return value.rstrip("\n").split("\n")
else:
return value
def get_interfaces(self):
"""
Get a tuple of interfaces for the container.
"""
return _lxc.Container.get_interfaces(self)
def get_ips(self, interface=None, family=None, scope=None, timeout=0):
"""
Get a tuple of IPs for the container.
"""
kwargs = {}
if interface:
kwargs['interface'] = interface
if family:
kwargs['family'] = family
if scope:
kwargs['scope'] = scope
ips = None
timeout = int(os.environ.get('LXC_GETIP_TIMEOUT', timeout))
while not ips:
ips = _lxc.Container.get_ips(self, **kwargs)
if timeout == 0:
break
timeout -= 1
time.sleep(1)
return ips
def rename(self, new_name):
"""
Rename the container.
On success, returns the new Container object.
On failure, returns False.
"""
if _lxc.Container.rename(self, new_name):
return Container(new_name)
return False
def set_config_item(self, key, value):
"""
Set a config key to a provided value.
The value can be a list for the keys supporting multiple values.
"""
try:
old_value = self.get_config_item(key)
except KeyError:
old_value = None
# Check if it's a list
def set_key(key, value):
self.clear_config_item(key)
if isinstance(value, list):
for entry in value:
if not _lxc.Container.set_config_item(self, key, entry):
return False
else:
_lxc.Container.set_config_item(self, key, value)
set_key(key, value)
new_value = self.get_config_item(key)
# loglevel is special and won't match the string we set
if key == "lxc.log.level":
new_value = value
if (isinstance(value, str) and isinstance(new_value, str) and
value == new_value):
return True
elif (isinstance(value, list) and isinstance(new_value, list) and
set(value) == set(new_value)):
return True
elif (isinstance(value, str) and isinstance(new_value, list) and
set([value]) == set(new_value)):
return True
elif old_value:
set_key(key, old_value)
return False
else:
self.clear_config_item(key)
return False
def wait(self, state, timeout=-1):
"""
Wait for the container to reach a given state or timeout.
"""
if isinstance(state, str):
state = state.upper()
return _lxc.Container.wait(self, state, timeout)
def list_containers(active=True, defined=True,
as_object=False, config_path=None):
"""
List the containers on the system.
"""
if config_path:
if not os.path.exists(config_path):
return tuple()
try:
entries = _lxc.list_containers(active=active, defined=defined,
config_path=config_path)
except ValueError:
return tuple()
else:
try:
entries = _lxc.list_containers(active=active, defined=defined)
except ValueError:
return tuple()
if as_object:
return tuple([Container(name, config_path) for name in entries])
else:
return entries
def attach_run_command(cmd):
"""
Run a command when attaching
Please do not call directly, this will execvp the command.
This is to be used in conjunction with the attach method
of a container.
"""
if isinstance(cmd, tuple):
return _lxc.attach_run_command(cmd)
elif isinstance(cmd, list):
return _lxc.attach_run_command((cmd[0], cmd))
else:
return _lxc.attach_run_command((cmd, [cmd]))
def attach_run_shell():
"""
Run a shell when attaching
Please do not call directly, this will execvp the shell.
This is to be used in conjunction with the attach method
of a container.
"""
return _lxc.attach_run_shell(None)
def arch_to_personality(arch):
"""
Determine the process personality corresponding to the architecture
"""
if isinstance(arch, bytes):
arch = str(arch, 'utf-8')
return _lxc.arch_to_personality(arch)
# namespace flags (no other python lib exports this)
CLONE_NEWIPC = _lxc.CLONE_NEWIPC
CLONE_NEWNET = _lxc.CLONE_NEWNET
CLONE_NEWNS = _lxc.CLONE_NEWNS
CLONE_NEWPID = _lxc.CLONE_NEWPID
CLONE_NEWUSER = _lxc.CLONE_NEWUSER
CLONE_NEWUTS = _lxc.CLONE_NEWUTS
# attach: environment variable handling
LXC_ATTACH_CLEAR_ENV = _lxc.LXC_ATTACH_CLEAR_ENV
LXC_ATTACH_KEEP_ENV = _lxc.LXC_ATTACH_KEEP_ENV
# attach: attach options
LXC_ATTACH_DEFAULT = _lxc.LXC_ATTACH_DEFAULT
LXC_ATTACH_DROP_CAPABILITIES = _lxc.LXC_ATTACH_DROP_CAPABILITIES
LXC_ATTACH_LSM_EXEC = _lxc.LXC_ATTACH_LSM_EXEC
LXC_ATTACH_LSM_NOW = _lxc.LXC_ATTACH_LSM_NOW
LXC_ATTACH_MOVE_TO_CGROUP = _lxc.LXC_ATTACH_MOVE_TO_CGROUP
LXC_ATTACH_REMOUNT_PROC_SYS = _lxc.LXC_ATTACH_REMOUNT_PROC_SYS
LXC_ATTACH_SET_PERSONALITY = _lxc.LXC_ATTACH_SET_PERSONALITY
# clone: clone flags
LXC_CLONE_KEEPBDEVTYPE = _lxc.LXC_CLONE_KEEPBDEVTYPE
LXC_CLONE_KEEPMACADDR = _lxc.LXC_CLONE_KEEPMACADDR
LXC_CLONE_KEEPNAME = _lxc.LXC_CLONE_KEEPNAME
LXC_CLONE_MAYBE_SNAPSHOT = _lxc.LXC_CLONE_MAYBE_SNAPSHOT
LXC_CLONE_SNAPSHOT = _lxc.LXC_CLONE_SNAPSHOT
# create: create flags
LXC_CREATE_QUIET = _lxc.LXC_CREATE_QUIET

View File

@ -1,89 +0,0 @@
#!/usr/bin/env python3
#
# python-lxc: Python bindings for LXC
#
# (C) Copyright Canonical Ltd. 2012
#
# Authors:
# Stéphane Graber <stgraber@ubuntu.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
# USA
import os
import subprocess
# Fix build when PIE is enabled (must run before setuptools import)
for var in ("LDFLAGS", "CFLAGS"):
current = os.environ.get(var, None)
if not current:
continue
new = []
for flag in current.split(" "):
if flag.lower() in ("-pie", "-fpie"):
if "-fPIC" not in new:
new.append("-fPIC")
continue
new.append(flag)
os.environ[var] = " ".join(new)
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as BuildExtCommand
class LxcBuildExtCommand(BuildExtCommand):
user_options = BuildExtCommand.user_options + [
('no-pkg-config', None,
"don't use pkg-config to detect include/library paths")
]
def initialize_options(self):
super(LxcBuildExtCommand, self).initialize_options()
self.no_pkg_config = False
def build_extensions(self):
if not self.no_pkg_config:
pkg_config_executable = os.environ.get('PKG_CONFIG_EXECUTABLE',
'pkg-config')
def get_pkg_config_var(name):
args = [pkg_config_executable, '--variable', name, 'lxc']
output = subprocess.check_output(args,
universal_newlines=True)
return output.rstrip('\n')
try:
includedir = get_pkg_config_var('includedir')
libdir = get_pkg_config_var('libdir')
self.compiler.add_include_dir(includedir)
self.compiler.add_library_dir(libdir)
except subprocess.CalledProcessError:
pass
super(LxcBuildExtCommand, self).build_extensions()
setup(name='lxc',
version='0.1',
description='LXC',
packages=['lxc'],
package_dir={'lxc': 'lxc'},
ext_modules=[Extension('_lxc', sources=['lxc.c'], libraries=['lxc'])],
cmdclass={'build_ext': LxcBuildExtCommand},
)