/
workspace.go
120 lines (112 loc) · 3.66 KB
/
workspace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package controllers
import (
"context"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"docker.io/go-docker/api/types"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/scaleshift/scaleshift/api/src/config"
"github.com/scaleshift/scaleshift/api/src/db"
"github.com/scaleshift/scaleshift/api/src/generated/models"
"github.com/scaleshift/scaleshift/api/src/generated/restapi/operations"
"github.com/scaleshift/scaleshift/api/src/generated/restapi/operations/workspace"
"github.com/scaleshift/scaleshift/api/src/log"
)
func workspaceRoute(api *operations.ScaleShiftAPI) {
api.WorkspaceGetWorkspacesHandler = workspace.GetWorkspacesHandlerFunc(getWorkspaces)
api.WorkspaceDeleteWorkspaceHandler = workspace.DeleteWorkspaceHandlerFunc(deleteWorkspace)
}
func getWorkspaces(params workspace.GetWorkspacesParams) middleware.Responder {
files, err := ioutil.ReadDir(config.Config.WorkspaceContainerDir)
if err != nil {
log.Error("ReadDir@getWorkspaces", err, nil)
code := http.StatusInternalServerError
return workspace.NewGetWorkspacesDefault(code).WithPayload(newerror(code))
}
cli, _, code := dockerClient(nil)
if code != 0 {
return workspace.NewGetWorkspacesDefault(code).WithPayload(newerror(code))
}
defer cli.Close()
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{
Quiet: true,
All: true,
})
if err != nil {
log.Error("ContainerList@getWorkspaces", err, nil)
code := http.StatusBadRequest
return workspace.NewGetWorkspacesDefault(code).WithPayload(newerror(code))
}
jobs, err := db.GetJobs()
if err != nil {
log.Error("GetJobs@getWorkspaces", err, nil)
code := http.StatusBadRequest
return workspace.NewGetWorkspacesDefault(code).WithPayload(newerror(code))
}
payload := []*models.Workspace{}
for _, f := range files {
if f.IsDir() {
payload = append(payload, &models.Workspace{
Notebooks: findNotebooks(f.Name(), containers),
Jobs: findJobs(f.Name(), jobs),
Path: swag.String(f.Name()),
AbsolutePath: filepath.Join(config.Config.WorkspaceHostDir, f.Name()),
})
}
}
return workspace.NewGetWorkspacesOK().WithPayload(payload)
}
func findNotebooks(path string, containers []types.Container) []string {
notebooks := []string{}
for _, container := range containers {
isJupyter := false
if as, ok1 := container.Labels["com.scaleshift.image.built-as"]; ok1 {
if _, ok2 := container.Labels["com.scaleshift.container.publish"]; ok2 {
if strings.EqualFold(as, "jupyter-notebook") {
isJupyter = true
}
}
}
if !isJupyter {
continue
}
for _, mount := range container.Mounts {
src := strings.TrimPrefix(strings.Replace(mount.Source, config.Config.WorkspaceHostDir, "", -1), "/")
if path == src {
name := ""
if len(container.Names) > 0 {
name = strings.TrimPrefix(container.Names[0], "/")
}
notebooks = append(notebooks, name)
break
}
}
}
return notebooks
}
func findJobs(path string, jobs []*db.Job) []string {
result := []string{}
for _, job := range jobs {
for _, workspace := range strings.Split(job.Workspaces, ",") {
if strings.EqualFold(path, workspace) {
result = append(result, job.JobID)
break
}
}
}
return result
}
func deleteWorkspace(params workspace.DeleteWorkspaceParams) middleware.Responder {
path := filepath.Join(config.Config.WorkspaceContainerDir, swag.StringValue(params.Body.Path))
err := os.RemoveAll(path)
if err != nil {
log.Error("RemoveAll@deleteWorkspace", err, nil)
code := http.StatusInternalServerError
return workspace.NewDeleteWorkspaceDefault(code).WithPayload(newerror(code))
}
return workspace.NewDeleteWorkspaceNoContent()
}