Source code for craft_providers.multipass.installer

#
# 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
import shutil
import subprocess
import sys
import time

from craft_providers.errors import details_from_called_process_error

from . import errors
from .multipass import Multipass

logger = logging.getLogger(__name__)


[docs]def install() -> str: """Install Multipass. :returns: Multipass version. :raises MultipassInstallationError: on error. """ if sys.platform == "darwin": _install_darwin() elif sys.platform == "linux": _install_linux() elif sys.platform == "win32": raise errors.MultipassInstallationError( "automated installation not yet supported for Windows" ) else: raise errors.MultipassInstallationError( f"unsupported platform {sys.platform!r}" ) # TODO: Multipass needs time after being installed or errors could happen on # launch, i.e.: "Remote "" is unknown or unreachable." Current guidance is # to sleep 20 seconds after install, but we should have a more reliable and # timely approach. See: https://github.com/canonical/multipass/issues/1995 time.sleep(20) multipass_version, _ = Multipass().wait_until_ready() return multipass_version
def _install_darwin() -> None: try: subprocess.run(["brew", "install", "multipass"], check=True) except subprocess.CalledProcessError as error: raise errors.MultipassInstallationError( "error during brew installation", details=details_from_called_process_error(error), ) from error def _install_linux() -> None: try: subprocess.run(["sudo", "snap", "install", "multipass"], check=True) except subprocess.CalledProcessError as error: raise errors.MultipassInstallationError( "error during snap installation", details=details_from_called_process_error(error), ) from error
[docs]def is_installed() -> bool: """Check if Multipass is installed (and found on PATH). :returns: True if multipass is installed. """ return shutil.which("multipass") is not None