github.com/containerd/Containerd@v1.4.13/metadata/migrations.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package metadata 18 19 import bolt "go.etcd.io/bbolt" 20 21 type migration struct { 22 schema string 23 version int 24 migrate func(*bolt.Tx) error 25 } 26 27 // migrations stores the list of database migrations 28 // for each update to the database schema. The migrations 29 // array MUST be ordered by version from least to greatest. 30 // The last entry in the array should correspond to the 31 // schemaVersion and dbVersion constants. 32 // A migration test MUST be added for each migration in 33 // the array. 34 // The migrate function can safely assume the version 35 // of the data it is migrating from is the previous version 36 // of the database. 37 var migrations = []migration{ 38 { 39 schema: "v1", 40 version: 1, 41 migrate: addChildLinks, 42 }, 43 { 44 schema: "v1", 45 version: 2, 46 migrate: migrateIngests, 47 }, 48 { 49 schema: "v1", 50 version: 3, 51 migrate: noOpMigration, 52 }, 53 } 54 55 // addChildLinks Adds children key to the snapshotters to enforce snapshot 56 // entries cannot be removed which have children 57 func addChildLinks(tx *bolt.Tx) error { 58 v1bkt := tx.Bucket(bucketKeyVersion) 59 if v1bkt == nil { 60 return nil 61 } 62 63 // iterate through each namespace 64 v1c := v1bkt.Cursor() 65 66 for k, v := v1c.First(); k != nil; k, v = v1c.Next() { 67 if v != nil { 68 continue 69 } 70 nbkt := v1bkt.Bucket(k) 71 72 sbkt := nbkt.Bucket(bucketKeyObjectSnapshots) 73 if sbkt != nil { 74 // Iterate through each snapshotter 75 if err := sbkt.ForEach(func(sk, sv []byte) error { 76 if sv != nil { 77 return nil 78 } 79 snbkt := sbkt.Bucket(sk) 80 81 // Iterate through each snapshot 82 return snbkt.ForEach(func(k, v []byte) error { 83 if v != nil { 84 return nil 85 } 86 parent := snbkt.Bucket(k).Get(bucketKeyParent) 87 if len(parent) > 0 { 88 pbkt := snbkt.Bucket(parent) 89 if pbkt == nil { 90 // Not enforcing consistency during migration, skip 91 return nil 92 } 93 cbkt, err := pbkt.CreateBucketIfNotExists(bucketKeyChildren) 94 if err != nil { 95 return err 96 } 97 if err := cbkt.Put(k, nil); err != nil { 98 return err 99 } 100 } 101 102 return nil 103 }) 104 }); err != nil { 105 return err 106 } 107 } 108 } 109 110 return nil 111 } 112 113 // migrateIngests moves ingests from the key/value ingest bucket 114 // to a structured ingest bucket for storing additional state about 115 // an ingest. 116 func migrateIngests(tx *bolt.Tx) error { 117 v1bkt := tx.Bucket(bucketKeyVersion) 118 if v1bkt == nil { 119 return nil 120 } 121 122 // iterate through each namespace 123 v1c := v1bkt.Cursor() 124 125 for k, v := v1c.First(); k != nil; k, v = v1c.Next() { 126 if v != nil { 127 continue 128 } 129 bkt := v1bkt.Bucket(k).Bucket(bucketKeyObjectContent) 130 if bkt == nil { 131 continue 132 } 133 134 dbkt := bkt.Bucket(deprecatedBucketKeyObjectIngest) 135 if dbkt == nil { 136 continue 137 } 138 139 // Create new ingests bucket 140 nbkt, err := bkt.CreateBucketIfNotExists(bucketKeyObjectIngests) 141 if err != nil { 142 return err 143 } 144 145 if err := dbkt.ForEach(func(ref, bref []byte) error { 146 ibkt, err := nbkt.CreateBucketIfNotExists(ref) 147 if err != nil { 148 return err 149 } 150 return ibkt.Put(bucketKeyRef, bref) 151 }); err != nil { 152 return err 153 } 154 155 if err := bkt.DeleteBucket(deprecatedBucketKeyObjectIngest); err != nil { 156 return err 157 } 158 } 159 160 return nil 161 } 162 163 // noOpMigration was for a database change from boltdb/bolt which is no 164 // longer being supported, to go.etcd.io/bbolt which is the currently 165 // maintained repo for boltdb. 166 func noOpMigration(tx *bolt.Tx) error { 167 return nil 168 }