[lxc-devel] [PATCH] lxc-ls: Fix support of --nesting for unpriv
Serge Hallyn
serge.hallyn at ubuntu.com
Tue Mar 4 22:23:04 UTC 2014
Quoting Stéphane Graber (stgraber at ubuntu.com):
> This reworks the way lxc-ls works in nesting mode. In the past it'd use
> attach_wait's subprocess function to call itself in the container's
> namespace, carefully only attaching to the namespaces it needed.
>
> This works great for system containers but not so much as soon as you
> also need to attach to userns. Instead this fix moves all of the
> container listing code into a get_containers function (hence the massive
> diff, sorry), this function is then called recursively.
>
> For running containers, the function is called through attach_wait
> inside the container's namespace, for stopped container, the function is
> simply called recursively with a base path (container's rootfs) in an
> attempt to find containers that way.
> Communication between the parent lxc-ls and the child lxc-ls is done
> through a temporary fd and serialized state using json (similar to what
> was done using stdout in the previous implementation).
>
> As get_global_config_item unfortunately caches the values, there's no
> easy way to figure out what the lxcpath should be for a root container
> when running as non-root, so just use @LXCPATH@ for now and have
> python do the parsing itself.
>
> As a result, the following things now work as expected:
> - listing nested unprivileged containers (root containers inside unpriv)
> - listing nested containers when they're not running
> - filtering containers in nesting mode (only the first level is filtered)
> - copy with invalid config (used to traceback)
>
> Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
One change below,
Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
...
> +# 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:
> + containers.append(entry)
> + continue
> +
> + try:
> + container = lxc.Container(container_name, path)
> + except:
> + print("Invalid container: %s" % conainer_name, file=sys.stderr)
> + pass
I think you meant continue here instead of pass? Otherwise you
will proceed with a bogus 'container'.
> +
> + if container.controllable:
> + state = container.state
> + else:
> + state = 'UNKNOWN'
> +
> + # Filter by status
> + if args.state and state not in args.state:
> + continue
More information about the lxc-devel
mailing list