Compare commits
5 Commits
fix/r8s-12
...
feat/EE-26
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e79639da34 | ||
|
|
e67555102c | ||
|
|
43ad2ab22a | ||
|
|
2351771340 | ||
|
|
e2e35777f5 |
@@ -19,7 +19,7 @@ func startAutoupdate(stackID portainer.StackID, interval string, scheduler *sche
|
||||
}
|
||||
|
||||
jobID = scheduler.StartJobEvery(d, func() error {
|
||||
return stacks.RedeployWhenChanged(stackID, stackDeployer, datastore, gitService)
|
||||
return stacks.RedeployWhenChanged(stackID, stackDeployer, datastore, gitService, nil)
|
||||
})
|
||||
|
||||
return jobID, nil
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/portainer/libhttp/response"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/stacks"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
@@ -31,6 +32,7 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h
|
||||
}
|
||||
|
||||
stack, err := handler.DataStore.Stack().StackByWebhookID(webhookID.String())
|
||||
|
||||
if err != nil {
|
||||
statusCode := http.StatusInternalServerError
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
@@ -39,7 +41,15 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h
|
||||
return &httperror.HandlerError{StatusCode: statusCode, Message: "Unable to find the stack by webhook ID", Err: err}
|
||||
}
|
||||
|
||||
if err = stacks.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService); err != nil {
|
||||
envs := []portainer.Pair{}
|
||||
for key, value := range r.URL.Query() {
|
||||
envs = append(envs, portainer.Pair{
|
||||
Name: key,
|
||||
Value: value[len(value)-1],
|
||||
})
|
||||
}
|
||||
|
||||
if err = stacks.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService, envs); err != nil {
|
||||
if _, ok := err.(*stacks.StackAuthorMissingErr); ok {
|
||||
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Autoupdate for the stack isn't available", Err: err}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func (e *StackAuthorMissingErr) Error() string {
|
||||
|
||||
// RedeployWhenChanged pull and redeploy the stack when git repo changed
|
||||
// Stack will always be redeployed if force deployment is set to true
|
||||
func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService) error {
|
||||
func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService, additionalEnv []portainer.Pair) error {
|
||||
logger := log.WithFields(log.Fields{"stackID": stackID})
|
||||
logger.Debug("redeploying stack")
|
||||
|
||||
@@ -32,6 +32,28 @@ func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, data
|
||||
return errors.WithMessagef(err, "failed to get the stack %v", stackID)
|
||||
}
|
||||
|
||||
for _, env := range additionalEnv {
|
||||
exist := false
|
||||
for index, stackEnv := range stack.Env {
|
||||
if env.Name == stackEnv.Name {
|
||||
fmt.Println("found")
|
||||
stack.Env[index] = portainer.Pair{
|
||||
Name: env.Name,
|
||||
Value: env.Value,
|
||||
}
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !exist {
|
||||
stack.Env = append(stack.Env, portainer.Pair{
|
||||
Name: env.Name,
|
||||
Value: env.Value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if stack.GitConfig == nil {
|
||||
return nil // do nothing if it isn't a git-based stack
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ func Test_redeployWhenChanged_FailsWhenCannotFindStack(t *testing.T) {
|
||||
_, store, teardown := datastore.MustNewTestStore(true, true)
|
||||
defer teardown()
|
||||
|
||||
err := RedeployWhenChanged(1, nil, store, nil)
|
||||
err := RedeployWhenChanged(1, nil, store, nil, nil)
|
||||
assert.Error(t, err)
|
||||
assert.Truef(t, strings.HasPrefix(err.Error(), "failed to get the stack"), "it isn't an error we expected: %v", err.Error())
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func Test_redeployWhenChanged_DoesNothingWhenNotAGitBasedStack(t *testing.T) {
|
||||
err = store.Stack().Create(&portainer.Stack{ID: 1, CreatedBy: "admin"})
|
||||
assert.NoError(t, err, "failed to create a test stack")
|
||||
|
||||
err = RedeployWhenChanged(1, nil, store, &gitService{nil, ""})
|
||||
err = RedeployWhenChanged(1, nil, store, &gitService{nil, ""}, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func Test_redeployWhenChanged_DoesNothingWhenNoGitChanges(t *testing.T) {
|
||||
}})
|
||||
assert.NoError(t, err, "failed to create a test stack")
|
||||
|
||||
err = RedeployWhenChanged(1, nil, store, &gitService{nil, "oldHash"})
|
||||
err = RedeployWhenChanged(1, nil, store, &gitService{nil, "oldHash"}, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -108,12 +108,12 @@ func Test_redeployWhenChanged_FailsWhenCannotClone(t *testing.T) {
|
||||
}})
|
||||
assert.NoError(t, err, "failed to create a test stack")
|
||||
|
||||
err = RedeployWhenChanged(1, nil, store, &gitService{cloneErr, "newHash"})
|
||||
err = RedeployWhenChanged(1, nil, store, &gitService{cloneErr, "newHash"}, nil)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, cloneErr, "should failed to clone but didn't, check test setup")
|
||||
}
|
||||
|
||||
func Test_redeployWhenChanged(t *testing.T) {
|
||||
func Test_redeployWhenChanged_WithAdditionalEnv(t *testing.T) {
|
||||
_, store, teardown := datastore.MustNewTestStore(true, true)
|
||||
defer teardown()
|
||||
|
||||
@@ -139,11 +139,13 @@ func Test_redeployWhenChanged(t *testing.T) {
|
||||
err = store.Stack().Create(&stack)
|
||||
assert.NoError(t, err, "failed to create a test stack")
|
||||
|
||||
additionalEnvs := []portainer.Pair{{Name: "version", Value: "latest"}}
|
||||
|
||||
t.Run("can deploy docker compose stack", func(t *testing.T) {
|
||||
stack.Type = portainer.DockerComposeStack
|
||||
store.Stack().UpdateStack(stack.ID, &stack)
|
||||
|
||||
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"})
|
||||
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"}, additionalEnvs)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
@@ -151,7 +153,7 @@ func Test_redeployWhenChanged(t *testing.T) {
|
||||
stack.Type = portainer.DockerSwarmStack
|
||||
store.Stack().UpdateStack(stack.ID, &stack)
|
||||
|
||||
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"})
|
||||
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"}, additionalEnvs)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
@@ -159,7 +161,7 @@ func Test_redeployWhenChanged(t *testing.T) {
|
||||
stack.Type = portainer.KubernetesStack
|
||||
store.Stack().UpdateStack(stack.ID, &stack)
|
||||
|
||||
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"})
|
||||
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"}, additionalEnvs)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func StartStackSchedules(scheduler *scheduler.Scheduler, stackdeployer StackDepl
|
||||
}
|
||||
stackID := stack.ID // to be captured by the scheduled function
|
||||
jobID := scheduler.StartJobEvery(d, func() error {
|
||||
return RedeployWhenChanged(stackID, stackdeployer, datastore, gitService)
|
||||
return RedeployWhenChanged(stackID, stackdeployer, datastore, gitService, nil)
|
||||
})
|
||||
|
||||
stack.AutoUpdate.JobID = jobID
|
||||
|
||||
Reference in New Issue
Block a user