launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #29190
[Merge] ~andrey-fedoseev/launchpad:snap-base-features into launchpad:master
Andrey Fedoseev has proposed merging ~andrey-fedoseev/launchpad:snap-base-features into launchpad:master.
Commit message:
Add `ISnapBase.features` field
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~andrey-fedoseev/launchpad/+git/launchpad/+merge/429878
The field is used to designate the features available for a snap base
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~andrey-fedoseev/launchpad:snap-base-features into launchpad:master.
diff --git a/lib/lp/snappy/interfaces/snapbase.py b/lib/lp/snappy/interfaces/snapbase.py
index 08cfd79..8fdc1f4 100644
--- a/lib/lp/snappy/interfaces/snapbase.py
+++ b/lib/lp/snappy/interfaces/snapbase.py
@@ -8,6 +8,8 @@ __all__ = [
"ISnapBase",
"ISnapBaseSet",
"NoSuchSnapBase",
+ "ALLOW_DUPLICATE_BUILD_ON",
+ "SNAP_BASE_KNOWN_FEATURES",
]
import http.client
@@ -74,6 +76,10 @@ class SnapBaseNameField(ContentNameField):
return None
+ALLOW_DUPLICATE_BUILD_ON = "allow_duplicate_build_on"
+SNAP_BASE_KNOWN_FEATURES = {ALLOW_DUPLICATE_BUILD_ON}
+
+
class ISnapBaseView(Interface):
"""`ISnapBase` attributes that anyone can view."""
@@ -181,6 +187,20 @@ class ISnapBaseEditableAttributes(Interface):
)
)
+ features = exported(
+ Dict(
+ title=_("Features supported by this base"),
+ key_type=TextLine(),
+ required=False,
+ readonly=False,
+ description=_(
+ "A dictionary designating the features supported by the base. "
+ "Key is the name of a feature, value is a boolean indicating "
+ "whether the feature is supported or not."
+ ),
+ )
+ )
+
class ISnapBaseEdit(Interface):
"""`ISnapBase` methods that require launchpad.Edit permission."""
@@ -263,7 +283,14 @@ class ISnapBaseSetEdit(Interface):
)
)
@export_factory_operation(
- ISnapBase, ["name", "display_name", "distro_series", "build_channels"]
+ ISnapBase,
+ [
+ "name",
+ "display_name",
+ "distro_series",
+ "build_channels",
+ "features",
+ ],
)
@operation_for_version("devel")
def new(
@@ -272,6 +299,7 @@ class ISnapBaseSetEdit(Interface):
display_name,
distro_series,
build_channels,
+ features,
processors=None,
date_created=None,
):
diff --git a/lib/lp/snappy/model/snapbase.py b/lib/lp/snappy/model/snapbase.py
index f87a3e6..e92f91a 100644
--- a/lib/lp/snappy/model/snapbase.py
+++ b/lib/lp/snappy/model/snapbase.py
@@ -7,7 +7,10 @@ __all__ = [
"SnapBase",
]
+from typing import Dict, Optional
+
import pytz
+from storm.databases.postgres import JSON as PgJSON
from storm.locals import (
JSON,
Bool,
@@ -29,6 +32,7 @@ from lp.registry.model.person import Person
from lp.services.database.constants import DEFAULT
from lp.services.database.interfaces import IMasterStore, IStore
from lp.snappy.interfaces.snapbase import (
+ SNAP_BASE_KNOWN_FEATURES,
CannotDeleteSnapBase,
ISnapBase,
ISnapBaseSet,
@@ -69,6 +73,8 @@ class SnapBase(Storm):
is_default = Bool(name="is_default", allow_none=False)
+ _features = PgJSON(name="features", allow_none=False)
+
def __init__(
self,
registrant,
@@ -76,6 +82,7 @@ class SnapBase(Storm):
display_name,
distro_series,
build_channels,
+ features,
date_created=DEFAULT,
):
super().__init__()
@@ -85,8 +92,25 @@ class SnapBase(Storm):
self.distro_series = distro_series
self.build_channels = build_channels
self.date_created = date_created
+ self.features = features
self.is_default = False
+ @property
+ def features(self) -> Dict[str, bool]:
+ return {
+ k: v
+ for k, v in (self._features or {}).items()
+ if k in SNAP_BASE_KNOWN_FEATURES
+ }
+
+ @features.setter
+ def features(self, value: Optional[Dict[str, bool]]) -> None:
+ self._features = {
+ k: v
+ for k, v in (value or {}).items()
+ if k in SNAP_BASE_KNOWN_FEATURES
+ }
+
def _getProcessors(self):
return list(
Store.of(self).find(
@@ -217,6 +241,7 @@ class SnapBaseSet:
display_name,
distro_series,
build_channels,
+ features,
processors=None,
date_created=DEFAULT,
):
@@ -228,6 +253,7 @@ class SnapBaseSet:
display_name,
distro_series,
build_channels,
+ features,
date_created=date_created,
)
store.add(snap_base)
diff --git a/lib/lp/snappy/tests/test_snapbase.py b/lib/lp/snappy/tests/test_snapbase.py
index afd71c1..36d046e 100644
--- a/lib/lp/snappy/tests/test_snapbase.py
+++ b/lib/lp/snappy/tests/test_snapbase.py
@@ -17,6 +17,7 @@ from lp.app.interfaces.security import IAuthorization
from lp.registry.interfaces.pocket import PackagePublishingPocket
from lp.services.webapp.interfaces import OAuthPermission
from lp.snappy.interfaces.snapbase import (
+ ALLOW_DUPLICATE_BUILD_ON,
CannotDeleteSnapBase,
ISnapBase,
ISnapBaseSet,
@@ -69,6 +70,17 @@ class TestSnapBase(TestCaseWithFactory):
getUtility(ISnapBaseSet).setDefault(snap_base)
self.assertRaises(CannotDeleteSnapBase, snap_base.destroySelf)
+ def test_features(self):
+ snap_base = self.factory.makeSnapBase(
+ features={ALLOW_DUPLICATE_BUILD_ON: True, "unknown_feature": True}
+ )
+ self.assertEqual(
+ snap_base.features,
+ {
+ ALLOW_DUPLICATE_BUILD_ON: True,
+ },
+ )
+
class TestSnapBaseProcessors(TestCaseWithFactory):
@@ -102,6 +114,7 @@ class TestSnapBaseProcessors(TestCaseWithFactory):
display_name=self.factory.getUniqueUnicode(),
distro_series=self.distroseries,
build_channels={},
+ features={},
)
self.assertContentEqual(self.procs, snap_base.processors)
@@ -113,6 +126,7 @@ class TestSnapBaseProcessors(TestCaseWithFactory):
display_name=self.factory.getUniqueUnicode(),
distro_series=self.distroseries,
build_channels={},
+ features={},
processors=self.procs[:2],
)
self.assertContentEqual(self.procs[:2], snap_base.processors)
@@ -211,6 +225,7 @@ class TestSnapBaseWebservice(TestCaseWithFactory):
display_name="Dummy",
distro_series=distroseries_url,
build_channels={"snapcraft": "stable"},
+ features={"allow_duplicate_build_on": True},
)
self.assertEqual(201, response.status)
snap_base = webservice.get(response.getHeader("Location")).jsonBody()
@@ -228,6 +243,7 @@ class TestSnapBaseWebservice(TestCaseWithFactory):
webservice.getAbsoluteUrl(distroseries_url)
),
"build_channels": Equals({"snapcraft": "stable"}),
+ "features": Equals({"allow_duplicate_build_on": True}),
"is_default": Is(False),
}
),
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index 3fd560c..7cbd238 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -6372,6 +6372,7 @@ class LaunchpadObjectFactory(ObjectFactory):
display_name=None,
distro_series=None,
build_channels=None,
+ features=None,
processors=None,
date_created=DEFAULT,
):
@@ -6394,6 +6395,7 @@ class LaunchpadObjectFactory(ObjectFactory):
display_name,
distro_series,
build_channels,
+ features=features,
processors=processors,
date_created=date_created,
)