|
1 | 1 | package cmd
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "bytes" |
5 | 4 | "context"
|
6 | 5 | "fmt"
|
7 |
| - "io" |
8 |
| - "os" |
9 |
| - "os/signal" |
10 | 6 | "path"
|
11 | 7 | "path/filepath"
|
12 |
| - "syscall" |
13 |
| - "time" |
14 | 8 |
|
| 9 | + "github.com/cortexlabs/cortex/cli/local" |
| 10 | + "github.com/cortexlabs/cortex/pkg/lib/debug" |
15 | 11 | "github.com/cortexlabs/cortex/pkg/lib/errors"
|
16 | 12 | "github.com/cortexlabs/cortex/pkg/lib/exit"
|
17 | 13 | "github.com/cortexlabs/cortex/pkg/lib/files"
|
| 14 | + "github.com/cortexlabs/cortex/pkg/lib/hash" |
18 | 15 | "github.com/cortexlabs/cortex/pkg/lib/prompt"
|
19 | 16 | s "github.com/cortexlabs/cortex/pkg/lib/strings"
|
| 17 | + "github.com/cortexlabs/cortex/pkg/lib/table" |
20 | 18 | "github.com/cortexlabs/cortex/pkg/lib/zip"
|
| 19 | + "github.com/cortexlabs/cortex/pkg/operator/schema" |
| 20 | + "github.com/cortexlabs/cortex/pkg/types/spec" |
| 21 | + "github.com/docker/docker/api/types" |
21 | 22 | dockertypes "github.com/docker/docker/api/types"
|
22 |
| - "github.com/docker/docker/api/types/container" |
23 |
| - "github.com/docker/docker/api/types/mount" |
24 |
| - "github.com/docker/go-connections/nat" |
| 23 | + "github.com/docker/docker/api/types/filters" |
25 | 24 | "github.com/spf13/cobra"
|
26 | 25 | )
|
27 | 26 |
|
28 |
| -var _localWorkSpace string |
29 |
| - |
30 | 27 | func init() {
|
31 | 28 | localCmd.PersistentFlags()
|
32 | 29 | addEnvFlag(localCmd)
|
33 |
| - _localWorkSpace = filepath.Join(_localDir, "local_workspace") |
34 |
| - |
35 | 30 | }
|
36 | 31 |
|
37 | 32 | func deploymentBytes(configPath string, force bool) map[string][]byte {
|
@@ -112,140 +107,121 @@ var localCmd = &cobra.Command{
|
112 | 107 | Long: "local an application.",
|
113 | 108 | Args: cobra.ExactArgs(0),
|
114 | 109 | Run: func(cmd *cobra.Command, args []string) {
|
115 |
| - docker, err := getDockerClient() |
| 110 | + configPath := getConfigPath(args) |
| 111 | + deploymentMap := deploymentBytes(configPath, false) |
| 112 | + projectFileMap, err := zip.UnzipMemToMem(deploymentMap["project.zip"]) |
116 | 113 | if err != nil {
|
117 |
| - panic(err) |
118 |
| - } |
119 |
| - |
120 |
| - // _localWorkSpace = filepath.Join(_localDir, "local_workspace") |
121 |
| - |
122 |
| - // configPath := getConfigPath(args) |
123 |
| - // deploymentMap := deploymentBytes(configPath, false) |
124 |
| - // projectFileMap, err := zip.UnzipMemToMem(deploymentMap["project.zip"]) |
125 |
| - // if err != nil { |
126 |
| - // exit.Error(err) |
127 |
| - // } |
128 |
| - |
129 |
| - // apiConfigs, err := spec.ExtractAPIConfigs(deploymentMap["config"], projectFileMap, configPath) |
130 |
| - // if err != nil { |
131 |
| - // exit.Error(err) |
132 |
| - // } |
133 |
| - |
134 |
| - // err = spec.ValidateLocalAPIs(apiConfigs, projectFileMap) |
135 |
| - // if err != nil { |
136 |
| - // exit.Error(err) |
137 |
| - // } |
138 |
| - |
139 |
| - // projectID := hash.Bytes(deploymentMap["project.zip"]) |
140 |
| - // deploymentID := k8s.RandomName() |
141 |
| - // api := spec.GetAPISpec(&apiConfigs[0], projectID, deploymentID) |
142 |
| - |
143 |
| - hostConfig := &container.HostConfig{ |
144 |
| - PortBindings: nat.PortMap{ |
145 |
| - "8888/tcp": []nat.PortBinding{ |
146 |
| - { |
147 |
| - HostPort: "8888", |
148 |
| - }, |
149 |
| - }, |
150 |
| - }, |
151 |
| - Mounts: []mount.Mount{ |
152 |
| - { |
153 |
| - Type: mount.TypeBind, |
154 |
| - Source: "/home/ubuntu/src/github.com/cortexlabs/cortex/examples/pytorch/iris-classifier", |
155 |
| - Target: "/mnt/project", |
156 |
| - }, |
157 |
| - }, |
158 |
| - } |
159 |
| - |
160 |
| - containerConfig := &container.Config{ |
161 |
| - Image: "cortexlabs/python-serve:latest", |
162 |
| - Tty: true, |
163 |
| - AttachStdout: true, |
164 |
| - AttachStderr: true, |
165 |
| - Env: []string{ |
166 |
| - "CORTEX_VERSION=master", |
167 |
| - "CORTEX_SERVING_PORT=8888", |
168 |
| - "CORTEX_CACHE_DIR=" + "/mnt/cache", |
169 |
| - "CORTEX_API_SPEC=" + "app.yaml", |
170 |
| - "CORTEX_PROJECT_DIR=" + "/mnt/project", |
171 |
| - "CORTEX_WORKERS_PER_REPLICA=1", |
172 |
| - "CORTEX_MAX_WORKER_CONCURRENCY=10", |
173 |
| - "CORTEX_SO_MAX_CONN=10", |
174 |
| - "CORTEX_THREADS_PER_WORKER=1", |
175 |
| - "AWS_ACCESS_KEY_ID=" + os.Getenv("AWS_ACCESS_KEY_ID"), |
176 |
| - "AWS_SECRET_ACCESS_KEY=" + os.Getenv("AWS_SECRET_ACCESS_KEY"), |
177 |
| - }, |
178 |
| - ExposedPorts: nat.PortSet{ |
179 |
| - "8888/tcp": struct{}{}, |
180 |
| - }, |
| 114 | + exit.Error(err) |
181 | 115 | }
|
182 | 116 |
|
183 |
| - containerInfo, err := docker.ContainerCreate(context.Background(), containerConfig, hostConfig, nil, "") |
| 117 | + apiConfigs, err := spec.ExtractAPIConfigs(deploymentMap["config"], projectFileMap, configPath) |
184 | 118 | if err != nil {
|
185 |
| - panic(err) |
| 119 | + exit.Error(err) |
186 | 120 | }
|
187 | 121 |
|
188 |
| - err = docker.ContainerStart(context.Background(), containerInfo.ID, dockertypes.ContainerStartOptions{}) |
| 122 | + err = local.ValidateLocalAPIs(apiConfigs, projectFileMap) |
189 | 123 | if err != nil {
|
190 |
| - panic("ContainerStart") |
| 124 | + exit.Error(err) |
191 | 125 | }
|
192 | 126 |
|
193 |
| - removeContainer := func() { |
194 |
| - docker.ContainerRemove(context.Background(), containerInfo.ID, dockertypes.ContainerRemoveOptions{ |
195 |
| - RemoveVolumes: true, |
196 |
| - Force: true, |
197 |
| - }) |
| 127 | + projectID := hash.Bytes(deploymentMap["project.zip"]) |
| 128 | + |
| 129 | + results := make([]schema.DeployResult, len(apiConfigs)) |
| 130 | + for i, apiConfig := range apiConfigs { |
| 131 | + api, msg, err := local.UpdateAPI(&apiConfig, projectID) |
| 132 | + results[i].Message = msg |
| 133 | + if err != nil { |
| 134 | + results[i].Error = errors.Message(err) |
| 135 | + } else { |
| 136 | + results[i].API = *api |
| 137 | + } |
198 | 138 | }
|
| 139 | + debug.Pp(results) |
| 140 | + }, |
| 141 | +} |
199 | 142 |
|
200 |
| - defer removeContainer() |
201 |
| - |
202 |
| - // Make sure to remove container immediately on ctrl+c |
203 |
| - c := make(chan os.Signal, 1) |
204 |
| - signal.Notify(c, os.Interrupt, syscall.SIGTERM) |
205 |
| - caughtCtrlC := false |
206 |
| - go func() { |
207 |
| - <-c |
208 |
| - caughtCtrlC = true |
209 |
| - removeContainer() |
210 |
| - exit.Error(ErrorDockerCtrlC()) |
211 |
| - }() |
| 143 | +var localGet = &cobra.Command{ |
| 144 | + Use: "local-get", |
| 145 | + Short: "local an application", |
| 146 | + Long: "local an application.", |
| 147 | + Args: cobra.ExactArgs(1), |
| 148 | + Run: func(cmd *cobra.Command, args []string) { |
| 149 | + containers := GetContainerByAPI(args[0]) |
| 150 | + debug.Pp(containers) |
| 151 | + rows := [][]interface{}{} |
212 | 152 |
|
213 |
| - err = docker.ContainerStart(context.Background(), containerInfo.ID, dockertypes.ContainerStartOptions{}) |
214 |
| - if err != nil { |
215 |
| - panic("ContainerInspect") |
| 153 | + for _, container := range containers { |
| 154 | + rows = append(rows, []interface{}{ |
| 155 | + container.Labels["apiName"], container.State, |
| 156 | + }) |
216 | 157 | }
|
217 | 158 |
|
218 |
| - logsOutput, err := docker.ContainerAttach(context.Background(), containerInfo.ID, dockertypes.ContainerAttachOptions{ |
219 |
| - Stream: true, |
220 |
| - Stdout: true, |
221 |
| - Stderr: true, |
222 |
| - }) |
223 |
| - if err != nil { |
224 |
| - panic("ContainerAttach") |
| 159 | + t := table.Table{ |
| 160 | + Headers: []table.Header{ |
| 161 | + { |
| 162 | + Title: "api name", |
| 163 | + }, { |
| 164 | + Title: "status", |
| 165 | + }, |
| 166 | + }, |
| 167 | + Rows: rows, |
225 | 168 | }
|
226 |
| - defer logsOutput.Close() |
| 169 | + fmt.Println(t.MustFormat()) |
| 170 | + }, |
| 171 | +} |
227 | 172 |
|
228 |
| - var outputBuffer bytes.Buffer |
229 |
| - tee := io.TeeReader(logsOutput.Reader, &outputBuffer) |
| 173 | +func GetContainerByAPI(apiName string) []dockertypes.Container { |
| 174 | + docker, err := getDockerClient() |
| 175 | + if err != nil { |
| 176 | + panic(err) |
| 177 | + } |
230 | 178 |
|
231 |
| - _, err = io.Copy(os.Stdout, tee) |
232 |
| - if err != nil { |
233 |
| - panic("Copy") |
234 |
| - } |
| 179 | + dargs := filters.NewArgs() |
| 180 | + dargs.Add("label", "cortex=true") |
| 181 | + dargs.Add("label", "apiName="+apiName) |
235 | 182 |
|
236 |
| - // Let the ctrl+c handler run its course |
237 |
| - if caughtCtrlC { |
238 |
| - time.Sleep(5 * time.Second) |
239 |
| - } |
| 183 | + containers, err := docker.ContainerList(context.Background(), types.ContainerListOptions{ |
| 184 | + All: true, |
| 185 | + Filters: dargs, |
| 186 | + }) |
| 187 | + if err != nil { |
| 188 | + exit.Error(err) |
| 189 | + } |
| 190 | + |
| 191 | + return containers |
| 192 | +} |
240 | 193 |
|
241 |
| - info, err := docker.ContainerInspect(context.Background(), containerInfo.ID) |
| 194 | +var localDelete = &cobra.Command{ |
| 195 | + Use: "local-delete", |
| 196 | + Short: "local an application", |
| 197 | + Long: "local an application.", |
| 198 | + Args: cobra.ExactArgs(1), |
| 199 | + Run: func(cmd *cobra.Command, args []string) { |
| 200 | + apiName := args[0] |
| 201 | + err := local.DeleteContainers(apiName) |
242 | 202 | if err != nil {
|
243 |
| - panic("ContainerInspect") |
| 203 | + exit.Error(err) |
244 | 204 | }
|
| 205 | + }, |
| 206 | +} |
245 | 207 |
|
246 |
| - if info.State.Running { |
247 |
| - panic("info.State.Running") |
| 208 | +var localLogs = &cobra.Command{ |
| 209 | + Use: "local-logs", |
| 210 | + Short: "local an application", |
| 211 | + Long: "local an application.", |
| 212 | + Args: cobra.ExactArgs(1), |
| 213 | + Run: func(cmd *cobra.Command, args []string) { |
| 214 | + path, err := files.GetAbsPath(args[0]) |
| 215 | + if err != nil { |
| 216 | + panic(err) |
248 | 217 | }
|
| 218 | + fmt.Println(path) |
| 219 | + // containers := GetContainerByAPI(args[0]) |
| 220 | + // containerIDs := []string{} |
| 221 | + // for _, container := range containers { |
| 222 | + // containerIDs = append(containerIDs, container.ID) |
| 223 | + // } |
249 | 224 |
|
| 225 | + // streamDockerLogs(containerIDs[0], containerIDs[1:]...) |
250 | 226 | },
|
251 | 227 | }
|
0 commit comments