Create a new container.

    name
        Name of the container

    config
        The config file to use for the container. Defaults to system-wide
        config (usually in /etc/lxc/lxc.conf).

    profile
        Profile to use in container creation (see
        :mod:`lxc.get_container_profile
        <salt.modules.lxc.get_container_profile>`). Values in a profile will be
        overridden by the **Container Creation Arguments** listed below.

    network_profile
        Network profile to use for container

        .. versionadded:: 2015.5.0

    **Container Creation Arguments**

    template
        The template to use. For example, ``ubuntu`` or ``fedora``.
        For a full list of available templates, check out
        the :mod:`lxc.templates <salt.modules.lxc.templates>` function.

        Conflicts with the ``image`` argument.

        .. note::

            The ``download`` template requires the following three parameters
            to be defined in ``options``:

            * **dist** - The name of the distribution
            * **release** - Release name/version
            * **arch** - Architecture of the container

            The available images can be listed using the :mod:`lxc.images
            <salt.modules.lxc.images>` function.

    options
        Template-specific options to pass to the lxc-create command. These
        correspond to the long options (ones beginning with two dashes) that
        the template script accepts. For example:

        .. code-block:: bash

            options='{"dist": "centos", "release": "6", "arch": "amd64"}'

        For available template options, refer to the lxc template scripts
        which are ususally located under ``/usr/share/lxc/templates``,
        or run ``lxc-create -t <template> -h``.

    image
        A tar archive to use as the rootfs for the container. Conflicts with
        the ``template`` argument.

    backing
        The type of storage to use. Set to ``lvm`` to use an LVM group.
        Defaults to filesystem within /var/lib/lxc.

    fstype
        Filesystem type to use on LVM logical volume

    size : 1G
        Size of the volume to create. Only applicable if ``backing=lvm``.

    vgname : lxc
        Name of the LVM volume group in which to create the volume for this
        container. Only applicable if ``backing=lvm``.

    lvname
        Name of the LVM logical volume in which to create the volume for this
        container. Only applicable if ``backing=lvm``.

    thinpool
        Name of a pool volume that will be used for thin-provisioning this
        container. Only applicable if ``backing=lvm``.

    nic_opts
        give extra opts overriding network profile values

    path
        parent path for the container creation (default: /var/lib/lxc)

    zfsroot
        Name of the ZFS root in which to create the volume for this container.
        Only applicable if ``backing=zfs``. (default: tank/lxc)

        .. versionadded:: 2015.8.0

def create(name,
           config=None,
           profile=None,
           network_profile=None,
           nic_opts=None,
           **kwargs):
    '''
    Create a new container.

    name
        Name of the container

    config
        The config file to use for the container. Defaults to system-wide
        config (usually in /etc/lxc/lxc.conf).

    profile
        Profile to use in container creation (see
        :mod:`lxc.get_container_profile
        <salt.modules.lxc.get_container_profile>`). Values in a profile will be
        overridden by the **Container Creation Arguments** listed below.

    network_profile
        Network profile to use for container

        .. versionadded:: 2015.5.0

    **Container Creation Arguments**

    template
        The template to use. For example, ``ubuntu`` or ``fedora``.
        For a full list of available templates, check out
        the :mod:`lxc.templates <salt.modules.lxc.templates>` function.

        Conflicts with the ``image`` argument.

        .. note::

            The ``download`` template requires the following three parameters
            to be defined in ``options``:

            * **dist** - The name of the distribution
            * **release** - Release name/version
            * **arch** - Architecture of the container

            The available images can be listed using the :mod:`lxc.images
            <salt.modules.lxc.images>` function.

    options
        Template-specific options to pass to the lxc-create command. These
        correspond to the long options (ones beginning with two dashes) that
        the template script accepts. For example:

        .. code-block:: bash

            options='{"dist": "centos", "release": "6", "arch": "amd64"}'

        For available template options, refer to the lxc template scripts
        which are ususally located under ``/usr/share/lxc/templates``,
        or run ``lxc-create -t <template> -h``.

    image
        A tar archive to use as the rootfs for the container. Conflicts with
        the ``template`` argument.

    backing
        The type of storage to use. Set to ``lvm`` to use an LVM group.
        Defaults to filesystem within /var/lib/lxc.

    fstype
        Filesystem type to use on LVM logical volume

    size : 1G
        Size of the volume to create. Only applicable if ``backing=lvm``.

    vgname : lxc
        Name of the LVM volume group in which to create the volume for this
        container. Only applicable if ``backing=lvm``.

    lvname
        Name of the LVM logical volume in which to create the volume for this
        container. Only applicable if ``backing=lvm``.

    thinpool
        Name of a pool volume that will be used for thin-provisioning this
        container. Only applicable if ``backing=lvm``.

    nic_opts
        give extra opts overriding network profile values

    path
        parent path for the container creation (default: /var/lib/lxc)

    zfsroot
        Name of the ZFS root in which to create the volume for this container.
        Only applicable if ``backing=zfs``. (default: tank/lxc)

        .. versionadded:: 2015.8.0
    '''
    # Required params for 'download' template
    download_template_deps = ('dist', 'release', 'arch')

    cmd = 'lxc-create -n {0}'.format(name)

    profile = get_container_profile(copy.deepcopy(profile))
    kw_overrides = copy.deepcopy(kwargs)

    def select(key, default=None):
        kw_overrides_match = kw_overrides.pop(key, None)
        profile_match = profile.pop(key, default)
        # Return the profile match if the the kwarg match was None, as the
        # lxc.present state will pass these kwargs set to None by default.
        if kw_overrides_match is None:
            return profile_match
        return kw_overrides_match

    path = select('path')
    if exists(name, path=path):
        raise CommandExecutionError(
            'Container \'{0}\' already exists'.format(name)
        )

    tvg = select('vgname')
    vgname = tvg if tvg else __salt__['config.get']('lxc.vgname')

    # The 'template' and 'image' params conflict
    template = select('template')
    image = select('image')
    if template and image:
        raise SaltInvocationError(
            'Only one of \'template\' and \'image\' is permitted'
        )
    elif not any((template, image, profile)):
        raise SaltInvocationError(
            'At least one of \'template\', \'image\', and \'profile\' is '
            'required'
        )

    options = select('options') or {}
    backing = select('backing')
    if vgname and not backing:
        backing = 'lvm'
    lvname = select('lvname')
    thinpool = select('thinpool')
    fstype = select('fstype')
    size = select('size', '1G')
    zfsroot = select('zfsroot')
    if backing in ('dir', 'overlayfs', 'btrfs', 'zfs'):
        fstype = None
        size = None
    # some backends won't support some parameters
    if backing in ('aufs', 'dir', 'overlayfs', 'btrfs'):
        lvname = vgname = thinpool = None

    if image:
        img_tar = __salt__['cp.cache_file'](image)
        template = os.path.join(
                os.path.dirname(salt.__file__),
                'templates',
                'lxc',
                'salt_tarball')
        options['imgtar'] = img_tar
    if path:
        cmd += ' -P {0}'.format(pipes.quote(path))
        if not os.path.exists(path):
            os.makedirs(path)
    if config:
        cmd += ' -f {0}'.format(config)
    if template:
        cmd += ' -t {0}'.format(template)
    if backing:
        backing = backing.lower()
        cmd += ' -B {0}'.format(backing)
        if backing in ('zfs',):
            if zfsroot:
                cmd += ' --zfsroot {0}'.format(zfsroot)
        if backing in ('lvm',):
            if lvname:
                cmd += ' --lvname {0}'.format(lvname)
            if vgname:
                cmd += ' --vgname {0}'.format(vgname)
            if thinpool:
                cmd += ' --thinpool {0}'.format(thinpool)
        if backing not in ('dir', 'overlayfs'):
            if fstype:
                cmd += ' --fstype {0}'.format(fstype)
            if size:
                cmd += ' --fssize {0}'.format(size)

    if options:
        if template == 'download':
            missing_deps = [x for x in download_template_deps
                            if x not in options]
            if missing_deps:
                raise SaltInvocationError(
                    'Missing params in \'options\' dict: {0}'
                    .format(', '.join(missing_deps))
                )
        cmd += ' --'
        for key, val in six.iteritems(options):
            cmd += ' --{0} {1}'.format(key, val)

    ret = __salt__['cmd.run_all'](cmd, python_shell=False)
    # please do not merge extra conflicting stuff
    # inside those two line (ret =, return)
    return _after_ignition_network_profile(cmd,
                                           ret,
                                           name,
                                           network_profile,
                                           path,
                                           nic_opts)