Merge pull request #793 from stgraber/master

Remove legacy versions of lxc-ls
This commit is contained in:
Christian Brauner 2016-02-02 11:45:30 +00:00
commit 57e40de3bd
12 changed files with 4 additions and 1145 deletions

4
.gitignore vendored
View File

@ -62,7 +62,6 @@ src/lxc/lxc-unfreeze
src/lxc/lxc-unshare
src/lxc/lxc-usernsexec
src/lxc/lxc-wait
src/lxc/legacy/lxc-ls
src/lxc/lxc-user-nic
src/lxc/version.h
@ -121,12 +120,9 @@ doc/*.7
doc/ja/*.1
doc/ja/*.5
doc/ja/*.7
doc/ja/legacy/*.1
doc/legacy/*.1
doc/ko/*.1
doc/ko/*.5
doc/ko/*.7
doc/ko/legacy/*.1
doc/manpage.links
doc/manpage.refs
doc/api/html/*

View File

@ -685,7 +685,6 @@ AC_CONFIG_FILES([
doc/Makefile
doc/api/Makefile
doc/legacy/lxc-ls.sgml
doc/lxc-attach.sgml
doc/lxc-autostart.sgml
doc/lxc-cgroup.sgml
@ -734,7 +733,6 @@ AC_CONFIG_FILES([
doc/examples/lxc-complex.conf
doc/ja/Makefile
doc/ja/legacy/lxc-ls.sgml
doc/ja/lxc-attach.sgml
doc/ja/lxc-autostart.sgml
doc/ja/lxc-cgroup.sgml
@ -772,7 +770,6 @@ AC_CONFIG_FILES([
doc/ja/see_also.sgml
doc/ko/Makefile
doc/ko/legacy/lxc-ls.sgml
doc/ko/lxc-attach.sgml
doc/ko/lxc-autostart.sgml
doc/ko/lxc-cgroup.sgml
@ -835,9 +832,7 @@ AC_CONFIG_FILES([
src/Makefile
src/lxc/Makefile
src/lxc/lxc-checkconfig
src/lxc/lxc-ls
src/lxc/lxc-start-ephemeral
src/lxc/legacy/lxc-ls
src/lxc/lxc.functions
src/lxc/version.h
src/python-lxc/Makefile

View File

@ -31,6 +31,7 @@ man_MANS = \
lxc-execute.1 \
lxc-freeze.1 \
lxc-info.1 \
lxc-ls.1 \
lxc-monitor.1 \
lxc-snapshot.1 \
lxc-start.1 \
@ -50,10 +51,7 @@ man_MANS = \
lxc.7
if ENABLE_PYTHON
man_MANS += lxc-ls.1
man_MANS += lxc-start-ephemeral.1
else
man_MANS += legacy/lxc-ls.1
endif
%.1 : %.sgml

View File

@ -23,6 +23,7 @@ man_MANS = \
lxc-execute.1 \
lxc-freeze.1 \
lxc-info.1 \
lxc-ls.1 \
lxc-monitor.1 \
lxc-snapshot.1 \
lxc-start.1 \
@ -42,10 +43,7 @@ man_MANS = \
lxc.7
if ENABLE_PYTHON
man_MANS += lxc-ls.1
man_MANS += lxc-start-ephemeral.1
else
man_MANS += legacy/lxc-ls.1
endif
%.1 : %.sgml

View File

@ -1,176 +0,0 @@
<!--
lxc: linux Container library
(C) Copyright IBM Corp. 2007, 2008
Authors:
Daniel Lezcano <dlezcano at fr.ibm.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
Translated into Japanese
by KATOH Yasufumi <karma at jazz.email.ne.jp>
-->
<!DOCTYPE refentry PUBLIC @docdtd@ [
<!ENTITY seealso SYSTEM "@builddir@/../see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-ls</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-ls</refname>
<refpurpose>
<!--
list the containers existing on the system
-->
システム上に存在するコンテナをリスト表示する。
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-ls</command>
<arg choice="opt">--active</arg>
<arg choice="opt">ls option</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title><!-- Description -->説明</title>
<para>
<!--
<command>lxc-ls</command> list the containers existing on the
system.
-->
<command>lxc-ls</command> はシステム上に存在するコンテナをリスト表示します。
</para>
</refsect1>
<refsect1>
<title><!-- Options -->オプション</title>
<variablelist>
<varlistentry>
<term>
<option><optional>--active</optional></option>
</term>
<listitem>
<para>
<!--
List active containers.
-->
稼働中のコンテナをリスト表示します。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>ls options</optional></option>
</term>
<listitem>
<para>
<!--
The option passed to <command>lxc-ls</command> are the
same as the <command>ls</command> command.
-->
<command>lxc-ls</command> が受け付けるオプションは、<command>ls</command> コマンドと同じです。
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title><!-- Examples -->例</title>
<variablelist>
<varlistentry>
<term>lxc-ls -l</term>
<listitem>
<para>
<!--
list all the container and their permissions.
-->
全てのコンテナとそのパーミッションをリスト表示します。
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>lxc-ls --active -1</term>
<listitem>
<para>
<!--
list active containers and display the list in one column.
-->
稼働中のコンテナを一列にリスト表示します。
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<simpara>
<citerefentry>
<refentrytitle>ls</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
</simpara>
</refsect1>
&seealso;
<refsect1>
<title><!-- Author -->作者</title>
<para>Daniel Lezcano <email>daniel.lezcano@free.fr</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

View File

@ -23,6 +23,7 @@ man_MANS = \
lxc-execute.1 \
lxc-freeze.1 \
lxc-info.1 \
lxc-ls.1 \
lxc-monitor.1 \
lxc-snapshot.1 \
lxc-start.1 \
@ -42,10 +43,7 @@ man_MANS = \
lxc.7
if ENABLE_PYTHON
man_MANS += lxc-ls.1
man_MANS += lxc-start-ephemeral.1
else
man_MANS += legacy/lxc-ls.1
endif
%.1 : %.sgml

View File

@ -1,176 +0,0 @@
<!--
lxc: linux Container library
(C) Copyright IBM Corp. 2007, 2008
Authors:
Daniel Lezcano <dlezcano at fr.ibm.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
Translated into Korean
by Sungbae Yoo <sungbae.yoo at samsung.com>
-->
<!DOCTYPE refentry PUBLIC @docdtd@ [
<!ENTITY seealso SYSTEM "@builddir@/../see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-ls</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-ls</refname>
<refpurpose>
<!--
list the containers existing on the system
-->
시스템 내에 존재하는 컨테이너들의 리스트 표시
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-ls</command>
<arg choice="opt">--active</arg>
<arg choice="opt">ls option</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title><!-- Description -->설명</title>
<para>
<!--
<command>lxc-ls</command> list the containers existing on the
system.
-->
<command>lxc-ls</command>는 시스템 내에 존재하는 컨테이너들의 리스트를 표시한다.
</para>
</refsect1>
<refsect1>
<title><!-- Options -->옵션</title>
<variablelist>
<varlistentry>
<term>
<option><optional>--active</optional></option>
</term>
<listitem>
<para>
<!--
List active containers.
-->
동작 중인 컨테이너들의 리스트를 표시한다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>ls options</optional></option>
</term>
<listitem>
<para>
<!--
The option passed to <command>lxc-ls</command> are the
same as the <command>ls</command> command.
-->
<command>lxc-ls</command>에는 <command>ls</command>와 같은 옵션을 사용할 수 있다.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title><!-- Examples -->예제</title>
<variablelist>
<varlistentry>
<term>lxc-ls -l</term>
<listitem>
<para>
<!--
list all the container and their permissions.
-->
모든 컨테이너들의 리스트와 그들의 퍼미션 정보를 표시한다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>lxc-ls --active -1</term>
<listitem>
<para>
<!--
list active containers and display the list in one column.
-->
동작 중인 컨테이너들의 리스트를 1열로 표시한다.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title><!-- See Also -->참조</title>
<simpara>
<citerefentry>
<refentrytitle>ls</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
</simpara>
</refsect1>
&seealso;
<refsect1>
<title><!-- Author -->저자</title>
<para>Daniel Lezcano <email>daniel.lezcano@free.fr</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

View File

@ -1,156 +0,0 @@
<!--
lxc: linux Container library
(C) Copyright IBM Corp. 2007, 2008
Authors:
Daniel Lezcano <dlezcano at fr.ibm.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
-->
<!DOCTYPE refentry PUBLIC @docdtd@ [
<!ENTITY seealso SYSTEM "@builddir@/../see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-ls</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-ls</refname>
<refpurpose>
list the containers existing on the system
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-ls</command>
<arg choice="opt">--active</arg>
<arg choice="opt"><replaceable>ls options</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-ls</command> list the containers existing on the
system.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option><optional>--active</optional></option>
</term>
<listitem>
<para>
List active containers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional><replaceable>ls options</replaceable></optional></option>
</term>
<listitem>
<para>
The option passed to <command>lxc-ls</command> are the
same as the <command>ls</command> command.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<variablelist>
<varlistentry>
<term>lxc-ls -l</term>
<listitem>
<para>
list all the container and their permissions.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>lxc-ls --active -1</term>
<listitem>
<para>
list active containers and display the list in one column.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<simpara>
<citerefentry>
<refentrytitle>ls</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
</simpara>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Daniel Lezcano <email>daniel.lezcano@free.fr</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

View File

@ -190,14 +190,10 @@ endif
bin_SCRIPTS = lxc-checkconfig
EXTRA_DIST = \
lxc-ls \
lxc-top.lua
if ENABLE_PYTHON
bin_SCRIPTS += lxc-ls
bin_SCRIPTS += lxc-start-ephemeral
else
bin_SCRIPTS += legacy/lxc-ls
endif
bin_PROGRAMS = \

View File

@ -1,99 +0,0 @@
#!/bin/sh
#
# lxc: linux Container library
# 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
. @DATADIR@/lxc/lxc.functions
usage()
{
echo "usage: $(basename $0) [--active] [--] [LS_OPTIONS...]" >&2
}
help() {
usage
echo >&2
echo "List containers existing on the system." >&2
echo >&2
echo " --active list active containers" >&2
echo " LS_OPTIONS ls command options (see \`ls --help')" >&2
}
get_parent_cgroup()
{
parent_cgroup=""
# Obtain a list of hierarchies that contain one or more subsystems
hierarchies=$(tail -n +2 /proc/cgroups | cut -f 2)
# Iterate through the list until a suitable hierarchy is found
for hierarchy in $hierarchies; do
# Obtain information about the init process in the hierarchy
fields=$(grep -E "^$hierarchy:" /proc/1/cgroup | head -n 1)
if [ -z "$fields" ]; then continue; fi
fields=${fields#*:}
# Get a comma-separated list of the hierarchy's subsystems
subsystems=${fields%:*}
# Get the cgroup of the init process in the hierarchy
init_cgroup=${fields#*:}
# Get the filesystem mountpoint of the hierarchy
mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \
'$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts)
if [ -z "$mountpoint" ]; then continue; fi
# Return the absolute path to the containers' parent cgroup
# (do not append '/lxc' if the hierarchy contains the 'ns' subsystem)
case ",$subsystems," in
*,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";;
*) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";;
esac
break
done
}
directory=$(readlink -f "$lxc_path")
for i in "$@"; do
case $i in
--help)
help; exit;;
--active)
get_parent_cgroup; directory="$parent_cgroup"; shift;;
--)
shift; break;;
*)
break;;
esac
done
containers=""
if [ ! -z "$directory" ]; then
if [ x"$parent_cgroup" = x ]; then
containers=$(find -L $directory -mindepth 2 -maxdepth 2 -name config -type f |awk -F "/" '{print $(NF-1)}')
else
containers=$(find $directory -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')
fi
if [ x"$containers" = x ]; then
exit 0
fi
fi
cd "$directory"
ls -d $@ -- $containers

View File

@ -1,515 +0,0 @@
#!/usr/bin/env python3
#
# lxc-ls: List containers
#
# This python implementation is based on the work done in the original
# shell implementation done by Serge Hallyn in Ubuntu (and other contributors)
#
# (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 argparse
import gettext
import json
import lxc
import os
import re
import shutil
import tempfile
import sys
_ = gettext.gettext
gettext.textdomain("lxc-ls")
# Required for containers without python
import encodings.ascii
assert encodings.ascii
# Constants
LXCPATH = "@LXCPATH@"
RUNTIME_PATH = "@RUNTIME_PATH@"
# Functions used later on
def batch(iterable, cols=1):
import math
length = len(iterable)
lines = math.ceil(length / cols)
for line in range(lines):
fields = []
for col in range(cols):
index = line + (col * lines)
if index < length:
fields.append(iterable[index])
yield fields
def get_terminal_size():
import os
env = os.environ
def ioctl_GWINSZ(fd):
try:
import fcntl
import termios
import struct
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
'1234'))
return cr
except:
return
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
return int(cr[1]), int(cr[0])
def get_root_path(path):
lxc_path = LXCPATH
global_conf = "%s/etc/lxc/lxc.conf" % path
if os.path.exists(global_conf):
with open(global_conf, "r") as fd:
for line in fd:
if line.startswith("lxc.lxcpath"):
lxc_path = line.split("=")[-1].strip()
break
return lxc_path
# Constants
FIELDS = ("name", "state", "interfaces", "ipv4", "ipv6", "autostart", "pid",
"memory", "ram", "swap", "groups")
DEFAULT_FIELDS = ("name", "state", "ipv4", "ipv6", "groups", "autostart")
# Begin parsing the command line
parser = argparse.ArgumentParser(description=_("LXC: List containers"),
formatter_class=argparse.RawTextHelpFormatter,
epilog=_("""Valid fancy-format fields:
%s
Default fancy-format fields:
%s\n""" % (", ".join(FIELDS), ", ".join(DEFAULT_FIELDS))))
parser.add_argument("-1", dest="one", action="store_true",
help=_("list one container per line (default when piped)"))
parser.add_argument("-P", "--lxcpath", dest="lxcpath", metavar="PATH",
help=_("Use specified container path"),
default=lxc.default_config_path)
parser.add_argument("--active", action="store_true",
help=_("list only active containers"))
parser.add_argument("--frozen", dest="state", action="append_const",
const="FROZEN", help=_("list only frozen containers"))
parser.add_argument("--running", dest="state", action="append_const",
const="RUNNING", help=_("list only running containers"))
parser.add_argument("--stopped", dest="state", action="append_const",
const="STOPPED", help=_("list only stopped containers"))
parser.add_argument("-f", "--fancy", action="store_true",
help=_("use fancy output"))
parser.add_argument("-F", "--fancy-format", type=str,
default=",".join(DEFAULT_FIELDS),
help=_("comma separated list of fields to show"))
parser.add_argument("-g", "--groups", type=str, action="append",
metavar="GROUPS",
help=_("groups (comma separated) the container must "
"be a member of"))
parser.add_argument("--nesting", dest="nesting", action="store_true",
help=_("show nested containers"))
parser.add_argument("filter", metavar='FILTER', type=str, nargs="?",
help=_("regexp to be applied on the container list"))
parser.add_argument("--version", action="version", version=lxc.version)
args = parser.parse_args()
# --active is the same as --running --frozen
if args.active:
if not args.state:
args.state = []
args.state += ["RUNNING", "FROZEN", "UNKNOWN"]
# If the output is piped, default to --one
if not sys.stdout.isatty():
args.one = True
# Turn args.fancy_format into a list
args.fancy_format = args.fancy_format.strip().split(",")
if set(args.fancy_format) - set(FIELDS):
parser.error(_("Invalid field(s): %s" %
", ".join(list(set(args.fancy_format) - set(FIELDS)))))
# Basic checks
## Check for setns
SUPPORT_SETNS = os.path.exists("/proc/self/ns")
SUPPORT_SETNS_NET = False
SUPPORT_SETNS_PID = False
if SUPPORT_SETNS:
SUPPORT_SETNS_NET = os.path.exists("/proc/self/ns/net")
SUPPORT_SETNS_PID = os.path.exists("/proc/self/ns/pid")
## Nesting requires setns to pid and net ns
if args.nesting:
if not SUPPORT_SETNS:
parser.error(_("Showing nested containers requires setns support "
"which your kernel doesn't support."))
if not SUPPORT_SETNS_NET:
parser.error(_("Showing nested containers requires setns to the "
"network namespace which your kernel doesn't support."))
if not SUPPORT_SETNS_PID:
parser.error(_("Showing nested containers requires setns to the "
"PID namespace which your kernel doesn't support."))
# Set the actual lxcpath value
if not args.lxcpath:
args.lxcpath = lxc.default_config_path
# List of containers, stored as dictionaries
def get_containers(fd=None, base="/", root=False):
containers = []
paths = [args.lxcpath]
if not root:
paths.append(get_root_path(base))
# Generate a unique list of valid paths
paths = set([os.path.normpath("%s/%s" % (base, path)) for path in paths])
for path in paths:
if not os.access(path, os.R_OK):
continue
for container_name in lxc.list_containers(config_path=path):
entry = {}
entry['name'] = container_name
# Apply filter
if root and args.filter and \
not re.match(args.filter, container_name):
continue
# Return before grabbing the object (non-root)
if not args.state and not args.fancy and not args.nesting \
and not args.groups:
containers.append(entry)
continue
try:
container = lxc.Container(container_name, path)
except:
continue
if args.groups or "autostart" in args.fancy_format \
or "groups" in args.fancy_format:
try:
groups = container.get_config_item("lxc.group")
except KeyError:
groups = []
if args.groups:
set_has = set(groups)
for group in args.groups:
set_must = set(group.split(","))
if not set_must - set_has:
break
else:
continue
if container.controllable:
state = container.state
else:
state = 'UNKNOWN'
# Filter by status
if args.state and state not in args.state:
continue
# Nothing more is needed if we're not printing some fancy output
if not args.fancy and not args.nesting:
containers.append(entry)
continue
# Some extra field we may want
if 'state' in args.fancy_format:
entry['state'] = state
if 'pid' in args.fancy_format:
entry['pid'] = "-"
if state == 'UNKNOWN':
entry['pid'] = state
elif container.init_pid != -1:
entry['pid'] = str(container.init_pid)
if 'groups' in args.fancy_format:
entry['groups'] = "-"
if len(groups) > 0:
entry['groups'] = ", ".join(groups)
if 'autostart' in args.fancy_format:
entry['autostart'] = "NO"
try:
if container.get_config_item("lxc.start.auto") == "1":
if len(groups) > 0:
entry['autostart'] = "BY-GROUP"
else:
entry['autostart'] = "YES"
except KeyError:
pass
if 'memory' in args.fancy_format or \
'ram' in args.fancy_format or \
'swap' in args.fancy_format:
if container.running:
try:
memory_ram = int(container.get_cgroup_item(
"memory.usage_in_bytes"))
except:
memory_ram = 0
try:
memory_stat = container.get_cgroup_item("memory.stat")
beg = memory_stat.find("\nswap ") + 6
end = memory_stat[beg:].find("\n") + len(memory_stat[:beg])
memory_swap = int(memory_stat[beg:end])
except:
memory_swap = 0
else:
memory_ram = 0
memory_swap = 0
memory_total = memory_ram + memory_swap
if 'memory' in args.fancy_format:
if container.running:
entry['memory'] = "%sMB" % round(memory_total / 1048576, 2)
else:
entry['memory'] = "-"
if 'ram' in args.fancy_format:
if container.running:
entry['ram'] = "%sMB" % round(memory_ram / 1048576, 2)
else:
entry['ram'] = "-"
if 'swap' in args.fancy_format:
if container.running:
entry['swap'] = "%sMB" % round(memory_swap / 1048576, 2)
else:
entry['swap'] = "-"
# Get the IPs
for family, protocol in {'inet': 'ipv4', 'inet6': 'ipv6'}.items():
if protocol in args.fancy_format:
entry[protocol] = "-"
if state == 'UNKNOWN':
entry[protocol] = state
continue
if container.running:
if not SUPPORT_SETNS_NET:
entry[protocol] = 'UNKNOWN'
continue
ips = container.get_ips(family=family)
if ips:
entry[protocol] = ", ".join(ips)
# Get the interfaces
if 'interfaces' in args.fancy_format:
entry['interfaces'] = "-"
if state == 'UNKNOWN' or (container.running and
not SUPPORT_SETNS_NET):
entry['interfaces'] = "UNKNOWN"
elif container.running:
interfaces = container.get_interfaces()
if interfaces:
entry['interfaces'] = ", ".join(interfaces)
# Nested containers
if args.nesting:
if container.running:
# Recursive call in container namespace
temp_fd, temp_file = tempfile.mkstemp()
os.remove(temp_file)
container.attach_wait(get_containers, temp_fd)
json_file = os.fdopen(temp_fd, "r")
json_file.seek(0)
try:
sub_containers = json.loads(json_file.read())
except:
sub_containers = []
json_file.close()
else:
def clear_lock():
try:
lock_path = "%s/lxc/lock/%s/%s" % (RUNTIME_PATH,
path,
entry['name'])
if os.path.exists(lock_path):
if os.path.isdir(lock_path):
shutil.rmtree(lock_path)
else:
os.remove(lock_path)
except:
pass
clear_lock()
# Recursive call using container rootfs
sub_containers = get_containers(
base="%s/%s" % (
base, container.get_config_item("lxc.rootfs")))
clear_lock()
for sub in sub_containers:
if 'nesting_parent' not in sub:
sub['nesting_parent'] = []
sub['nesting_parent'].insert(0, entry['name'])
sub['nesting_real_name'] = sub.get('nesting_real_name',
sub['name'])
sub['name'] = "%s/%s" % (entry['name'], sub['name'])
containers.append(sub)
# Append the container
containers.append(entry)
if fd:
json_file = os.fdopen(fd, "w+")
json_file.write(json.dumps(containers))
return
return containers
containers = get_containers(root=True)
# Print the list
## Standard list with one entry per line
if not args.fancy and args.one:
for container in sorted(containers,
key=lambda container: container['name']):
print(container['name'])
sys.exit(0)
## Standard list with multiple entries per line
if not args.fancy and not args.one:
# Get the longest name and extra simple list
field_maxlength = 0
container_names = []
for container in containers:
if len(container['name']) > field_maxlength:
field_maxlength = len(container['name'])
container_names.append(container['name'])
# Figure out how many we can put per line
width = get_terminal_size()[0]
entries = int(width / (field_maxlength + 2))
if entries == 0:
entries = 1
for line in batch(sorted(container_names), entries):
line_format = ""
for index in range(len(line)):
line_format += "{line[%s]:%s}" % (index, field_maxlength + 2)
print(line_format.format(line=line))
## Fancy listing
if args.fancy:
field_maxlength = {}
# Get the maximum length per field
for field in args.fancy_format:
field_maxlength[field] = len(field)
for container in containers:
for field in args.fancy_format:
if field == 'name' and 'nesting_real_name' in container:
fieldlen = len(" " * ((len(container['nesting_parent']) - 1)
* 4) + " \_ " + container['nesting_real_name'])
if fieldlen > field_maxlength[field]:
field_maxlength[field] = fieldlen
elif len(container[field]) > field_maxlength[field]:
field_maxlength[field] = len(container[field])
# Generate the line format string based on the maximum length and
# a 2 character padding
line_format = ""
index = 0
for field in args.fancy_format:
line_format += "{fields[%s]:%s}" % (index, field_maxlength[field] + 2)
index += 1
# Get the line length minus the padding of the last field
line_length = -2
for field in field_maxlength:
line_length += field_maxlength[field] + 2
# Print header
print(line_format.format(fields=[header.upper()
for header in args.fancy_format]))
print("-" * line_length)
# Print the entries
for container in sorted(containers,
key=lambda container: container['name']):
fields = []
for field in args.fancy_format:
if field == 'name' and 'nesting_real_name' in container:
prefix = " " * ((len(container['nesting_parent']) - 1) * 4)
fields.append(prefix + " \_ " + container['nesting_real_name'])
else:
fields.append(container[field])
print(line_format.format(fields=fields))

View File

@ -291,7 +291,7 @@ int main(int argc, char *argv[])
}
ret = readlink("/proc/self/fd/2", ttyname2, sizeof(ttyname2));
if (ret < 0) {
printf("Warning: unable to open stderr, continueing.");
printf("Warning: unable to open stderr, continuing.");
memset(ttyname2, '\0', sizeof(ttyname2));
}
}