On Tue, Mar 04, 2014 at 04:23:04PM -0600, Serge Hallyn wrote: > Quoting Stéphane Graber ([email protected]): > > 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 <[email protected]> > > One change below, > > Acked-by: Serge E. Hallyn <[email protected]> > > ... > > > +# 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'.
Oops, yeah, I actually fixed this locally but forgot to commit... what I did here is drop the print() entirely as it's redundant with what LXC will print anyway and replace the pass with continue. > > > + > > + if container.controllable: > > + state = container.state > > + else: > > + state = 'UNKNOWN' > > + > > + # Filter by status > > + if args.state and state not in args.state: > > + continue > _______________________________________________ > lxc-devel mailing list > [email protected] > http://lists.linuxcontainers.org/listinfo/lxc-devel -- Stéphane Graber Ubuntu developer http://www.ubuntu.com
signature.asc
Description: Digital signature
_______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
