images: remove the docker field

The 'docker' bit on model.Image was unused at runtime — every code
path that branched on it had been removed earlier, leaving only the
field, the SQL column, the --docker flag, and the
#feature:docker sentinel that BuildMetadataPackages emitted into a
hash file. None of those have callers anymore.

Strip the field from the model, the API params, the SQLite column,
the CLI flag, and BuildMetadataPackages's signature. Add migration
2 (drop_images_docker) so existing installs lose the column on next
daemon start. ALTER TABLE ... DROP COLUMN is fine: SQLite has
supported it since 3.35 (2021).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Thales Maciel 2026-04-26 20:28:40 -03:00
parent 408ad6756c
commit 6c37fec17b
No known key found for this signature in database
GPG key ID: 33112E6833C34679
9 changed files with 23 additions and 28 deletions

View file

@ -158,7 +158,6 @@ type ImageRegisterParams struct {
InitrdPath string `json:"initrd_path,omitempty"` InitrdPath string `json:"initrd_path,omitempty"`
ModulesDir string `json:"modules_dir,omitempty"` ModulesDir string `json:"modules_dir,omitempty"`
KernelRef string `json:"kernel_ref,omitempty"` KernelRef string `json:"kernel_ref,omitempty"`
Docker bool `json:"docker,omitempty"`
} }
type ImagePullParams struct { type ImagePullParams struct {

View file

@ -309,7 +309,7 @@ func TestImageRegisterFlagsExist(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("find register: %v", err) t.Fatalf("find register: %v", err)
} }
for _, flagName := range []string{"name", "rootfs", "work-seed", "kernel", "initrd", "modules", "docker"} { for _, flagName := range []string{"name", "rootfs", "work-seed", "kernel", "initrd", "modules"} {
if register.Flags().Lookup(flagName) == nil { if register.Flags().Lookup(flagName) == nil {
t.Fatalf("missing flag %q", flagName) t.Fatalf("missing flag %q", flagName)
} }

View file

@ -80,7 +80,6 @@ func (d *deps) newImageRegisterCommand() *cobra.Command {
cmd.Flags().StringVar(&params.InitrdPath, "initrd", "", "initrd path") cmd.Flags().StringVar(&params.InitrdPath, "initrd", "", "initrd path")
cmd.Flags().StringVar(&params.ModulesDir, "modules", "", "modules dir") cmd.Flags().StringVar(&params.ModulesDir, "modules", "", "modules dir")
cmd.Flags().StringVar(&params.KernelRef, "kernel-ref", "", "name of a cataloged kernel (see 'banger kernel list')") cmd.Flags().StringVar(&params.KernelRef, "kernel-ref", "", "name of a cataloged kernel (see 'banger kernel list')")
cmd.Flags().BoolVar(&params.Docker, "docker", false, "mark image as docker-prepared")
_ = cmd.RegisterFlagCompletionFunc("kernel-ref", d.completeKernelNames) _ = cmd.RegisterFlagCompletionFunc("kernel-ref", d.completeKernelNames)
return cmd return cmd
} }

View file

@ -129,14 +129,9 @@ func StageOptionalArtifactPath(artifactDir, stagedPath, name string) string {
} }
// BuildMetadataPackages returns the canonical package set recorded for a // BuildMetadataPackages returns the canonical package set recorded for a
// managed image build. The #feature:docker sentinel is appended when // managed image build.
// docker is requested. func BuildMetadataPackages() []string {
func BuildMetadataPackages(docker bool) []string { return DebianBasePackages()
packages := DebianBasePackages()
if docker {
packages = append(packages, "#feature:docker")
}
return packages
} }
// WritePackagesMetadata writes the hash of packages next to rootfsPath so // WritePackagesMetadata writes the hash of packages next to rootfsPath so

View file

@ -64,7 +64,6 @@ func (s *ImageService) RegisterImage(ctx context.Context, params api.ImageRegist
image.KernelPath = kernelPath image.KernelPath = kernelPath
image.InitrdPath = initrdPath image.InitrdPath = initrdPath
image.ModulesDir = modulesDir image.ModulesDir = modulesDir
image.Docker = params.Docker
image.UpdatedAt = now image.UpdatedAt = now
case errors.Is(lookupErr, sql.ErrNoRows): case errors.Is(lookupErr, sql.ErrNoRows):
id, idErr := model.NewID() id, idErr := model.NewID()
@ -80,7 +79,6 @@ func (s *ImageService) RegisterImage(ctx context.Context, params api.ImageRegist
KernelPath: kernelPath, KernelPath: kernelPath,
InitrdPath: initrdPath, InitrdPath: initrdPath,
ModulesDir: modulesDir, ModulesDir: modulesDir,
Docker: params.Docker,
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
} }

View file

@ -76,7 +76,6 @@ type Image struct {
ModulesDir string `json:"modules_dir,omitempty"` ModulesDir string `json:"modules_dir,omitempty"`
BuildSize string `json:"build_size,omitempty"` BuildSize string `json:"build_size,omitempty"`
SeededSSHPublicKeyFingerprint string `json:"seeded_ssh_public_key_fingerprint,omitempty"` SeededSSHPublicKeyFingerprint string `json:"seeded_ssh_public_key_fingerprint,omitempty"`
Docker bool `json:"docker"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }

View file

@ -24,6 +24,7 @@ type migration struct {
// entries — installed DBs key off the id column. // entries — installed DBs key off the id column.
var migrations = []migration{ var migrations = []migration{
{id: 1, name: "baseline", up: migrateBaseline}, {id: 1, name: "baseline", up: migrateBaseline},
{id: 2, name: "drop_images_docker", up: migrateDropImagesDocker},
} }
// runMigrations ensures schema_migrations exists, then applies every // runMigrations ensures schema_migrations exists, then applies every
@ -141,3 +142,13 @@ func migrateBaseline(tx *sql.Tx) error {
} }
return nil return nil
} }
// migrateDropImagesDocker removes the legacy images.docker column.
// SQLite supports ALTER TABLE ... DROP COLUMN since 3.35 (2021), and
// banger ships against modern SQLite, so a single statement is enough.
// Existing values are simply discarded — the field never affected
// runtime behaviour.
func migrateDropImagesDocker(tx *sql.Tx) error {
_, err := tx.Exec(`ALTER TABLE images DROP COLUMN docker;`)
return err
}

View file

@ -123,8 +123,8 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
const query = ` const query = `
INSERT INTO images ( INSERT INTO images (
id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path,
modules_dir, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at modules_dir, build_size, seeded_ssh_public_key_fingerprint, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET ON CONFLICT(id) DO UPDATE SET
name=excluded.name, name=excluded.name,
managed=excluded.managed, managed=excluded.managed,
@ -136,7 +136,6 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
modules_dir=excluded.modules_dir, modules_dir=excluded.modules_dir,
build_size=excluded.build_size, build_size=excluded.build_size,
seeded_ssh_public_key_fingerprint=excluded.seeded_ssh_public_key_fingerprint, seeded_ssh_public_key_fingerprint=excluded.seeded_ssh_public_key_fingerprint,
docker=excluded.docker,
updated_at=excluded.updated_at` updated_at=excluded.updated_at`
_, err := s.db.ExecContext(ctx, query, _, err := s.db.ExecContext(ctx, query,
image.ID, image.ID,
@ -150,7 +149,6 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
image.ModulesDir, image.ModulesDir,
image.BuildSize, image.BuildSize,
image.SeededSSHPublicKeyFingerprint, image.SeededSSHPublicKeyFingerprint,
boolToInt(image.Docker),
image.CreatedAt.Format(time.RFC3339), image.CreatedAt.Format(time.RFC3339),
image.UpdatedAt.Format(time.RFC3339), image.UpdatedAt.Format(time.RFC3339),
) )
@ -158,15 +156,15 @@ func (s *Store) UpsertImage(ctx context.Context, image model.Image) error {
} }
func (s *Store) GetImageByName(ctx context.Context, name string) (model.Image, error) { func (s *Store) GetImageByName(ctx context.Context, name string) (model.Image, error) {
return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at FROM images WHERE name = ?", name) return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, build_size, seeded_ssh_public_key_fingerprint, created_at, updated_at FROM images WHERE name = ?", name)
} }
func (s *Store) GetImageByID(ctx context.Context, id string) (model.Image, error) { func (s *Store) GetImageByID(ctx context.Context, id string) (model.Image, error) {
return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at FROM images WHERE id = ?", id) return s.getImage(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, build_size, seeded_ssh_public_key_fingerprint, created_at, updated_at FROM images WHERE id = ?", id)
} }
func (s *Store) ListImages(ctx context.Context) ([]model.Image, error) { func (s *Store) ListImages(ctx context.Context) ([]model.Image, error) {
rows, err := s.db.QueryContext(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, build_size, seeded_ssh_public_key_fingerprint, docker, created_at, updated_at FROM images ORDER BY created_at ASC") rows, err := s.db.QueryContext(ctx, "SELECT id, name, managed, artifact_dir, rootfs_path, work_seed_path, kernel_path, initrd_path, modules_dir, build_size, seeded_ssh_public_key_fingerprint, created_at, updated_at FROM images ORDER BY created_at ASC")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -356,7 +354,7 @@ type scanner interface {
func scanImageRow(row scanner) (model.Image, error) { func scanImageRow(row scanner) (model.Image, error) {
var image model.Image var image model.Image
var managed, docker int var managed int
var workSeedPath sql.NullString var workSeedPath sql.NullString
var seededSSHPublicKeyFingerprint sql.NullString var seededSSHPublicKeyFingerprint sql.NullString
var createdAt, updatedAt string var createdAt, updatedAt string
@ -372,7 +370,6 @@ func scanImageRow(row scanner) (model.Image, error) {
&image.ModulesDir, &image.ModulesDir,
&image.BuildSize, &image.BuildSize,
&seededSSHPublicKeyFingerprint, &seededSSHPublicKeyFingerprint,
&docker,
&createdAt, &createdAt,
&updatedAt, &updatedAt,
) )
@ -380,7 +377,6 @@ func scanImageRow(row scanner) (model.Image, error) {
return image, err return image, err
} }
image.Managed = managed == 1 image.Managed = managed == 1
image.Docker = docker == 1
image.WorkSeedPath = workSeedPath.String image.WorkSeedPath = workSeedPath.String
image.SeededSSHPublicKeyFingerprint = seededSSHPublicKeyFingerprint.String image.SeededSSHPublicKeyFingerprint = seededSSHPublicKeyFingerprint.String
image.CreatedAt, err = time.Parse(time.RFC3339, createdAt) image.CreatedAt, err = time.Parse(time.RFC3339, createdAt)

View file

@ -179,8 +179,8 @@ func TestGetImageRejectsMalformedTimestamp(t *testing.T) {
_, err := store.db.ExecContext(ctx, ` _, err := store.db.ExecContext(ctx, `
INSERT INTO images ( INSERT INTO images (
id, name, managed, artifact_dir, rootfs_path, kernel_path, initrd_path, id, name, managed, artifact_dir, rootfs_path, kernel_path, initrd_path,
modules_dir, build_size, docker, created_at, updated_at modules_dir, build_size, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
"image-bad-time", "image-bad-time",
"image-bad-time", "image-bad-time",
0, 0,
@ -190,7 +190,6 @@ func TestGetImageRejectsMalformedTimestamp(t *testing.T) {
"", "",
"", "",
"", "",
0,
"not-a-time", "not-a-time",
"not-a-time", "not-a-time",
) )
@ -398,7 +397,6 @@ func sampleImage(name string) model.Image {
ModulesDir: "/modules/" + name, ModulesDir: "/modules/" + name,
BuildSize: "8G", BuildSize: "8G",
SeededSSHPublicKeyFingerprint: "seeded-fingerprint", SeededSSHPublicKeyFingerprint: "seeded-fingerprint",
Docker: true,
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
} }