Skip to content

Commit 21f589c

Browse files
authored
Migrate legacy setup to default profile (#259)
* Migrate legacy setup to default profile. * Add migration tests. * Move files to `.backup` instead of deleting them. * Typo fix.
1 parent 0185d0a commit 21f589c

File tree

10 files changed

+1029
-11
lines changed

10 files changed

+1029
-11
lines changed

cmd/docker-mcp/commands/catalog_next.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,25 @@ import (
99

1010
catalognext "github.com/docker/mcp-gateway/pkg/catalog_next"
1111
"github.com/docker/mcp-gateway/pkg/db"
12+
"github.com/docker/mcp-gateway/pkg/docker"
13+
"github.com/docker/mcp-gateway/pkg/migrate"
1214
"github.com/docker/mcp-gateway/pkg/oci"
1315
"github.com/docker/mcp-gateway/pkg/workingset"
1416
)
1517

16-
func catalogNextCommand() *cobra.Command {
18+
func catalogNextCommand(docker docker.Client) *cobra.Command {
1719
cmd := &cobra.Command{
1820
Use: "catalog-next",
1921
Short: "Manage catalogs (next generation)",
22+
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
23+
dao, err := db.New()
24+
if err != nil {
25+
return err
26+
}
27+
defer dao.Close()
28+
migrate.MigrateConfig(cmd.Context(), docker, dao)
29+
return nil
30+
},
2031
}
2132

2233
cmd.AddCommand(createCatalogNextCommand())

cmd/docker-mcp/commands/gateway.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ func gatewayCommand(docker docker.Client, dockerCli command.Cli) *cobra.Command
123123
options.MCPRegistryServers = mcpServers
124124
}
125125

126+
// TODO(cody): When all commands are migrated, we should default this parameter to "default"
127+
// Also need to consider the case when there is no default profile
126128
if options.WorkingSet != "" {
127129
if len(options.ServerNames) > 0 {
128130
return fmt.Errorf("cannot use --profile with --servers flag")

cmd/docker-mcp/commands/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ func Root(ctx context.Context, cwd string, dockerCli command.Cli) *cobra.Command
7171
dockerClient := docker.NewClient(dockerCli)
7272

7373
if isWorkingSetsFeatureEnabled(dockerCli) {
74-
cmd.AddCommand(workingSetCommand())
75-
cmd.AddCommand(catalogNextCommand())
74+
cmd.AddCommand(workingSetCommand(dockerClient))
75+
cmd.AddCommand(catalogNextCommand(dockerClient))
7676
}
7777
cmd.AddCommand(catalogCommand(dockerCli))
7878
cmd.AddCommand(clientCommand(dockerCli, cwd))

cmd/docker-mcp/commands/workingset.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,29 @@ import (
99

1010
"github.com/docker/mcp-gateway/pkg/client"
1111
"github.com/docker/mcp-gateway/pkg/db"
12+
"github.com/docker/mcp-gateway/pkg/docker"
13+
"github.com/docker/mcp-gateway/pkg/migrate"
1214
"github.com/docker/mcp-gateway/pkg/oci"
1315
"github.com/docker/mcp-gateway/pkg/registryapi"
1416
"github.com/docker/mcp-gateway/pkg/sliceutil"
1517
"github.com/docker/mcp-gateway/pkg/workingset"
1618
)
1719

18-
func workingSetCommand() *cobra.Command {
20+
func workingSetCommand(docker docker.Client) *cobra.Command {
1921
cfg := client.ReadConfig()
2022

2123
cmd := &cobra.Command{
2224
Use: "profile",
2325
Short: "Manage profiles",
26+
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
27+
dao, err := db.New()
28+
if err != nil {
29+
return err
30+
}
31+
defer dao.Close()
32+
migrate.MigrateConfig(cmd.Context(), docker, dao)
33+
return nil
34+
},
2435
}
2536

2637
cmd.AddCommand(exportWorkingSetCommand())

pkg/db/db.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import (
2323
type DAO interface {
2424
WorkingSetDAO
2525
CatalogDAO
26+
MigrationStatusDAO
27+
28+
// Normally unnecessary to call this
29+
Close() error
2630
}
2731

2832
type dao struct {
@@ -97,6 +101,10 @@ func New(opts ...Option) (DAO, error) {
97101
return &dao{db: sqlxDb}, nil
98102
}
99103

104+
func (d *dao) Close() error {
105+
return d.db.Close()
106+
}
107+
100108
func DefaultDatabaseFilename() (string, error) {
101109
homeDir, err := user.HomeDir()
102110
if err != nil {

pkg/db/migration_status.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package db
2+
3+
import (
4+
"context"
5+
"time"
6+
)
7+
8+
type MigrationStatusDAO interface {
9+
GetMigrationStatus(ctx context.Context) (*MigrationStatus, error)
10+
UpdateMigrationStatus(ctx context.Context, status MigrationStatus) error
11+
}
12+
13+
type MigrationStatus struct {
14+
ID *int64 `db:"id"`
15+
Status string `db:"status"`
16+
Logs string `db:"logs"`
17+
LastUpdated *time.Time `db:"last_updated"`
18+
}
19+
20+
func (d *dao) GetMigrationStatus(ctx context.Context) (*MigrationStatus, error) {
21+
const query = `SELECT id, status, logs, last_updated FROM migration_status LIMIT 1`
22+
23+
var migrationStatus MigrationStatus
24+
err := d.db.GetContext(ctx, &migrationStatus, query)
25+
if err != nil {
26+
return nil, err
27+
}
28+
return &migrationStatus, nil
29+
}
30+
31+
func (d *dao) UpdateMigrationStatus(ctx context.Context, status MigrationStatus) error {
32+
tx, err := d.db.BeginTxx(ctx, nil)
33+
if err != nil {
34+
return err
35+
}
36+
defer txClose(tx, &err)
37+
38+
const deleteQuery = `DELETE FROM migration_status`
39+
_, err = tx.ExecContext(ctx, deleteQuery)
40+
if err != nil {
41+
return err
42+
}
43+
44+
const query = `INSERT INTO migration_status (status, logs) VALUES ($1, $2)`
45+
46+
_, err = tx.ExecContext(ctx, query, status.Status, status.Logs)
47+
if err != nil {
48+
return err
49+
}
50+
51+
if err = tx.Commit(); err != nil {
52+
return err
53+
}
54+
55+
return nil
56+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
create table migration_status (
2+
id integer primary key,
3+
status text not null,
4+
logs text,
5+
last_updated DATETIME DEFAULT CURRENT_TIMESTAMP
6+
);

pkg/gateway/configuration_workingset.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/docker/mcp-gateway/pkg/db"
1313
"github.com/docker/mcp-gateway/pkg/docker"
1414
"github.com/docker/mcp-gateway/pkg/log"
15+
"github.com/docker/mcp-gateway/pkg/migrate"
1516
"github.com/docker/mcp-gateway/pkg/oci"
1617
"github.com/docker/mcp-gateway/pkg/workingset"
1718
)
@@ -31,7 +32,15 @@ func NewWorkingSetConfiguration(workingSet string, ociService oci.Service, docke
3132
}
3233

3334
func (c *WorkingSetConfiguration) Read(ctx context.Context) (Configuration, chan Configuration, func() error, error) {
34-
configuration, err := c.readOnce(ctx)
35+
dao, err := db.New()
36+
if err != nil {
37+
return Configuration{}, nil, nil, fmt.Errorf("failed to create database client: %w", err)
38+
}
39+
40+
// Do migration from legacy files
41+
migrate.MigrateConfig(ctx, c.docker, dao)
42+
43+
configuration, err := c.readOnce(ctx, dao)
3544
if err != nil {
3645
return Configuration{}, nil, nil, err
3746
}
@@ -42,15 +51,10 @@ func (c *WorkingSetConfiguration) Read(ctx context.Context) (Configuration, chan
4251
return configuration, updates, func() error { return nil }, nil
4352
}
4453

45-
func (c *WorkingSetConfiguration) readOnce(ctx context.Context) (Configuration, error) {
54+
func (c *WorkingSetConfiguration) readOnce(ctx context.Context, dao db.DAO) (Configuration, error) {
4655
start := time.Now()
4756
log.Log("- Reading profile configuration...")
4857

49-
dao, err := db.New()
50-
if err != nil {
51-
return Configuration{}, fmt.Errorf("failed to create database client: %w", err)
52-
}
53-
5458
dbWorkingSet, err := dao.GetWorkingSet(ctx, c.WorkingSet)
5559
if err != nil {
5660
if errors.Is(err, sql.ErrNoRows) {

0 commit comments

Comments
 (0)