github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/overlord/snapstate/policy/policy.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 // Package policy implements fine grained decision-making for snapstate 21 package policy 22 23 import ( 24 "github.com/snapcore/snapd/asserts" 25 "github.com/snapcore/snapd/boot" 26 "github.com/snapcore/snapd/overlord/snapstate" 27 "github.com/snapcore/snapd/overlord/state" 28 "github.com/snapcore/snapd/snap" 29 ) 30 31 func init() { 32 snapstate.PolicyFor = For 33 } 34 35 func For(typ snap.Type, model *asserts.Model) snapstate.Policy { 36 switch typ { 37 case snap.TypeKernel: 38 return &kernelPolicy{modelKernel: model.Kernel()} 39 case snap.TypeGadget: 40 return &gadgetPolicy{modelGadget: model.Gadget()} 41 case snap.TypeOS: 42 return &osPolicy{modelBase: model.Base()} 43 case snap.TypeBase: 44 return &basePolicy{modelBase: model.Base()} 45 case snap.TypeSnapd: 46 return &snapdPolicy{onClassic: model.Classic()} 47 default: 48 return appPolicy{} 49 } 50 } 51 52 func ephemeral(dev boot.Device) bool { 53 return !dev.RunMode() 54 } 55 56 func inUse(name string, rev snap.Revision, typ snap.Type, dev boot.Device) error { 57 check, err := boot.InUse(typ, dev) 58 if err != nil { 59 return err 60 } 61 if check(name, rev) { 62 return errInUseForBoot 63 } 64 return nil 65 } 66 67 type appPolicy struct{} 68 69 func (appPolicy) CanRemove(_ *state.State, snapst *snapstate.SnapState, rev snap.Revision, dev boot.Device) error { 70 if ephemeral(dev) { 71 return errEphemeralSnapsNotRemovalable 72 } 73 74 if !rev.Unset() { 75 return nil 76 } 77 78 if snapst.Required { 79 return errRequired 80 } 81 82 return nil 83 }