Skip to content
Browse files

overlord/ifacestate: support implicit slots on snapd

This patch changes the interface manager to support using "snapd" snap
as a host for implicit slots. The way this works is as follows. On
startup snapd inspects the state and if it sees that the "snapd" snap is
installed it chooses it as a host of implicit slots for the lifetime of
the snapd process.

This is done by setting the snap mapper, early in the interface manager
startup code, to CoreSnapdSystemMapper which, as the name suggests, uses
"core" in the state, "snapd" in memory and "system" in the API layer.
The mapper is the interrogated when adding implicit slots so it is never
the case that both core and snapd have implicit slots and contend for
auto-connection candidates.

This is a simple reuse of the existing mapper and, as the mapper itself,
can be re-factored to be a field on the interface manager if we so
require. I didn't choose to do this as it would require large and boring
changes across the stack, to call various interacting methods on the
interface manager instance.

Signed-off-by: Zygmunt Krynicki <>
  • Loading branch information
zyga committed Jul 14, 2018
1 parent 360ad8e commit c69daaba9adf2e1d37a439eec248aeec3949c306
Showing with 24 additions and 2 deletions.
  1. +11 −0 overlord/ifacestate/helpers.go
  2. +13 −2 overlord/ifacestate/implicit.go
@@ -104,6 +104,17 @@ func (m *InterfaceManager) addSnaps() error {
if err != nil {
return err
// Before adding any snap scan the set of snaps we know about. If any of
// those is snapd then for the duration of this process always add implicit
// slots to snapd and not to any other type: os snap and use a mapper to
// use names core-snapd-system on state, in memory and in API responses,
// respectively.
for _, snapInfo := range snaps {
if snapInfo.SnapName() == "snapd" {
mapper = &CoreSnapdSystemMapper{}
for _, snapInfo := range snaps {
if err := m.repo.AddSnap(snapInfo); err != nil {
@@ -33,10 +33,21 @@ import (
// It is assumed that slots have names matching the interface name. Existing
// slots are not changed, only missing slots are added.
func addImplicitSlots(snapInfo *snap.Info) {
if snapInfo.Type != snap.TypeOS {
// Implicit slots can be added to the special "snapd" snap or to snaps with
// type "os". Currently there are no other snaps that gain implicit
// interfaces.
if snapInfo.Type != snap.TypeOS && snapInfo.InstanceName() != "snapd" {
// Ask each interface if it wants to be implcitly added.

// If the manager has chosen to put implicit slots on the "snapd" snap
// then stop adding them to any other core snaps.
_, isSnapdHostingImplicitSlots := mapper.(*CoreSnapdSystemMapper)
if isSnapdHostingImplicitSlots && snapInfo.InstanceName() != "snapd" {

// Ask each interface if it wants to be implicitly added.
for _, iface := range builtin.Interfaces() {
si := interfaces.StaticInfoOf(iface)
if (release.OnClassic && si.ImplicitOnClassic) || (!release.OnClassic && si.ImplicitOnCore) {

0 comments on commit c69daab

Please sign in to comment.