Skip to content

Commit

Permalink
lifecycle: only warn when a default provider snap is missing (#2885)
Browse files Browse the repository at this point in the history
Snapcraft gained the ability to check for artifacts from snaps listed as plugs
when using the content interface.

The side effect, is that the snap needs to be published on the main Snap Store,
this is a requirement brand stores cannot meet, so instead of failing,
Snapcraft resorts to warning instead.

Signed-off-by: Sergio Schvezov <sergio.schvezov@canonical.com>
  • Loading branch information
sergiusens committed Jan 20, 2020
1 parent f87bd94 commit 2ef3923
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 8 deletions.
21 changes: 15 additions & 6 deletions snapcraft/internal/lifecycle/_runner.py
@@ -1,6 +1,6 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2015-2018 Canonical Ltd
# Copyright (C) 2015-2020 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
Expand Down Expand Up @@ -83,23 +83,32 @@ def execute(
"The repo backend is not returning the list of installed packages"
)

build_snaps = project_config.build_snaps
content_snaps = project_config.project._get_content_snaps()
required_snaps = project_config.build_snaps | content_snaps

if common.is_process_container():
installed_snaps = [] # type: List[str]
if common.is_process_container() and build_snaps:
installed_snaps: List[str] = []
logger.warning(
(
"The following snaps are required but not installed as snapcraft "
"is running inside docker or podman container: {}.\n"
"Please ensure the environment is properly setup before continuing.\n"
"Ignore this message if the appropriate measures have already been taken".format(
", ".join(required_snaps)
", ".join(build_snaps)
)
)
)
else:
installed_snaps = repo.snaps.install_snaps(required_snaps)
installed_snaps = repo.snaps.install_snaps(build_snaps)
for content_snap in content_snaps:
try:
installed_snaps += repo.snaps.install_snaps([content_snap])
except repo.snaps.errors.SnapUnavailableError:
logger.warning(
f"Could not install snap defined in plug {content_snap!r}. "
"The missing library report may have false positives listed if those "
"libraries are provided by the content snap."
)

try:
global_state = states.GlobalState.load(
Expand Down
5 changes: 4 additions & 1 deletion snapcraft/internal/meta/snap.py
@@ -1,6 +1,6 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2019 Canonical Ltd
# Copyright (C) 2019-2020 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
Expand Down Expand Up @@ -119,6 +119,9 @@ def get_provider_content_directories(self) -> Set[str]:
provider_path = common.get_installed_snap_path(provider)
yaml_path = os.path.join(provider_path, "meta", "snap.yaml")

if not os.path.exists(yaml_path):
continue

snap = Snap.from_file(yaml_path)
for slot in snap.get_content_slots():
slot_installed_path = common.get_installed_snap_path(provider)
Expand Down
2 changes: 1 addition & 1 deletion snapcraft/internal/repo/snaps.py
@@ -1,6 +1,6 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2017-2019 Canonical Ltd
# Copyright (C) 2017-2020 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
Expand Down
@@ -0,0 +1,20 @@
name: content-test
version: '0.1'
summary: snap using a plug with a content interface should install
description: |
Defining a plug using the content interface should install the snap
listed under default-provider.
grade: devel
confinement: devmode

plugs:
content-interface:
content: content-interface
interface: content
target: $SNAP/content
default-provider: hello

parts:
empty:
plugin: nil
28 changes: 28 additions & 0 deletions tests/spread/general/content-interface-provider-found/task.yaml
@@ -0,0 +1,28 @@
summary: Build a snap that uses the content interface

environment:
SNAP_DIR: snaps/provider

prepare: |
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
set_base "$SNAP_DIR/snap/snapcraft.yaml"
restore: |
cd "$SNAP_DIR"
snapcraft clean
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
restore_yaml "snap/snapcraft.yaml"
execute: |
cd "$SNAP_DIR"
snapcraft prime
if ! snap list hello; then
echo "snap listed as default provider was not installed"
exit 1
fi
@@ -0,0 +1,20 @@
name: content-test
version: '0.1'
summary: snap using a plug with a content interface that cannot be found
description: |
Defining a plug using the content interface should only warn when it
cannot find the snap listed under default-provider.
grade: devel
confinement: devmode

plugs:
content-interface:
content: content-interface
interface: content
target: $SNAP/content
default-provider: unknown-content-snap

parts:
empty:
plugin: nil
@@ -0,0 +1,24 @@
summary: Build a snap that uses the content interface with a non published snap

environment:
SNAP_DIR: snaps/provider

prepare: |
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
set_base "$SNAP_DIR/snap/snapcraft.yaml"
restore: |
cd "$SNAP_DIR"
snapcraft clean
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
restore_yaml "snap/snapcraft.yaml"
execute: |
cd "$SNAP_DIR"
output=$(snapcraft prime)
echo "$output" | MATCH "Could not install snap defined in plug"

0 comments on commit 2ef3923

Please sign in to comment.