Hande SIGINT in install command

Replicate the same logic in that was implementd in the upgrade action to handle SIGINT
Rename mutexes to isolate the variables

Signed-off-by: Stephane Moser <moser.sts@gmail.com>
pull/9180/head
Stephane Moser 4 years ago
parent d7833eb2b0
commit 3434053d38

@ -22,9 +22,12 @@ import (
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"os" "os"
"os/signal"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"sync"
"syscall"
"text/template" "text/template"
"time" "time"
@ -66,6 +69,8 @@ const notesFileSuffix = "NOTES.txt"
const defaultDirectoryPermission = 0755 const defaultDirectoryPermission = 0755
var installLock sync.Mutex
// Install performs an installation operation. // Install performs an installation operation.
type Install struct { type Install struct {
cfg *Configuration cfg *Configuration
@ -331,11 +336,21 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
// not working. // not working.
return rel, err return rel, err
} }
rChan := make(chan resultMessage)
go i.performInstall(rChan, rel, toBeAdopted, resources)
go i.handleSignals(rChan, rel)
result := <-rChan
//start preformInstall go routine
return result.r, result.e
}
func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, toBeAdopted kube.ResourceList, resources kube.ResourceList) {
// pre-install hooks // pre-install hooks
if !i.DisableHooks { if !i.DisableHooks {
if err := i.cfg.execHook(rel, release.HookPreInstall, i.Timeout); err != nil { if err := i.cfg.execHook(rel, release.HookPreInstall, i.Timeout); err != nil {
return i.failRelease(rel, fmt.Errorf("failed pre-install: %s", err)) i.reportToRun(c, rel, fmt.Errorf("failed pre-install: %s", err))
return
} }
} }
@ -344,29 +359,34 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
// to true, since that is basically an upgrade operation. // to true, since that is basically an upgrade operation.
if len(toBeAdopted) == 0 && len(resources) > 0 { if len(toBeAdopted) == 0 && len(resources) > 0 {
if _, err := i.cfg.KubeClient.Create(resources); err != nil { if _, err := i.cfg.KubeClient.Create(resources); err != nil {
return i.failRelease(rel, err) i.reportToRun(c, rel, err)
return
} }
} else if len(resources) > 0 { } else if len(resources) > 0 {
if _, err := i.cfg.KubeClient.Update(toBeAdopted, resources, false); err != nil { if _, err := i.cfg.KubeClient.Update(toBeAdopted, resources, false); err != nil {
return i.failRelease(rel, err) i.reportToRun(c, rel, err)
return
} }
} }
if i.Wait { if i.Wait {
if i.WaitForJobs { if i.WaitForJobs {
if err := i.cfg.KubeClient.WaitWithJobs(resources, i.Timeout); err != nil { if err := i.cfg.KubeClient.WaitWithJobs(resources, i.Timeout); err != nil {
return i.failRelease(rel, err) i.reportToRun(c, rel, err)
return
} }
} else { } else {
if err := i.cfg.KubeClient.Wait(resources, i.Timeout); err != nil { if err := i.cfg.KubeClient.Wait(resources, i.Timeout); err != nil {
return i.failRelease(rel, err) i.reportToRun(c, rel, err)
return
} }
} }
} }
if !i.DisableHooks { if !i.DisableHooks {
if err := i.cfg.execHook(rel, release.HookPostInstall, i.Timeout); err != nil { if err := i.cfg.execHook(rel, release.HookPostInstall, i.Timeout); err != nil {
return i.failRelease(rel, fmt.Errorf("failed post-install: %s", err)) i.reportToRun(c, rel, fmt.Errorf("failed post-install: %s", err))
return
} }
} }
@ -387,9 +407,26 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
i.cfg.Log("failed to record the release: %s", err) i.cfg.Log("failed to record the release: %s", err)
} }
return rel, nil i.reportToRun(c, rel, nil)
}
func (i *Install) handleSignals(c chan<- resultMessage, rel *release.Release) {
// Handle SIGINT
cSignal := make(chan os.Signal)
signal.Notify(cSignal, os.Interrupt, syscall.SIGTERM)
go func() {
<-cSignal
i.cfg.Log("SIGTERM or SIGINT received")
i.reportToRun(c, rel, fmt.Errorf("SIGTERM or SIGINT received, release failed"))
}()
}
func (i *Install) reportToRun(c chan<- resultMessage, rel *release.Release, err error) {
installLock.Lock()
if err != nil {
rel, err = i.failRelease(rel, err)
}
c <- resultMessage{r: rel, e: err}
installLock.Unlock()
} }
func (i *Install) failRelease(rel *release.Release, err error) (*release.Release, error) { func (i *Install) failRelease(rel *release.Release, err error) (*release.Release, error) {
rel.SetStatus(release.StatusFailed, fmt.Sprintf("Release %q failed: %s", i.ReleaseName, err.Error())) rel.SetStatus(release.StatusFailed, fmt.Sprintf("Release %q failed: %s", i.ReleaseName, err.Error()))
if i.Atomic { if i.Atomic {

@ -40,7 +40,7 @@ import (
"helm.sh/helm/v3/pkg/storage/driver" "helm.sh/helm/v3/pkg/storage/driver"
) )
var mutex sync.Mutex var upgradeLock sync.Mutex
// Upgrade is the action for upgrading releases. // Upgrade is the action for upgrading releases.
// //
@ -326,12 +326,12 @@ func (u *Upgrade) performUpgrade(originalRelease, upgradedRelease *release.Relea
} }
func (u *Upgrade) reportToPerformUpgrade(c chan<- resultMessage, rel *release.Release, created kube.ResourceList, err error) { func (u *Upgrade) reportToPerformUpgrade(c chan<- resultMessage, rel *release.Release, created kube.ResourceList, err error) {
mutex.Lock() upgradeLock.Lock()
if err != nil { if err != nil {
rel, err = u.failRelease(rel, created, err) rel, err = u.failRelease(rel, created, err)
} }
c <- resultMessage{r: rel, e: err} c <- resultMessage{r: rel, e: err}
mutex.Unlock() upgradeLock.Unlock()
} }
func (u *Upgrade) handleSignals(c chan<- resultMessage, upgradedRelease *release.Release) { func (u *Upgrade) handleSignals(c chan<- resultMessage, upgradedRelease *release.Release) {
// Handle SIGINT // Handle SIGINT

Loading…
Cancel
Save