Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: project uptime #382

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions internal/util/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,28 @@ func FormatCreatedTime(input string) string {
}
}

func FormatStatusTime(input string) string {
t, err := time.Parse(timeLayout, input)
if err != nil {
return "stopped"
}

duration := time.Since(t)
func FormatUptime(uptime int32) string {
duration := time.Duration(uptime) * time.Second

if duration < time.Minute {
return "up < 1 minute"
return "< 1 minute"
} else if duration < time.Hour {
minutes := int(duration.Minutes())
if minutes == 1 {
return "up 1 minute"
return "1 minute"
}
return fmt.Sprintf("up %d minutes", minutes)
return fmt.Sprintf("%d minutes", minutes)
} else if duration < 24*time.Hour {
hours := int(duration.Hours())
if hours == 1 {
return "up 1 hour"
return "1 hour"
}
return fmt.Sprintf("up %d hours", hours)
return fmt.Sprintf("%d hours", hours)
} else {
days := int(duration.Hours() / 24)
if days == 1 {
return "up 1 day"
return "1 day"
}
return fmt.Sprintf("up %d days", days)
return fmt.Sprintf("%d days", days)
}
}
36 changes: 36 additions & 0 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"net/url"
"time"

"github.com/daytonaio/daytona/cmd/daytona/config"
"github.com/daytonaio/daytona/internal/util/apiclient"
Expand All @@ -19,6 +20,8 @@ import (
func (a *Agent) Start() error {
log.Info("Starting Daytona Agent")

a.startTime = time.Now()

err := a.setDefaultConfig()
if err != nil {
return err
Expand Down Expand Up @@ -78,6 +81,17 @@ func (a *Agent) Start() error {
}
}()

go func() {
for {
err := a.updateProjectState()
if err != nil {
log.Error(fmt.Sprintf("failed to update project state: %s", err))
}

time.Sleep(2 * time.Second)
}
}()

return a.Tailscale.Start()
}

Expand Down Expand Up @@ -162,3 +176,25 @@ func (a *Agent) setDefaultConfig() error {

return config.Save()
}

// Agent uptime in seconds
func (a *Agent) uptime() int32 {
return int32(time.Since(a.startTime).Seconds())
}

func (a *Agent) updateProjectState() error {
apiClient, err := server.GetApiClient(nil)
if err != nil {
return err
}

uptime := a.uptime()
res, err := apiClient.WorkspaceAPI.SetProjectState(context.Background(), a.Config.WorkspaceId, a.Config.ProjectName).SetState(serverapiclient.SetProjectState{
Uptime: &uptime,
}).Execute()
if err != nil {
return apiclient.HandleErrorResponse(res, err)
}

return nil
}
3 changes: 3 additions & 0 deletions pkg/agent/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package agent

import (
"time"

"github.com/daytonaio/daytona/pkg/agent/config"
"github.com/daytonaio/daytona/pkg/serverapiclient"
)
Expand All @@ -27,4 +29,5 @@ type Agent struct {
Git GitService
Ssh SshServer
Tailscale TailscaleServer
startTime time.Time
}
4 changes: 4 additions & 0 deletions pkg/api/controllers/workspace/dto/dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ type CreateWorkspace struct {
Target string
Repositories []gitprovider.GitRepository
} // @name CreateWorkspace

type SetProjectState struct {
Uptime uint64 `json:"uptime"`
} // @name SetProjectState
52 changes: 52 additions & 0 deletions pkg/api/controllers/workspace/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2024 Daytona Platforms Inc.
// SPDX-License-Identifier: Apache-2.0

package workspace

import (
"fmt"
"net/http"
"time"

"github.com/daytonaio/daytona/pkg/api/controllers/workspace/dto"
"github.com/daytonaio/daytona/pkg/server"
"github.com/daytonaio/daytona/pkg/workspace"
"github.com/gin-gonic/gin"
)

// SetProjectState godoc
//
// @Tags workspace
// @Summary Set project state
// @Description Set project state
// @Param workspaceId path string true "Workspace ID or Name"
// @Param projectId path string true "Project ID"
// @Param setState body SetProjectState true "Set State"
// @Success 200
// @Router /workspace/{workspaceId}/{projectId}/state [post]
//
// @id SetProjectState
func SetProjectState(ctx *gin.Context) {
workspaceId := ctx.Param("workspaceId")
projectId := ctx.Param("projectId")

var setProjectStateDTO dto.SetProjectState
err := ctx.BindJSON(&setProjectStateDTO)
if err != nil {
ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error()))
return
}

server := server.GetInstance(nil)

_, err = server.WorkspaceService.SetProjectState(workspaceId, projectId, &workspace.ProjectState{
Uptime: setProjectStateDTO.Uptime,
UpdatedAt: time.Now().Format(time.RFC1123),
})
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %s", workspaceId, err.Error()))
return
}

ctx.Status(200)
}
68 changes: 62 additions & 6 deletions pkg/api/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,46 @@ const docTemplate = `{
}
}
},
"/workspace/{workspaceId}/{projectId}/state": {
"post": {
"description": "Set project state",
"tags": [
"workspace"
],
"summary": "Set project state",
"operationId": "SetProjectState",
"parameters": [
{
"type": "string",
"description": "Workspace ID or Name",
"name": "workspaceId",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Project ID",
"name": "projectId",
"in": "path",
"required": true
},
{
"description": "Set State",
"name": "setState",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/SetProjectState"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/workspace/{workspaceId}/{projectId}/stop": {
"post": {
"description": "Stop project",
Expand Down Expand Up @@ -1085,6 +1125,9 @@ const docTemplate = `{
"repository": {
"$ref": "#/definitions/GitRepository"
},
"state": {
"$ref": "#/definitions/ProjectState"
},
"target": {
"type": "string"
},
Expand All @@ -1099,9 +1142,6 @@ const docTemplate = `{
"created": {
"type": "string"
},
"finished": {
"type": "string"
},
"isRunning": {
"type": "boolean"
},
Expand All @@ -1111,14 +1151,22 @@ const docTemplate = `{
"providerMetadata": {
"type": "string"
},
"started": {
"type": "string"
},
"workspaceId": {
"type": "string"
}
}
},
"ProjectState": {
"type": "object",
"properties": {
"updatedAt": {
"type": "string"
},
"uptime": {
"type": "integer"
}
}
},
"Provider": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -1183,6 +1231,14 @@ const docTemplate = `{
}
}
},
"SetProjectState": {
"type": "object",
"properties": {
"uptime": {
"type": "integer"
}
}
},
"Workspace": {
"type": "object",
"properties": {
Expand Down
68 changes: 62 additions & 6 deletions pkg/api/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,46 @@
}
}
},
"/workspace/{workspaceId}/{projectId}/state": {
"post": {
"description": "Set project state",
"tags": [
"workspace"
],
"summary": "Set project state",
"operationId": "SetProjectState",
"parameters": [
{
"type": "string",
"description": "Workspace ID or Name",
"name": "workspaceId",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Project ID",
"name": "projectId",
"in": "path",
"required": true
},
{
"description": "Set State",
"name": "setState",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/SetProjectState"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/workspace/{workspaceId}/{projectId}/stop": {
"post": {
"description": "Stop project",
Expand Down Expand Up @@ -1082,6 +1122,9 @@
"repository": {
"$ref": "#/definitions/GitRepository"
},
"state": {
"$ref": "#/definitions/ProjectState"
},
"target": {
"type": "string"
},
Expand All @@ -1096,9 +1139,6 @@
"created": {
"type": "string"
},
"finished": {
"type": "string"
},
"isRunning": {
"type": "boolean"
},
Expand All @@ -1108,14 +1148,22 @@
"providerMetadata": {
"type": "string"
},
"started": {
"type": "string"
},
"workspaceId": {
"type": "string"
}
}
},
"ProjectState": {
"type": "object",
"properties": {
"updatedAt": {
"type": "string"
},
"uptime": {
"type": "integer"
}
}
},
"Provider": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -1180,6 +1228,14 @@
}
}
},
"SetProjectState": {
"type": "object",
"properties": {
"uptime": {
"type": "integer"
}
}
},
"Workspace": {
"type": "object",
"properties": {
Expand Down
Loading
Loading