// CheckInterfaces checks whether plugs and slots of snap are allowed for installation. func CheckInterfaces(st *state.State, snapInfo *snap.Info) error { // XXX: AddImplicitSlots is really a brittle interface snap.AddImplicitSlots(snapInfo) baseDecl, err := assertstate.BaseDeclaration(st) if err != nil { return fmt.Errorf("internal error: cannot find base declaration: %v", err) } var snapDecl *asserts.SnapDeclaration if snapInfo.SnapID != "" { var err error snapDecl, err = assertstate.SnapDeclaration(st, snapInfo.SnapID) if err != nil { return fmt.Errorf("cannot find snap declaration for %q: %v", snapInfo.Name(), err) } } ic := policy.InstallCandidate{ Snap: snapInfo, SnapDeclaration: snapDecl, BaseDeclaration: baseDecl, } return ic.Check() }
func (s *apiSuite) mockSnap(c *C, yamlText string) *snap.Info { if s.d == nil { panic("call s.daemon(c) in your test first") } snapInfo := snaptest.MockSnap(c, yamlText, &snap.SideInfo{Revision: snap.R(1)}) snap.AddImplicitSlots(snapInfo) st := s.d.overlord.State() st.Lock() defer st.Unlock() // Put a side info into the state snapstate.Set(st, snapInfo.Name(), &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{ { RealName: snapInfo.Name(), Revision: snapInfo.Revision, SnapID: "ididid", }, }, Current: snapInfo.Revision, }) // Put the snap into the interface repository repo := s.d.overlord.InterfaceManager().Repository() err := repo.AddSnap(snapInfo) c.Assert(err, IsNil) return snapInfo }
func (m *InterfaceManager) setupAffectedSnaps(task *state.Task, affectingSnap string, affectedSnaps []string) error { st := task.State() // Setup security of the affected snaps. for _, affectedSnapName := range affectedSnaps { // the snap that triggered the change needs to be skipped if affectedSnapName == affectingSnap { continue } var snapst snapstate.SnapState if err := snapstate.Get(st, affectedSnapName, &snapst); err != nil { return err } affectedSnapInfo, err := snapst.CurrentInfo() if err != nil { return err } snap.AddImplicitSlots(affectedSnapInfo) opts := confinementOptions(snapst.Flags) if err := setupSnapSecurity(task, affectedSnapInfo, opts, m.repo); err != nil { return err } } return nil }
func (m *InterfaceManager) doSetupProfiles(task *state.Task, _ *tomb.Tomb) error { task.State().Lock() defer task.State().Unlock() // Get snap.Info from bits handed by the snap manager. ss, err := snapstate.TaskSnapSetup(task) if err != nil { return err } snapInfo, err := snap.ReadInfo(ss.Name(), ss.SideInfo) if err != nil { return err } snap.AddImplicitSlots(snapInfo) snapName := snapInfo.Name() // The snap may have been updated so perform the following operation to // ensure that we are always working on the correct state: // // - disconnect all connections to/from the given snap // - remembering the snaps that were affected by this operation // - remove the (old) snap from the interfaces repository // - add the (new) snap to the interfaces repository // - restore connections based on what is kept in the state // - if a connection cannot be restored then remove it from the state // - setup the security of all the affected snaps affectedSnaps, err := m.repo.DisconnectSnap(snapName) if err != nil { return err } // XXX: what about snap renames? We should remove the old name (or switch // to IDs in the interfaces repository) if err := m.repo.RemoveSnap(snapName); err != nil { return err } if err := m.repo.AddSnap(snapInfo); err != nil { if _, ok := err.(*interfaces.BadInterfacesError); ok { logger.Noticef("%s", err) } else { return err } } if err := m.reloadConnections(snapName); err != nil { return err } // FIXME: here we should not reconnect auto-connect plug/slot // pairs that were explicitly disconnected by the user if err := m.autoConnect(task, snapName, nil); err != nil { return err } if err := setupSnapSecurity(task, snapInfo, ss.DevModeAllowed(), m.repo); err != nil { return err } return m.setupAffectedSnaps(task, snapName, affectedSnaps) }
func (m *InterfaceManager) addSnaps() error { snaps, err := snapstate.ActiveInfos(m.state) if err != nil { return err } for _, snapInfo := range snaps { snap.AddImplicitSlots(snapInfo) if err := m.repo.AddSnap(snapInfo); err != nil { logger.Noticef("%s", err) } } return nil }
func (s *InfoSnapYamlTestSuite) TestAddImplicitSlotsOnClassic(c *C) { restore := release.MockOnClassic(true) defer restore() osYaml := []byte("name: ubuntu-core\ntype: os\n") info, err := snap.InfoFromSnapYaml(osYaml) c.Assert(err, IsNil) snap.AddImplicitSlots(info) c.Assert(info.Slots["unity7"].Interface, Equals, "unity7") c.Assert(info.Slots["unity7"].Name, Equals, "unity7") c.Assert(info.Slots["unity7"].Snap, Equals, info) // Ensure that we have *some* implicit slots c.Assert(len(info.Slots) > 10, Equals, true) }