Esempio n. 1
0
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
}
Esempio n. 2
0
func (m *InterfaceManager) doDisconnect(task *state.Task, _ *tomb.Tomb) error {
	st := task.State()
	st.Lock()
	defer st.Unlock()

	plugRef, slotRef, err := getPlugAndSlotRefs(task)
	if err != nil {
		return err
	}

	conns, err := getConns(st)
	if err != nil {
		return err
	}

	var affectedConns []interfaces.ConnRef
	if plugRef.Snap != "" && plugRef.Name != "" && slotRef.Snap != "" && slotRef.Name != "" {
		if err := m.repo.Disconnect(plugRef.Snap, plugRef.Name, slotRef.Snap, slotRef.Name); err != nil {
			return err
		}
		affectedConns = []interfaces.ConnRef{{plugRef, slotRef}}
	} else if plugRef.Name != "" && slotRef.Snap == "" && slotRef.Name == "" {
		// NOTE: plugRef.Snap can be either empty or not, Connected handles both
		affectedConns, err = m.repo.Connected(plugRef.Snap, plugRef.Name)
		if err != nil {
			return err
		}
		m.repo.DisconnectAll(affectedConns)
	} else if plugRef.Snap == "" && plugRef.Name == "" && slotRef.Name != "" {
		// Symmetrically, slotRef.Snap can be either empty or not
		affectedConns, err = m.repo.Connected(slotRef.Snap, slotRef.Name)
		if err != nil {
			return err
		}
		m.repo.DisconnectAll(affectedConns)
	} else {
		return fmt.Errorf("internal error, unhandled disconnect case plug: %q, slot: %q", plugRef, slotRef)
	}
	affectedSnaps := snapNamesFromConns(affectedConns)
	for _, snapName := range affectedSnaps {
		var snapst snapstate.SnapState
		if err := snapstate.Get(st, snapName, &snapst); err != nil {
			return err
		}
		snapInfo, err := snapst.CurrentInfo()
		if err != nil {
			return err
		}
		opts := confinementOptions(snapst.Flags)
		if err := setupSnapSecurity(task, snapInfo, opts, m.repo); err != nil {
			return &state.Retry{}
		}
	}
	for _, conn := range affectedConns {
		delete(conns, conn.ID())
	}

	setConns(st, conns)
	return nil
}
Esempio n. 3
0
// localSnapInfo returns the information about the current snap for the given name plus the SnapState with the active flag and other snap revisions.
func localSnapInfo(st *state.State, name string) (*snap.Info, *snapstate.SnapState, error) {
	st.Lock()
	defer st.Unlock()

	var snapst snapstate.SnapState
	err := snapstate.Get(st, name, &snapst)
	if err != nil && err != state.ErrNoState {
		return nil, nil, fmt.Errorf("cannot consult state: %v", err)
	}

	info, err := snapst.CurrentInfo()
	if err == snapstate.ErrNoCurrent {
		return nil, nil, errNoSnap
	}
	if err != nil {
		return nil, nil, fmt.Errorf("cannot read snap details: %v", err)
	}

	return info, &snapst, nil
}