Skip to content

Commit

Permalink
interfaces/builtin/home: autoconnect home on core desktop (#14106)
Browse files Browse the repository at this point in the history
* asserts,i/policy: add on-core-desktop constraint

This is required for interface behaviours that are different on Core Desktop.

* interfaces/builtin/home: autoconnect home on core desktop

Core desktop is much like a classic system in that the user would reasonably
expect to be able to access this home directory.
  • Loading branch information
robert-ancell authored Jul 12, 2024
1 parent 0b52b0e commit fc53358
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 16 deletions.
59 changes: 52 additions & 7 deletions asserts/ifacedecls.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ type OnClassicConstraint struct {
SystemIDs []string
}

// OnCoreDesktopConstraint specifies a constraint based whether the system is core desktop.
type OnCoreDesktopConstraint struct {
CoreDesktop bool
}

type nameMatcher interface {
match(name string, special map[string]string) error
}
Expand Down Expand Up @@ -307,6 +312,7 @@ type constraintsHolder interface {
setAttributeConstraints(field string, cstrs *AttributeConstraints)
setIDConstraints(field string, cstrs []string)
setOnClassicConstraint(onClassic *OnClassicConstraint)
setOnCoreDesktopConstraint(onCoreDesktop *OnCoreDesktopConstraint)
setDeviceScopeConstraint(deviceScope *DeviceScopeConstraint)
}

Expand Down Expand Up @@ -400,6 +406,25 @@ func baseCompileConstraints(context *subruleContext, cDef constraintsDef, target
}
target.setOnClassicConstraint(c)
}
onCoreDesktop := cMap["on-core-desktop"]
if onCoreDesktop == nil {
defaultUsed++
} else {
var c *OnCoreDesktopConstraint
switch x := onCoreDesktop.(type) {
case string:
switch x {
case "true":
c = &OnCoreDesktopConstraint{CoreDesktop: true}
case "false":
c = &OnCoreDesktopConstraint{CoreDesktop: false}
}
}
if c == nil {
return fmt.Errorf("on-core-desktop in %s must be 'true' or 'false'", context)
}
target.setOnCoreDesktopConstraint(c)
}
dsc, err := compileDeviceScopeConstraint(cMap, context.String())
if err != nil {
return err
Expand All @@ -411,10 +436,10 @@ func baseCompileConstraints(context *subruleContext, cDef constraintsDef, target
}
// checks whether defaults have been used for everything, which is not
// well-formed
// +1+1 accounts for defaults for missing on-classic plus missing
// +1+1+1 accounts for defaults for missing on-classic, on-core-desktop plus missing
// on-store/on-brand/on-model
if defaultUsed == len(nameConstraints)+len(attributeConstraints)+len(idConstraints)+len(sideArityConstraints)+1+1 {
return fmt.Errorf("%s must specify at least one of %s, %s, %s, %s, on-classic, on-store, on-brand, on-model", context, strings.Join(nameConstraints, ", "), strings.Join(attrConstraints, ", "), strings.Join(idConstraints, ", "), strings.Join(sideArityConstraints, ", "))
if defaultUsed == len(nameConstraints)+len(attributeConstraints)+len(idConstraints)+len(sideArityConstraints)+1+1+1 {
return fmt.Errorf("%s must specify at least one of %s, %s, %s, %s, on-classic, on-core-desktop, on-store, on-brand, on-model", context, strings.Join(nameConstraints, ", "), strings.Join(attrConstraints, ", "), strings.Join(idConstraints, ", "), strings.Join(sideArityConstraints, ", "))
}
return nil
}
Expand Down Expand Up @@ -630,7 +655,8 @@ type PlugInstallationConstraints struct {

PlugAttributes *AttributeConstraints

OnClassic *OnClassicConstraint
OnClassic *OnClassicConstraint
OnCoreDesktop *OnCoreDesktopConstraint

DeviceScope *DeviceScopeConstraint
}
Expand Down Expand Up @@ -678,6 +704,10 @@ func (c *PlugInstallationConstraints) setOnClassicConstraint(onClassic *OnClassi
c.OnClassic = onClassic
}

func (c *PlugInstallationConstraints) setOnCoreDesktopConstraint(onCoreDesktop *OnCoreDesktopConstraint) {
c.OnCoreDesktop = onCoreDesktop
}

func (c *PlugInstallationConstraints) setDeviceScopeConstraint(deviceScope *DeviceScopeConstraint) {
c.DeviceScope = deviceScope
}
Expand Down Expand Up @@ -712,7 +742,8 @@ type PlugConnectionConstraints struct {
// PlugsPerSlot is always * (any) (for now)
PlugsPerSlot SideArityConstraint

OnClassic *OnClassicConstraint
OnClassic *OnClassicConstraint
OnCoreDesktop *OnCoreDesktopConstraint

DeviceScope *DeviceScopeConstraint
}
Expand Down Expand Up @@ -782,6 +813,10 @@ func (c *PlugConnectionConstraints) setOnClassicConstraint(onClassic *OnClassicC
c.OnClassic = onClassic
}

func (c *PlugConnectionConstraints) setOnCoreDesktopConstraint(onCoreDesktop *OnCoreDesktopConstraint) {
c.OnCoreDesktop = onCoreDesktop
}

func (c *PlugConnectionConstraints) setDeviceScopeConstraint(deviceScope *DeviceScopeConstraint) {
c.DeviceScope = deviceScope
}
Expand Down Expand Up @@ -939,7 +974,8 @@ type SlotInstallationConstraints struct {

SlotAttributes *AttributeConstraints

OnClassic *OnClassicConstraint
OnClassic *OnClassicConstraint
OnCoreDesktop *OnCoreDesktopConstraint

DeviceScope *DeviceScopeConstraint
}
Expand Down Expand Up @@ -987,6 +1023,10 @@ func (c *SlotInstallationConstraints) setOnClassicConstraint(onClassic *OnClassi
c.OnClassic = onClassic
}

func (c *SlotInstallationConstraints) setOnCoreDesktopConstraint(onCoreDesktop *OnCoreDesktopConstraint) {
c.OnCoreDesktop = onCoreDesktop
}

func (c *SlotInstallationConstraints) setDeviceScopeConstraint(deviceScope *DeviceScopeConstraint) {
c.DeviceScope = deviceScope
}
Expand Down Expand Up @@ -1035,7 +1075,8 @@ type SlotConnectionConstraints struct {
// PlugsPerSlot is always * (any) (for now)
PlugsPerSlot SideArityConstraint

OnClassic *OnClassicConstraint
OnClassic *OnClassicConstraint
OnCoreDesktop *OnCoreDesktopConstraint

DeviceScope *DeviceScopeConstraint
}
Expand Down Expand Up @@ -1111,6 +1152,10 @@ func (c *SlotConnectionConstraints) setOnClassicConstraint(onClassic *OnClassicC
c.OnClassic = onClassic
}

func (c *SlotConnectionConstraints) setOnCoreDesktopConstraint(onCoreDesktop *OnCoreDesktopConstraint) {
c.OnCoreDesktop = onCoreDesktop
}

func (c *SlotConnectionConstraints) setDeviceScopeConstraint(deviceScope *DeviceScopeConstraint) {
c.DeviceScope = deviceScope
}
Expand Down
16 changes: 8 additions & 8 deletions asserts/ifacedecls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1231,19 +1231,19 @@ func (s *plugSlotRulesSuite) TestCompilePlugRuleErrors(c *C) {
{`iface:
allow-connection:
slot-snap-ids:
- foo`, `allow-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `allow-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
deny-connection:
slot-snap-ids:
- foo`, `deny-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `deny-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
allow-auto-connection:
slot-snap-ids:
- foo`, `allow-auto-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `allow-auto-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
deny-auto-connection:
slot-snap-ids:
- foo`, `deny-auto-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `deny-auto-connection in plug rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, slot-publisher-id, slot-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
allow-connect: true`, `plug rule for interface "iface" must specify at least one of allow-installation, deny-installation, allow-connection, deny-connection, allow-auto-connection, deny-auto-connection`},
{`iface:
Expand Down Expand Up @@ -2076,19 +2076,19 @@ func (s *plugSlotRulesSuite) TestCompileSlotRuleErrors(c *C) {
{`iface:
allow-connection:
plug-snap-ids:
- foo`, `allow-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `allow-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
deny-connection:
plug-snap-ids:
- foo`, `deny-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `deny-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
allow-auto-connection:
plug-snap-ids:
- foo`, `allow-auto-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `allow-auto-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
deny-auto-connection:
plug-snap-ids:
- foo`, `deny-auto-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-store, on-brand, on-model`},
- foo`, `deny-auto-connection in slot rule for interface "iface" must specify at least one of plug-names, slot-names, plug-attributes, slot-attributes, slot-snap-type, plug-snap-type, plug-publisher-id, plug-snap-id, slots-per-plug, plugs-per-slot, on-classic, on-core-desktop, on-store, on-brand, on-model`},
{`iface:
allow-connect: true`, `slot rule for interface "iface" must specify at least one of allow-installation, deny-installation, allow-connection, deny-connection, allow-auto-connection, deny-auto-connection`},
{`iface:
Expand Down
1 change: 1 addition & 0 deletions interfaces/builtin/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const homeBaseDeclarationSlots = `
deny-auto-connection:
-
on-classic: false
on-core-desktop: false
-
plug-attributes:
read: all
Expand Down
27 changes: 26 additions & 1 deletion interfaces/policy/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ func checkOnClassic(c *asserts.OnClassicConstraint) error {
return nil
}

func checkOnCoreDesktop(c *asserts.OnCoreDesktopConstraint) error {
if c == nil {
return nil
}
if c.CoreDesktop != release.OnCoreDesktop {
return fmt.Errorf("on-core-desktop mismatch")
}
return nil
}

func checkDeviceScope(c *asserts.DeviceScopeConstraint, model *asserts.Model, store *asserts.Store) error {
if c == nil {
return nil
Expand Down Expand Up @@ -132,6 +142,9 @@ func checkPlugConnectionConstraints1(connc *ConnectCandidate, constraints *asser
if err := checkOnClassic(constraints.OnClassic); err != nil {
return err
}
if err := checkOnCoreDesktop(constraints.OnCoreDesktop); err != nil {
return err
}
if err := checkDeviceScope(constraints.DeviceScope, connc.Model, connc.Store); err != nil {
return err
}
Expand Down Expand Up @@ -185,6 +198,9 @@ func checkSlotConnectionConstraints1(connc *ConnectCandidate, constraints *asser
if err := checkOnClassic(constraints.OnClassic); err != nil {
return err
}
if err := checkOnCoreDesktop(constraints.OnCoreDesktop); err != nil {
return err
}
if err := checkDeviceScope(constraints.DeviceScope, connc.Model, connc.Store); err != nil {
return err
}
Expand Down Expand Up @@ -213,6 +229,9 @@ func checkSnapTypeSlotInstallationConstraints1(slot *snap.SlotInfo, constraints
if err := checkOnClassic(constraints.OnClassic); err != nil {
return err
}
if err := checkOnCoreDesktop(constraints.OnCoreDesktop); err != nil {
return err
}
return nil
}

Expand All @@ -221,7 +240,7 @@ func checkMinimalSlotInstallationAltConstraints(slot *snap.SlotInfo, altConstrai
var hasSnapTypeConstraints bool
// OR of constraints
for _, constraints := range altConstraints {
if constraints.OnClassic == nil && len(constraints.SlotSnapTypes) == 0 {
if constraints.OnClassic == nil && constraints.OnCoreDesktop == nil && len(constraints.SlotSnapTypes) == 0 {
continue
}
hasSnapTypeConstraints = true
Expand Down Expand Up @@ -254,6 +273,9 @@ func checkSlotInstallationConstraints1(ic *InstallCandidate, slot *snap.SlotInfo
if err := checkOnClassic(constraints.OnClassic); err != nil {
return err
}
if err := checkOnCoreDesktop(constraints.OnCoreDesktop); err != nil {
return err
}
if err := checkDeviceScope(constraints.DeviceScope, ic.Model, ic.Store); err != nil {
return err
}
Expand Down Expand Up @@ -293,6 +315,9 @@ func checkPlugInstallationConstraints1(ic *InstallCandidate, plug *snap.PlugInfo
if err := checkOnClassic(constraints.OnClassic); err != nil {
return err
}
if err := checkOnCoreDesktop(constraints.OnCoreDesktop); err != nil {
return err
}
if err := checkDeviceScope(constraints.DeviceScope, ic.Model, ic.Store); err != nil {
return err
}
Expand Down

0 comments on commit fc53358

Please sign in to comment.