diff --git a/api/http/handler/stacks/create_compose_stack.go b/api/http/handler/stacks/create_compose_stack.go index 6ceab991c..fb3688dbf 100644 --- a/api/http/handler/stacks/create_compose_stack.go +++ b/api/http/handler/stacks/create_compose_stack.go @@ -7,6 +7,7 @@ import ( "regexp" "strconv" "strings" + "time" "github.com/asaskevich/govalidator" httperror "github.com/portainer/libhttp/error" @@ -60,13 +61,14 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter, stackID := handler.DataStore.Stack().GetNextIdentifier() stack := &portainer.Stack{ - ID: portainer.StackID(stackID), - Name: payload.Name, - Type: portainer.DockerComposeStack, - EndpointID: endpoint.ID, - EntryPoint: filesystem.ComposeFileDefaultName, - Env: payload.Env, - Status: portainer.StackStatusActive, + ID: portainer.StackID(stackID), + Name: payload.Name, + Type: portainer.DockerComposeStack, + EndpointID: endpoint.ID, + EntryPoint: filesystem.ComposeFileDefaultName, + Env: payload.Env, + Status: portainer.StackStatusActive, + CreationDate: time.Now().Unix(), } stackFolder := strconv.Itoa(int(stack.ID)) @@ -146,13 +148,14 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite stackID := handler.DataStore.Stack().GetNextIdentifier() stack := &portainer.Stack{ - ID: portainer.StackID(stackID), - Name: payload.Name, - Type: portainer.DockerComposeStack, - EndpointID: endpoint.ID, - EntryPoint: payload.ComposeFilePathInRepository, - Env: payload.Env, - Status: portainer.StackStatusActive, + ID: portainer.StackID(stackID), + Name: payload.Name, + Type: portainer.DockerComposeStack, + EndpointID: endpoint.ID, + EntryPoint: payload.ComposeFilePathInRepository, + Env: payload.Env, + Status: portainer.StackStatusActive, + CreationDate: time.Now().Unix(), } projectPath := handler.FileService.GetStackProjectPath(strconv.Itoa(int(stack.ID))) @@ -242,13 +245,14 @@ func (handler *Handler) createComposeStackFromFileUpload(w http.ResponseWriter, stackID := handler.DataStore.Stack().GetNextIdentifier() stack := &portainer.Stack{ - ID: portainer.StackID(stackID), - Name: payload.Name, - Type: portainer.DockerComposeStack, - EndpointID: endpoint.ID, - EntryPoint: filesystem.ComposeFileDefaultName, - Env: payload.Env, - Status: portainer.StackStatusActive, + ID: portainer.StackID(stackID), + Name: payload.Name, + Type: portainer.DockerComposeStack, + EndpointID: endpoint.ID, + EntryPoint: filesystem.ComposeFileDefaultName, + Env: payload.Env, + Status: portainer.StackStatusActive, + CreationDate: time.Now().Unix(), } stackFolder := strconv.Itoa(int(stack.ID)) diff --git a/api/http/handler/stacks/create_swarm_stack.go b/api/http/handler/stacks/create_swarm_stack.go index 0113e8a41..bd65f3e3b 100644 --- a/api/http/handler/stacks/create_swarm_stack.go +++ b/api/http/handler/stacks/create_swarm_stack.go @@ -6,6 +6,7 @@ import ( "path" "strconv" "strings" + "time" "github.com/asaskevich/govalidator" httperror "github.com/portainer/libhttp/error" @@ -55,14 +56,15 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r stackID := handler.DataStore.Stack().GetNextIdentifier() stack := &portainer.Stack{ - ID: portainer.StackID(stackID), - Name: payload.Name, - Type: portainer.DockerSwarmStack, - SwarmID: payload.SwarmID, - EndpointID: endpoint.ID, - EntryPoint: filesystem.ComposeFileDefaultName, - Env: payload.Env, - Status: portainer.StackStatusActive, + ID: portainer.StackID(stackID), + Name: payload.Name, + Type: portainer.DockerSwarmStack, + SwarmID: payload.SwarmID, + EndpointID: endpoint.ID, + EntryPoint: filesystem.ComposeFileDefaultName, + Env: payload.Env, + Status: portainer.StackStatusActive, + CreationDate: time.Now().Unix(), } stackFolder := strconv.Itoa(int(stack.ID)) @@ -145,14 +147,15 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, stackID := handler.DataStore.Stack().GetNextIdentifier() stack := &portainer.Stack{ - ID: portainer.StackID(stackID), - Name: payload.Name, - Type: portainer.DockerSwarmStack, - SwarmID: payload.SwarmID, - EndpointID: endpoint.ID, - EntryPoint: payload.ComposeFilePathInRepository, - Env: payload.Env, - Status: portainer.StackStatusActive, + ID: portainer.StackID(stackID), + Name: payload.Name, + Type: portainer.DockerSwarmStack, + SwarmID: payload.SwarmID, + EndpointID: endpoint.ID, + EntryPoint: payload.ComposeFilePathInRepository, + Env: payload.Env, + Status: portainer.StackStatusActive, + CreationDate: time.Now().Unix(), } projectPath := handler.FileService.GetStackProjectPath(strconv.Itoa(int(stack.ID))) @@ -249,14 +252,15 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r stackID := handler.DataStore.Stack().GetNextIdentifier() stack := &portainer.Stack{ - ID: portainer.StackID(stackID), - Name: payload.Name, - Type: portainer.DockerSwarmStack, - SwarmID: payload.SwarmID, - EndpointID: endpoint.ID, - EntryPoint: filesystem.ComposeFileDefaultName, - Env: payload.Env, - Status: portainer.StackStatusActive, + ID: portainer.StackID(stackID), + Name: payload.Name, + Type: portainer.DockerSwarmStack, + SwarmID: payload.SwarmID, + EndpointID: endpoint.ID, + EntryPoint: filesystem.ComposeFileDefaultName, + Env: payload.Env, + Status: portainer.StackStatusActive, + CreationDate: time.Now().Unix(), } stackFolder := strconv.Itoa(int(stack.ID)) diff --git a/api/http/handler/stacks/stack_update.go b/api/http/handler/stacks/stack_update.go index df4178f8f..4ee04f5f9 100644 --- a/api/http/handler/stacks/stack_update.go +++ b/api/http/handler/stacks/stack_update.go @@ -4,6 +4,7 @@ import ( "errors" "net/http" "strconv" + "time" "github.com/asaskevich/govalidator" httperror "github.com/portainer/libhttp/error" @@ -123,6 +124,7 @@ func (handler *Handler) updateComposeStack(r *http.Request, stack *portainer.Sta } stack.Env = payload.Env + stack.UpdateDate = time.Now().Unix() stackFolder := strconv.Itoa(int(stack.ID)) _, err = handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent)) @@ -151,6 +153,7 @@ func (handler *Handler) updateSwarmStack(r *http.Request, stack *portainer.Stack } stack.Env = payload.Env + stack.UpdateDate = time.Now().Unix() stackFolder := strconv.Itoa(int(stack.ID)) _, err = handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent)) diff --git a/api/portainer.go b/api/portainer.go index e68e0c223..4a98d4d89 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -554,6 +554,8 @@ type ( Env []Pair `json:"Env"` ResourceControl *ResourceControl `json:"ResourceControl"` Status StackStatus `json:"Status"` + CreationDate int64 `json:"CreationDate"` + UpdateDate int64 `json:"UpdateDate"` ProjectPath string } diff --git a/app/portainer/components/datatables/stacks-datatable/stacksDatatable.html b/app/portainer/components/datatables/stacks-datatable/stacksDatatable.html index 1bd2c313d..a2ff2eb58 100644 --- a/app/portainer/components/datatables/stacks-datatable/stacksDatatable.html +++ b/app/portainer/components/datatables/stacks-datatable/stacksDatatable.html @@ -117,6 +117,20 @@