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  }