|
8 | 8 | "strings" |
9 | 9 | "time" |
10 | 10 |
|
| 11 | + nodev1 "buf.build/gen/go/brevdev/devplane/protocolbuffers/go/devplaneapi/v1" |
| 12 | + |
11 | 13 | "github.com/brevdev/brev-cli/pkg/cmd/cmderrors" |
12 | 14 | "github.com/brevdev/brev-cli/pkg/cmd/completions" |
13 | 15 | "github.com/brevdev/brev-cli/pkg/cmd/refresh" |
@@ -75,7 +77,15 @@ func runCopyCommand(t *terminal.Terminal, cstore CopyStore, source, dest string, |
75 | 77 | } |
76 | 78 | } |
77 | 79 |
|
78 | | - workspace, err := prepareWorkspace(t, cstore, workspaceNameOrID) |
| 80 | + target, err := util.ResolveWorkspaceOrNode(cstore, workspaceNameOrID) |
| 81 | + if err != nil { |
| 82 | + return breverrors.WrapAndTrace(err) |
| 83 | + } |
| 84 | + if target.Node != nil { |
| 85 | + return copyExternalNode(t, cstore, target.Node, localPath, remotePath, isUpload) |
| 86 | + } |
| 87 | + |
| 88 | + workspace, err := prepareWorkspace(t, cstore, target.Workspace) |
79 | 89 | if err != nil { |
80 | 90 | return breverrors.WrapAndTrace(err) |
81 | 91 | } |
@@ -116,26 +126,22 @@ func parseCopyArguments(source, dest string) (workspaceNameOrID, remotePath, loc |
116 | 126 | return destWorkspace, destPath, source, true, nil |
117 | 127 | } |
118 | 128 |
|
119 | | -func prepareWorkspace(t *terminal.Terminal, cstore CopyStore, workspaceNameOrID string) (*entity.Workspace, error) { |
| 129 | +func prepareWorkspace(t *terminal.Terminal, cstore CopyStore, workspace *entity.Workspace) (*entity.Workspace, error) { |
120 | 130 | s := t.NewSpinner() |
121 | | - workspace, err := util.GetUserWorkspaceByNameOrIDErr(cstore, workspaceNameOrID) |
122 | | - if err != nil { |
123 | | - return nil, breverrors.WrapAndTrace(err) |
124 | | - } |
125 | 131 |
|
126 | 132 | if workspace.Status == "STOPPED" { |
127 | | - err = startWorkspaceIfStopped(t, s, cstore, workspaceNameOrID, workspace) |
| 133 | + err := startWorkspaceIfStopped(t, s, cstore, workspace.Name, workspace) |
128 | 134 | if err != nil { |
129 | 135 | return nil, breverrors.WrapAndTrace(err) |
130 | 136 | } |
131 | 137 | } |
132 | 138 |
|
133 | | - err = pollUntil(s, workspace.ID, "RUNNING", cstore, " waiting for instance to be ready...") |
| 139 | + err := pollUntil(s, workspace.ID, "RUNNING", cstore, " waiting for instance to be ready...") |
134 | 140 | if err != nil { |
135 | 141 | return nil, breverrors.WrapAndTrace(err) |
136 | 142 | } |
137 | 143 |
|
138 | | - workspace, err = util.GetUserWorkspaceByNameOrIDErr(cstore, workspaceNameOrID) |
| 144 | + workspace, err = util.GetUserWorkspaceByNameOrIDErr(cstore, workspace.Name) |
139 | 145 | if err != nil { |
140 | 146 | return nil, breverrors.WrapAndTrace(err) |
141 | 147 | } |
@@ -287,6 +293,28 @@ func startWorkspaceIfStopped(t *terminal.Terminal, s *spinner.Spinner, tstore Co |
287 | 293 | return nil |
288 | 294 | } |
289 | 295 |
|
| 296 | +func copyExternalNode(t *terminal.Terminal, cstore CopyStore, node *nodev1.ExternalNode, localPath, remotePath string, isUpload bool) error { |
| 297 | + info, err := util.ResolveExternalNodeSSH(cstore, node) |
| 298 | + if err != nil { |
| 299 | + return breverrors.WrapAndTrace(err) |
| 300 | + } |
| 301 | + alias := info.SSHAlias() |
| 302 | + |
| 303 | + // Ensure SSH config is up to date so the alias resolves. |
| 304 | + refreshRes := refresh.RunRefreshAsync(cstore) |
| 305 | + if err := refreshRes.Await(); err != nil { |
| 306 | + return breverrors.WrapAndTrace(err) |
| 307 | + } |
| 308 | + |
| 309 | + s := t.NewSpinner() |
| 310 | + err = waitForSSHToBeAvailable(alias, s) |
| 311 | + if err != nil { |
| 312 | + return breverrors.WrapAndTrace(err) |
| 313 | + } |
| 314 | + |
| 315 | + return runSCP(t, alias, localPath, remotePath, isUpload) |
| 316 | +} |
| 317 | + |
290 | 318 | func pollUntil(s *spinner.Spinner, wsid string, state string, copyStore CopyStore, waitMsg string) error { |
291 | 319 | isReady := false |
292 | 320 | s.Suffix = waitMsg |
|
0 commit comments