Skip to content

Commit ff1a8b4

Browse files
committed
refactor(admin): 重构挂载和端口映射输入交互
- 挂载/端口映射改为行内输入模式,虚线框包裹所有输入行 - 用户填写后可直接提交/保存,无需点击"增加"按钮确认 - "增加映射"按钮改为 w-full block 样式,点击新增一行空输入 - 路径自动完成支持 Tab 补全唯一项 - 端口映射默认 TCP,移除协议选择器 - 必填字段标记改为红色 - 禁用 ~/ 前缀(宿主机和容器的 ~ 语义不同)
1 parent e3ff822 commit ff1a8b4

7 files changed

Lines changed: 423 additions & 414 deletions

File tree

internal/controlplane/http/admin_host_files_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func TestAdminHostFiles_EmptyPath(t *testing.T) {
122122

123123
func TestAdminHostFiles_RelativePath(t *testing.T) {
124124
h := NewAdminHostFilesHandler(slog.Default())
125-
for _, path := range []string{"foo/bar", "tmp", "./etc"} {
125+
for _, path := range []string{"foo/bar", "tmp", "./etc", "~", "~/foo"} {
126126
req := httptest.NewRequest(http.MethodGet, "/v1/admin/host-files?path="+path, nil)
127127
rr := httptest.NewRecorder()
128128
h.List().ServeHTTP(rr, req)

internal/controlplane/http/admin_hosts.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import (
2323
"github.com/zanel1u/cloud-cli-proxy/internal/store/repository"
2424
)
2525

26+
func expandHostMountSources(mounts repository.HostMounts) repository.HostMounts {
27+
return mounts
28+
}
29+
2630
type AdminHostStore interface {
2731
ListHostsWithUsername(context.Context) ([]repository.HostWithUsername, error)
2832
GetHostDetail(context.Context, string) (repository.HostDetail, error)
@@ -234,7 +238,7 @@ func (h *AdminHostsHandler) Create() nethttp.Handler {
234238
MemoryLimitMB: body.MemoryLimitMB,
235239
CPULimit: body.CPULimit,
236240
DiskLimitGB: body.DiskLimitGB,
237-
HostMounts: body.HostMounts,
241+
HostMounts: expandHostMountSources(body.HostMounts),
238242
HostPorts: body.HostPorts,
239243
})
240244
if err == nil {
@@ -1048,11 +1052,12 @@ func (h *AdminHostsHandler) UpdateMounts() nethttp.Handler {
10481052
return
10491053
}
10501054
if !strings.HasPrefix(m.Source, "/") || !strings.HasPrefix(m.Target, "/") {
1051-
writeJSON(w, nethttp.StatusBadRequest, map[string]string{"error": "paths must be absolute (start with /)"})
1055+
writeJSON(w, nethttp.StatusBadRequest, map[string]string{"error": "paths must be absolute"})
10521056
return
10531057
}
10541058
}
1055-
if err := h.store.UpdateHostMounts(r.Context(), hostID, body.Mounts); err != nil {
1059+
expandedMounts := expandHostMountSources(body.Mounts)
1060+
if err := h.store.UpdateHostMounts(r.Context(), hostID, expandedMounts); err != nil {
10561061
h.logger.Error("update host mounts failed", "host_id", hostID, "error", err)
10571062
writeJSON(w, nethttp.StatusInternalServerError, map[string]string{"error": "update mounts failed"})
10581063
return

internal/runtime/runtime_service.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"log/slog"
99
"os"
10+
"path/filepath"
1011
"strings"
1112

1213
"github.com/jackc/pgx/v5"
@@ -15,6 +16,20 @@ import (
1516
"github.com/zanel1u/cloud-cli-proxy/internal/store/repository"
1617
)
1718

19+
func expandBindMountSource(src string) string {
20+
if !strings.HasPrefix(src, "~/") && src != "~" {
21+
return src
22+
}
23+
home, err := os.UserHomeDir()
24+
if err != nil {
25+
return src
26+
}
27+
if src == "~" {
28+
return home
29+
}
30+
return filepath.Join(home, src[2:])
31+
}
32+
1833
const (
1934
DefaultImageLockPath = "deploy/docker/managed-user/image.lock"
2035
defaultRebuildMode = "preserve-home"
@@ -168,7 +183,7 @@ func (s *Service) QueueHostAction(ctx context.Context, hostID string, action age
168183
request.BindMounts = make([]agentapi.BindMount, 0, len(host.HostMounts))
169184
for _, hm := range host.HostMounts {
170185
request.BindMounts = append(request.BindMounts, agentapi.BindMount{
171-
Source: hm.Source,
186+
Source: expandBindMountSource(hm.Source),
172187
Target: hm.Target,
173188
ReadOnly: hm.ReadOnly,
174189
})

0 commit comments

Comments
 (0)