github.com/ethanhsieh/snapd@v0.0.0-20210615102523-3db9b8e4edc5/overlord/hookstate/hooks.go (about) 1 /* 2 * Copyright (C) 2017 Canonical Ltd 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 3 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 */ 17 18 package hookstate 19 20 import ( 21 "fmt" 22 "regexp" 23 "sort" 24 25 "github.com/snapcore/snapd/i18n" 26 "github.com/snapcore/snapd/overlord/snapstate" 27 "github.com/snapcore/snapd/overlord/state" 28 ) 29 30 func init() { 31 snapstate.SetupInstallHook = SetupInstallHook 32 snapstate.SetupPreRefreshHook = SetupPreRefreshHook 33 snapstate.SetupPostRefreshHook = SetupPostRefreshHook 34 snapstate.SetupRemoveHook = SetupRemoveHook 35 snapstate.SetupGateAutoRefreshHook = SetupGateAutoRefreshHook 36 } 37 38 func SetupInstallHook(st *state.State, snapName string) *state.Task { 39 hooksup := &HookSetup{ 40 Snap: snapName, 41 Hook: "install", 42 Optional: true, 43 } 44 45 summary := fmt.Sprintf(i18n.G("Run install hook of %q snap if present"), hooksup.Snap) 46 task := HookTask(st, summary, hooksup, nil) 47 48 return task 49 } 50 51 func SetupPostRefreshHook(st *state.State, snapName string) *state.Task { 52 hooksup := &HookSetup{ 53 Snap: snapName, 54 Hook: "post-refresh", 55 Optional: true, 56 } 57 58 summary := fmt.Sprintf(i18n.G("Run post-refresh hook of %q snap if present"), hooksup.Snap) 59 return HookTask(st, summary, hooksup, nil) 60 } 61 62 func SetupPreRefreshHook(st *state.State, snapName string) *state.Task { 63 hooksup := &HookSetup{ 64 Snap: snapName, 65 Hook: "pre-refresh", 66 Optional: true, 67 } 68 69 summary := fmt.Sprintf(i18n.G("Run pre-refresh hook of %q snap if present"), hooksup.Snap) 70 task := HookTask(st, summary, hooksup, nil) 71 72 return task 73 } 74 75 func SetupGateAutoRefreshHook(st *state.State, snapName string, base, restart bool, affectingSnaps map[string]bool) *state.Task { 76 hookSup := &HookSetup{ 77 Snap: snapName, 78 Hook: "gate-auto-refresh", 79 Optional: true, 80 } 81 affecting := make([]string, 0, len(affectingSnaps)) 82 for sn := range affectingSnaps { 83 affecting = append(affecting, sn) 84 } 85 sort.Strings(affecting) 86 summary := fmt.Sprintf(i18n.G("Run hook %s of snap %q"), hookSup.Hook, hookSup.Snap) 87 hookCtx := map[string]interface{}{ 88 "base": base, 89 "restart": restart, 90 "affecting-snaps": affecting, 91 } 92 task := HookTask(st, summary, hookSup, hookCtx) 93 return task 94 } 95 96 type snapHookHandler struct { 97 } 98 99 func (h *snapHookHandler) Before() error { 100 return nil 101 } 102 103 func (h *snapHookHandler) Done() error { 104 return nil 105 } 106 107 func (h *snapHookHandler) Error(err error) error { 108 return nil 109 } 110 111 func SetupRemoveHook(st *state.State, snapName string) *state.Task { 112 hooksup := &HookSetup{ 113 Snap: snapName, 114 Hook: "remove", 115 Optional: true, 116 IgnoreError: true, 117 } 118 119 summary := fmt.Sprintf(i18n.G("Run remove hook of %q snap if present"), hooksup.Snap) 120 task := HookTask(st, summary, hooksup, nil) 121 122 return task 123 } 124 125 func setupHooks(hookMgr *HookManager) { 126 handlerGenerator := func(context *Context) Handler { 127 return &snapHookHandler{} 128 } 129 130 hookMgr.Register(regexp.MustCompile("^install$"), handlerGenerator) 131 hookMgr.Register(regexp.MustCompile("^post-refresh$"), handlerGenerator) 132 hookMgr.Register(regexp.MustCompile("^pre-refresh$"), handlerGenerator) 133 hookMgr.Register(regexp.MustCompile("^remove$"), handlerGenerator) 134 hookMgr.Register(regexp.MustCompile("^gate-auto-refresh$"), handlerGenerator) 135 }