#
# Copyright 2021 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program 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 program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
"""Multipass Provider."""
import logging
from craft_providers import Base, bases
from .multipass_instance import MultipassInstance
logger = logging.getLogger(__name__)
[docs]def launch(
name: str,
*,
base_configuration: Base,
image_name: str,
cpus: int = 2,
disk_gb: int = 64,
mem_gb: int = 2,
auto_clean: bool = False,
) -> MultipassInstance:
"""Create, start, and configure instance.
If auto_clean is enabled, automatically delete an existing instance that is
deemed to be incompatible, rebuilding it with the specified environment.
:param name: Name of instance.
:param base_configuration: Base configuration to apply to instance.
:param image_name: Multipass image to use, e.g. snapcraft:core20.
:param cpus: Number of CPUs.
:param disk_gb: Disk allocation in gigabytes.
:param mem_gb: Memory allocation in gigabytes.
:param auto_clean: Automatically clean instance, if incompatible.
:returns: Multipass instance.
:raises BaseConfigurationError: on unexpected error configuration base.
:raises MultipassError: on unexpected Multipass error.
"""
instance = MultipassInstance(name=name)
if instance.exists():
# TODO: Warn if existing instance doesn't match cpu/disk/mem specs.
instance.start()
try:
base_configuration.warmup(executor=instance)
return instance
except bases.BaseCompatibilityError as error:
if auto_clean:
logger.debug(
"Cleaning incompatible instance %r (reason: %s).",
instance.name,
error.reason,
)
instance.delete()
else:
raise
instance.launch(
cpus=cpus,
disk_gb=disk_gb,
mem_gb=mem_gb,
image=image_name,
)
base_configuration.setup(executor=instance)
return instance