Skip to content

Commit

Permalink
1.5.2 (#17)
Browse files Browse the repository at this point in the history
* Bumped version to 1.5.2

* Compose actions moved to definition. Implemented Deploy action (Pull+Up)
  • Loading branch information
salilponde authored Dec 26, 2023
1 parent 12fa52b commit 72dd280
Show file tree
Hide file tree
Showing 21 changed files with 508 additions and 307 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
branches: ["main"]

env:
VERSION: "1.5.1"
VERSION: "1.5.2"

jobs:
docker:
Expand Down
4 changes: 3 additions & 1 deletion pkg/agent/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func startTaskSession(tqm messages.TaskQueuedMessage) {

stream := false
steamMessageTypes := []string{"DockerContainerLogs", "DockerContainerTerminal",
"DockerComposePull", "DockerComposeUp", "DockerComposeDown", "DockerComposeLogs"}
"DockerComposeDeploy", "DockerComposePull","DockerComposePull", "DockerComposeUp", "DockerComposeDown", "DockerComposeLogs"}
if slices.Contains(steamMessageTypes, messageType) {
stream = true
}
Expand Down Expand Up @@ -80,6 +80,8 @@ func startTaskSession(tqm messages.TaskQueuedMessage) {
handleDockerComposeContainerList(c, taskDefinition)
case "DockerComposeLogs":
handleDockerComposeLogs(c, taskDefinition)
case "DockerComposeDeploy":
handleDockerComposeDeploy(c, taskDefinition)
case "DockerComposePull":
handleDockerComposePull(c, taskDefinition)
case "DockerComposeUp":
Expand Down
16 changes: 16 additions & 0 deletions pkg/agent/tasks_compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ func handleDockerComposeLogs(c *websocket.Conn, messageString string) {
}
}

func handleDockerComposeDeploy(c *websocket.Conn, messageString string) {
m, err := messages.Parse[dockerapi.DockerComposeDeploy](messageString)
if err != nil {
err := completedWithFailure(c, "Error parsing request message")
if err != nil {
log.Debug().Err(err).Msg("Error sending message to client")
}
return
}

err = dockerapi.ComposeDeploy(m, c)
if err != nil {
log.Debug().Err(err).Msg("Error sending message to client")
}
}

func handleDockerComposePull(c *websocket.Conn, messageString string) {
m, err := messages.Parse[dockerapi.DockerComposePull](messageString)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/common/common.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package common

const Version = "1.5.1"
const Version = "1.5.2"
129 changes: 43 additions & 86 deletions pkg/dockerapi/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,11 @@ func toEnvFormat(variables map[string]store.VariableValue) ([]string) {
return ret
}

func processVars(cmd *exec.Cmd, variables map[string]store.VariableValue, ws *websocket.Conn) {
func processVars(cmd *exec.Cmd, variables map[string]store.VariableValue, ws *websocket.Conn, print bool) {
cmd.Env = os.Environ()
ws.WriteMessage(websocket.TextMessage, []byte("Setting below variables:\n"))
if print {
ws.WriteMessage(websocket.TextMessage, []byte("*** SETTING BELOW VARIABLES: ***\n\n"))
}

keys := make([]string, 0)
for k, _ := range variables {
Expand All @@ -194,17 +196,18 @@ func processVars(cmd *exec.Cmd, variables map[string]store.VariableValue, ws *we
if !variables[k].IsSecret {
val = *variables[k].Value
}
ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("%s=%s\n", k, val)))
if print {
ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("%s=%s\n", k, val)))
}
}

for _, v := range toEnvFormat(variables) {
cmd.Env = append(cmd.Env, v)
}
}

func ComposePull(req *DockerComposePull, ws *websocket.Conn) error {
go discardIncomingMessages(ws)

dir, file, err := createTempComposeFile(req.ProjectName, req.Definition)
func performComposeAction(action string, projectName string, definition string, variables map[string]store.VariableValue, ws *websocket.Conn, printVars bool) error {
dir, file, err := createTempComposeFile(projectName, definition)
log.Debug().Str("fileName", file).Msg("Created temporary compose file")
if err != nil {
return err
Expand All @@ -213,11 +216,21 @@ func ComposePull(req *DockerComposePull, ws *websocket.Conn) error {
log.Debug().Str("fileName", file).Msg("Deleting temporary compose file")
os.RemoveAll(dir)
}()

var cmd *exec.Cmd
switch action {
case "up":
cmd = exec.Command("docker-compose", "-p", projectName, "-f", file, action, "-d")
case "down":
cmd = exec.Command("docker-compose", "-p", projectName, action)
case "pull":
cmd = exec.Command("docker-compose", "-p", projectName, "-f", file, action)
default:
panic(fmt.Errorf("unknown compose action %s", action))
}
processVars(cmd, variables, ws, printVars)

cmd := exec.Command("docker-compose", "-p", req.ProjectName, "-f", file, "pull")
processVars(cmd, req.Variables, ws)

ws.WriteMessage(websocket.TextMessage, []byte("\nStarting action: Compose Pull\n"))
ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("\n*** STARTING ACTION: %s ***\n\n", action)))
f, err := pty.Start(cmd)
if err != nil {
log.Error().Err(err).Msg("pty returned error")
Expand All @@ -243,99 +256,43 @@ func ComposePull(req *DockerComposePull, ws *websocket.Conn) error {
}

err = cmd.Wait()
ws.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("\n*** COMPLETED ACTION: %s ***\n\n", action)))

if err != nil {
log.Error().Err(err).Msg("Error executing compose pull")
log.Error().Err(err).Msg(fmt.Sprintf("Error executing compose %s", action))
}

log.Debug().Msg("compose pull session closed")
return nil
}

func ComposeUp(req *DockerComposeUp, ws *websocket.Conn) error {
func ComposeDeploy(req *DockerComposeDeploy, ws *websocket.Conn) error {
go discardIncomingMessages(ws)

dir, file, err := createTempComposeFile(req.ProjectName, req.Definition)
log.Debug().Str("fileName", file).Msg("Created temporary compose file")
if err != nil {
return err
}
defer func() {
log.Debug().Str("fileName", file).Msg("Deleting temporary compose file")
os.RemoveAll(dir)
}()

cmd := exec.Command("docker-compose", "-p", req.ProjectName, "-f", file, "up", "-d")
processVars(cmd, req.Variables, ws)

ws.WriteMessage(websocket.TextMessage, []byte("\nStarting action: Compose Up\n"))
f, err := pty.Start(cmd)
err := performComposeAction("pull", req.ProjectName, req.Definition, req.Variables, ws, true)
if err != nil {
log.Error().Err(err).Msg("pty returned error")
return err
}
err = performComposeAction("up", req.ProjectName, req.Definition, req.Variables, ws, false)

b := make([]byte, 1024)
for {
n, err := f.Read(b)
if n == 0 {
break
}
if err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("Error while reading from pty")
}
break
}
_ = ws.WriteMessage(websocket.BinaryMessage, b[:n])
// We ignore websocket write errors. This is because
// we don't want to terminate the command execution in between
// causing unexpected state
}
return err
}

err = cmd.Wait()
if err != nil {
log.Error().Err(err).Msg("Error executing compose up")
}
func ComposePull(req *DockerComposePull, ws *websocket.Conn) error {
go discardIncomingMessages(ws)
err := performComposeAction("pull", req.ProjectName, req.Definition, req.Variables, ws, true)
return err
}

log.Debug().Msg("compose up session closed")
return nil
func ComposeUp(req *DockerComposeUp, ws *websocket.Conn) error {
go discardIncomingMessages(ws)
err := performComposeAction("up", req.ProjectName, req.Definition, req.Variables, ws, true)
return err
}

func ComposeDown(req *DockerComposeDown, ws *websocket.Conn) error {
go discardIncomingMessages(ws)

cmd := exec.Command("docker-compose", "-p", req.ProjectName, "down")
f, err := pty.Start(cmd)
if err != nil {
log.Error().Err(err).Msg("pty returned error")
return err
}

b := make([]byte, 1024)
for {
n, err := f.Read(b)
if n == 0 {
break
}
if err != nil {
if err != io.EOF {
log.Error().Err(err).Msg("Error while reading from pty")
}
break
}
_ = ws.WriteMessage(websocket.BinaryMessage, b[:n])
// We ignore websocket write errors. This is because
// we don't want to terminate the command execution in between
// causing unexpected state
}

err = cmd.Wait()
if err != nil {
log.Error().Err(err).Msg("Error executing compose down")
}

log.Debug().Msg("compose down session closed")
return nil
err := performComposeAction("down", req.ProjectName, "", nil, ws, true)
return err
}

func ComposeDownNoStreaming(req *DockerComposeDownNoStreaming) error {
Expand Down
6 changes: 6 additions & 0 deletions pkg/dockerapi/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ type DockerComposeLogs struct {
ProjectName string `json:"projectName"`
}

type DockerComposeDeploy struct {
ProjectName string `json:"projectName"`
Definition string `json:"definition"`
Variables map[string]store.VariableValue `json:"variables"`
}

type DockerComposePull struct {
ProjectName string `json:"projectName"`
Definition string `json:"definition"`
Expand Down
1 change: 1 addition & 0 deletions pkg/server/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ func (h *Handler) Register(e *echo.Echo) {
node_compose_project.DELETE("/:id", h.DeleteNodeComposeProject)
node_compose_project.GET("/:id/containers", h.GetNodeComposeContainerList)
node_compose_project.GET("/:id/logs", h.GetNodeComposeLogs)
node_compose_project.GET("/:id/deploy", h.GetNodeComposeDeploy)
node_compose_project.GET("/:id/pull", h.GetNodeComposePull)
node_compose_project.GET("/:id/up", h.GetNodeComposeUp)
node_compose_project.GET("/:id/down", h.GetNodeComposeDown)
Expand Down
56 changes: 56 additions & 0 deletions pkg/server/handler/node_compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,62 @@ func (h *Handler) getComposeVariables(environmentId *uint, nodeComposeProjectId
return variables
}

func (h *Handler) GetNodeComposeDeploy(c echo.Context) error {
nodeId, err := strconv.Atoi(c.Param("nodeId"))
if err != nil {
return unprocessableEntity(c, errors.New("nodeId should be an integer"))
}

id, err := strconv.Atoi(c.Param("id"))
if err != nil {
return unprocessableEntity(c, errors.New("id should be an integer"))
}

ncp, err := h.nodeComposeProjectStore.GetById(uint(nodeId), uint(id))
if err != nil {
return unprocessableEntity(c, errors.New("Project not found"))
}

definition, err := h.getComposeProjectDefinition(ncp)
if err != nil {
return unprocessableEntity(c, err)
}

environmentId := ncp.EnvironmentId
if ncp.EnvironmentId == nil {
node, err := h.nodeStore.GetById(uint(nodeId))
if err != nil {
return unprocessableEntity(c, errors.New("Node not found"))
}

environmentId = node.EnvironmentId
}

variables := h.getComposeVariables(environmentId, uint(id))

ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
if err != nil {
log.Error().Err(err).Msg("Error while upgrading from http to websocket")
return err
}
defer ws.Close()

req := dockerapi.DockerComposeDeploy{ProjectName: ncp.ProjectName, Definition: definition, Variables: variables}
if nodeId == 1 {
err := dockerapi.ComposeDeploy(&req, ws)
if err != nil {
log.Debug().Err(err).Msg("Error while calling ComposeDeploy")
}
} else {
err = messages.ProcessStreamTask[dockerapi.DockerComposeDeploy](uint(nodeId), req, ws)
if err != nil {
log.Debug().Err(err).Msg("Error while calling ComposeDeploy ProcessStreamTask")
}
}

return nil
}

func (h *Handler) GetNodeComposePull(c echo.Context) error {
nodeId, err := strconv.Atoi(c.Param("nodeId"))
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions runserver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ go build ./cmd/server
export DB_CONNECTION_STRING="/tmp/db"
export DATA_PATH="/tmp"
export LOG_LEVEL="DEBUG"
export SSL_ENABLED="0"
./server
Loading

0 comments on commit 72dd280

Please sign in to comment.