package db import ( "encoding/json" "fmt" "time" "github.com/opencontainers/go-digest" "github.com/pkg/errors" "github.com/rs/zerolog/log" ) // Migrate runs database migration func (c *Client) Migrate() error { if c.metadata.Version == dbVersion { return nil } migrations := map[int]func(*Client) error{ 2: (*Client).migration2, } for version := c.metadata.Version + 1; version <= dbVersion; version++ { migration, found := migrations[version] if !found { return fmt.Errorf("database migration v%d not found", version) } log.Info().Msgf("Database migration v%d...", version) if err := migration(c); err != nil { return errors.Wrapf(err, "Database migration v%d failed", version) } } return c.WriteMetadata(Metadata{ Version: dbVersion, }) } func (c *Client) migration2() error { type oldManifest struct { Name string Tag string MIMEType string Digest digest.Digest Created *time.Time DockerVersion string Labels map[string]string Architecture string `json:"-"` Os string `json:"-"` Layers []string } tx, err := c.Begin(true) if err != nil { return err } defer tx.Rollback() bucket := tx.Bucket([]byte(bucketManifest)) curs := bucket.Cursor() for k, v := curs.First(); k != nil; k, v = curs.Next() { var oldManifest oldManifest if err := json.Unmarshal(v, &oldManifest); err != nil { return err } entryBytes, _ := json.Marshal(oldManifest) if err := bucket.Put(k, entryBytes); err != nil { return err } } if err := tx.Commit(); err != nil { return err } return nil }