github.com/helmwave/helmwave@v0.36.4-0.20240509190856-b35563eba4c6/pkg/hooks/run.go (about) 1 package hooks 2 3 import ( 4 "bufio" 5 "context" 6 "os/exec" 7 8 "github.com/helmwave/helmwave/pkg/helper" 9 log "github.com/sirupsen/logrus" 10 ) 11 12 func runHooks(ctx context.Context, hooks []Hook) error { 13 for _, h := range hooks { 14 err := h.Run(ctx) 15 if err != nil { 16 h.Log().WithError(err).Error("failed to run hook") 17 18 return err 19 } 20 } 21 22 return nil 23 } 24 25 func (h *hook) Run(ctx context.Context) error { 26 err := h.run(ctx) 27 28 if h.AllowFailure { 29 h.Log().WithError(err).Warn("caught lifecycle error, skipping...") 30 31 return nil 32 } 33 34 return err 35 } 36 37 func (h *hook) run(ctx context.Context) error { 38 cmd := exec.CommandContext(ctx, h.Cmd, h.Args...) 39 40 const t = "🩼 running hook..." 41 42 switch h.Show { 43 case true: 44 h.Log().Info(t) 45 case false: 46 h.Log().Debug(t) 47 } 48 49 stdout, err := cmd.StdoutPipe() 50 if err != nil { 51 return NewCreatePipeError(err) 52 } 53 54 cmd.Env = h.getCommandEnviron(ctx) 55 56 // start the command after having set up the pipe 57 if err := cmd.Start(); err != nil { 58 return NewCommandRunError(err) 59 } 60 61 // read command's stdout line by line 62 in := bufio.NewScanner(stdout) 63 64 for in.Scan() { 65 switch h.Show { 66 case true: 67 log.Info(in.Text()) 68 case false: 69 log.Debug(in.Text()) 70 } 71 } 72 73 if err := in.Err(); err != nil { 74 return NewCommandReadOutputError(err) 75 } 76 77 if err := cmd.Wait(); err != nil { 78 return NewCommandRunError(err) 79 } 80 81 return nil 82 } 83 84 // BUILD 85 86 func (l *Lifecycle) RunPreBuild(ctx context.Context) error { 87 ctx = helper.ContextWithLifecycleType(ctx, "pre-build") 88 89 if len(l.PreBuild) != 0 { 90 log.Info("🩼 Running pre-build hooks...") 91 92 return runHooks(ctx, l.PreBuild) 93 } 94 95 return nil 96 } 97 98 func (l *Lifecycle) RunPostBuild(ctx context.Context) error { 99 ctx = helper.ContextWithLifecycleType(ctx, "post-build") 100 101 if len(l.PostBuild) != 0 { 102 log.Info("🩼 Running post-build hooks...") 103 104 return runHooks(ctx, l.PostBuild) 105 } 106 107 return nil 108 } 109 110 // UP 111 112 func (l *Lifecycle) RunPreUp(ctx context.Context) error { 113 ctx = helper.ContextWithLifecycleType(ctx, "pre-up") 114 115 if len(l.PreUp) != 0 { 116 log.Info("🩼 Running pre-up hooks...") 117 118 return runHooks(ctx, l.PreUp) 119 } 120 121 return nil 122 } 123 124 func (l *Lifecycle) RunPostUp(ctx context.Context) error { 125 ctx = helper.ContextWithLifecycleType(ctx, "post-up") 126 127 if len(l.PostUp) != 0 { 128 log.Info("🩼 Running post-up hooks...") 129 130 return runHooks(ctx, l.PostUp) 131 } 132 133 return nil 134 } 135 136 // DOWN 137 138 func (l *Lifecycle) RunPreDown(ctx context.Context) error { 139 ctx = helper.ContextWithLifecycleType(ctx, "pre-down") 140 141 if len(l.PreDown) != 0 { 142 log.Info("🩼 Running pre-down hooks...") 143 144 return runHooks(ctx, l.PreDown) 145 } 146 147 return nil 148 } 149 150 func (l *Lifecycle) RunPostDown(ctx context.Context) error { 151 ctx = helper.ContextWithLifecycleType(ctx, "post-down") 152 153 if len(l.PostDown) != 0 { 154 log.Info("🩼 Running post-down hooks...") 155 156 return runHooks(ctx, l.PostDown) 157 } 158 159 return nil 160 } 161 162 // ROLLBACK 163 164 func (l *Lifecycle) RunPreRollback(ctx context.Context) error { 165 ctx = helper.ContextWithLifecycleType(ctx, "pre-rollback") 166 167 if len(l.PreRollback) != 0 { 168 log.Info("🩼 Running pre-rollback hooks...") 169 170 return runHooks(ctx, l.PreRollback) 171 } 172 173 return nil 174 } 175 176 func (l *Lifecycle) RunPostRollback(ctx context.Context) error { 177 ctx = helper.ContextWithLifecycleType(ctx, "post-rollback") 178 179 if len(l.PostRollback) != 0 { 180 log.Info("🩼 Running post-rollback hooks...") 181 182 return runHooks(ctx, l.PostRollback) 183 } 184 185 return nil 186 }