Source code for datalad_container.containers_remove

"""Remove a container environment from a dataset"""

__docformat__ = 'restructuredtext'

import logging
import os.path as op

from datalad.distribution.dataset import (
    EnsureDataset,
    datasetmethod,
    require_dataset,
)
from datalad.interface.base import (
    Interface,
    build_doc,
    eval_results,
)
from datalad.interface.results import get_status_dict
from datalad.support.constraints import (
    EnsureNone,
    EnsureStr,
)
from datalad.support.param import Parameter
from datalad.utils import rmtree

from datalad_container.utils import get_container_configuration

lgr = logging.getLogger("datalad.containers.containers_remove")


[docs] @build_doc # all commands must be derived from Interface class ContainersRemove(Interface): # first docstring line is used a short description in the cmdline help # the rest is put in the verbose help and manpage """Remove a known container from a dataset This command is only removing a container from the committed Dataset configuration (configuration scope ``branch``). It will not modify any other configuration scopes. This command is *not* dropping the container image associated with the removed record, because it may still be needed for other dataset versions. In order to drop the container image, use the 'drop' command prior to removing the container configuration. """ # parameters of the command, must be exhaustive _params_ = dict( dataset=Parameter( args=("-d", "--dataset"), doc="""specify the dataset from removing a container. If no dataset is given, an attempt is made to identify the dataset based on the current working directory""", constraints=EnsureDataset() | EnsureNone()), name=Parameter( args=("name",), doc="""name of the container to remove""", metavar="NAME", constraints=EnsureStr(), ), remove_image=Parameter( args=("-i", "--remove-image",), doc="""if set, remove container image as well. Even with this flag, the container image content will not be dropped. Use the 'drop' command explicitly before removing the container configuration.""", action="store_true", ), ) @staticmethod @datasetmethod(name='containers_remove') @eval_results def __call__(name, dataset=None, remove_image=False): ds = require_dataset(dataset, check_installed=True, purpose='remove a container') res = get_status_dict( ds=ds, action='containers_remove', logger=lgr) container_cfg = get_container_configuration(ds, name) to_save = [] if remove_image and 'image' in container_cfg: imagepath = ds.pathobj / container_cfg['image'] # we use rmtree() and not .unlink(), because # the image could be more than a single file underneath # this location (e.g., docker image dumps) rmtree(imagepath) # at the very end, save() will take care of committing # any removal that just occurred to_save.append(imagepath) if container_cfg: ds.config.remove_section( f'datalad.containers.{name}', scope='branch', reload=True) res['status'] = 'ok' to_save.append(op.join('.datalad', 'config')) else: res['status'] = 'notneeded' if to_save: for r in ds.save( path=to_save, message='[DATALAD] Remove container {}'.format(name)): yield r yield res