github.com/wozhu6104/docker@v20.10.10+incompatible/layer/migration_test.go (about) 1 package layer // import "github.com/docker/docker/layer" 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "io" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "runtime" 11 "testing" 12 13 "github.com/docker/docker/daemon/graphdriver" 14 "github.com/docker/docker/pkg/stringid" 15 "github.com/vbatts/tar-split/tar/asm" 16 "github.com/vbatts/tar-split/tar/storage" 17 ) 18 19 func writeTarSplitFile(name string, tarContent []byte) error { 20 f, err := os.OpenFile(name, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644) 21 if err != nil { 22 return err 23 } 24 defer f.Close() 25 26 fz := gzip.NewWriter(f) 27 28 metaPacker := storage.NewJSONPacker(fz) 29 defer fz.Close() 30 31 rdr, err := asm.NewInputTarStream(bytes.NewReader(tarContent), metaPacker, nil) 32 if err != nil { 33 return err 34 } 35 36 if _, err := io.Copy(ioutil.Discard, rdr); err != nil { 37 return err 38 } 39 40 return nil 41 } 42 43 func TestLayerMigration(t *testing.T) { 44 // TODO Windows: Figure out why this is failing 45 if runtime.GOOS == "windows" { 46 t.Skip("Failing on Windows") 47 } 48 td, err := ioutil.TempDir("", "migration-test-") 49 if err != nil { 50 t.Fatal(err) 51 } 52 defer os.RemoveAll(td) 53 54 layer1Files := []FileApplier{ 55 newTestFile("/root/.bashrc", []byte("# Boring configuration"), 0644), 56 newTestFile("/etc/profile", []byte("# Base configuration"), 0644), 57 } 58 59 layer2Files := []FileApplier{ 60 newTestFile("/root/.bashrc", []byte("# Updated configuration"), 0644), 61 } 62 63 tar1, err := tarFromFiles(layer1Files...) 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 tar2, err := tarFromFiles(layer2Files...) 69 if err != nil { 70 t.Fatal(err) 71 } 72 73 graph, err := newVFSGraphDriver(filepath.Join(td, "graphdriver-")) 74 if err != nil { 75 t.Fatal(err) 76 } 77 78 graphID1 := stringid.GenerateRandomID() 79 if err := graph.Create(graphID1, "", nil); err != nil { 80 t.Fatal(err) 81 } 82 if _, err := graph.ApplyDiff(graphID1, "", bytes.NewReader(tar1)); err != nil { 83 t.Fatal(err) 84 } 85 86 tf1 := filepath.Join(td, "tar1.json.gz") 87 if err := writeTarSplitFile(tf1, tar1); err != nil { 88 t.Fatal(err) 89 } 90 91 root := filepath.Join(td, "layers") 92 ls, err := newStoreFromGraphDriver(root, graph, runtime.GOOS) 93 if err != nil { 94 t.Fatal(err) 95 } 96 97 newTarDataPath := filepath.Join(td, ".migration-tardata") 98 diffID, size, err := ls.(*layerStore).ChecksumForGraphID(graphID1, "", tf1, newTarDataPath) 99 if err != nil { 100 t.Fatal(err) 101 } 102 103 layer1a, err := ls.(*layerStore).RegisterByGraphID(graphID1, "", diffID, newTarDataPath, size) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 layer1b, err := ls.Register(bytes.NewReader(tar1), "") 109 if err != nil { 110 t.Fatal(err) 111 } 112 113 assertReferences(t, layer1a, layer1b) 114 // Attempt register, should be same 115 layer2a, err := ls.Register(bytes.NewReader(tar2), layer1a.ChainID()) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 graphID2 := stringid.GenerateRandomID() 121 if err := graph.Create(graphID2, graphID1, nil); err != nil { 122 t.Fatal(err) 123 } 124 if _, err := graph.ApplyDiff(graphID2, graphID1, bytes.NewReader(tar2)); err != nil { 125 t.Fatal(err) 126 } 127 128 tf2 := filepath.Join(td, "tar2.json.gz") 129 if err := writeTarSplitFile(tf2, tar2); err != nil { 130 t.Fatal(err) 131 } 132 diffID, size, err = ls.(*layerStore).ChecksumForGraphID(graphID2, graphID1, tf2, newTarDataPath) 133 if err != nil { 134 t.Fatal(err) 135 } 136 137 layer2b, err := ls.(*layerStore).RegisterByGraphID(graphID2, layer1a.ChainID(), diffID, tf2, size) 138 if err != nil { 139 t.Fatal(err) 140 } 141 assertReferences(t, layer2a, layer2b) 142 143 if metadata, err := ls.Release(layer2a); err != nil { 144 t.Fatal(err) 145 } else if len(metadata) > 0 { 146 t.Fatalf("Unexpected layer removal after first release: %#v", metadata) 147 } 148 149 metadata, err := ls.Release(layer2b) 150 if err != nil { 151 t.Fatal(err) 152 } 153 154 assertMetadata(t, metadata, createMetadata(layer2a)) 155 } 156 157 func tarFromFilesInGraph(graph graphdriver.Driver, graphID, parentID string, files ...FileApplier) ([]byte, error) { 158 t, err := tarFromFiles(files...) 159 if err != nil { 160 return nil, err 161 } 162 163 if err := graph.Create(graphID, parentID, nil); err != nil { 164 return nil, err 165 } 166 if _, err := graph.ApplyDiff(graphID, parentID, bytes.NewReader(t)); err != nil { 167 return nil, err 168 } 169 170 ar, err := graph.Diff(graphID, parentID) 171 if err != nil { 172 return nil, err 173 } 174 defer ar.Close() 175 176 return ioutil.ReadAll(ar) 177 } 178 179 func TestLayerMigrationNoTarsplit(t *testing.T) { 180 // TODO Windows: Figure out why this is failing 181 if runtime.GOOS == "windows" { 182 t.Skip("Failing on Windows") 183 } 184 td, err := ioutil.TempDir("", "migration-test-") 185 if err != nil { 186 t.Fatal(err) 187 } 188 defer os.RemoveAll(td) 189 190 layer1Files := []FileApplier{ 191 newTestFile("/root/.bashrc", []byte("# Boring configuration"), 0644), 192 newTestFile("/etc/profile", []byte("# Base configuration"), 0644), 193 } 194 195 layer2Files := []FileApplier{ 196 newTestFile("/root/.bashrc", []byte("# Updated configuration"), 0644), 197 } 198 199 graph, err := newVFSGraphDriver(filepath.Join(td, "graphdriver-")) 200 if err != nil { 201 t.Fatal(err) 202 } 203 graphID1 := stringid.GenerateRandomID() 204 graphID2 := stringid.GenerateRandomID() 205 206 tar1, err := tarFromFilesInGraph(graph, graphID1, "", layer1Files...) 207 if err != nil { 208 t.Fatal(err) 209 } 210 211 tar2, err := tarFromFilesInGraph(graph, graphID2, graphID1, layer2Files...) 212 if err != nil { 213 t.Fatal(err) 214 } 215 216 root := filepath.Join(td, "layers") 217 ls, err := newStoreFromGraphDriver(root, graph, runtime.GOOS) 218 if err != nil { 219 t.Fatal(err) 220 } 221 222 newTarDataPath := filepath.Join(td, ".migration-tardata") 223 diffID, size, err := ls.(*layerStore).ChecksumForGraphID(graphID1, "", "", newTarDataPath) 224 if err != nil { 225 t.Fatal(err) 226 } 227 228 layer1a, err := ls.(*layerStore).RegisterByGraphID(graphID1, "", diffID, newTarDataPath, size) 229 if err != nil { 230 t.Fatal(err) 231 } 232 233 layer1b, err := ls.Register(bytes.NewReader(tar1), "") 234 if err != nil { 235 t.Fatal(err) 236 } 237 238 assertReferences(t, layer1a, layer1b) 239 240 // Attempt register, should be same 241 layer2a, err := ls.Register(bytes.NewReader(tar2), layer1a.ChainID()) 242 if err != nil { 243 t.Fatal(err) 244 } 245 246 diffID, size, err = ls.(*layerStore).ChecksumForGraphID(graphID2, graphID1, "", newTarDataPath) 247 if err != nil { 248 t.Fatal(err) 249 } 250 251 layer2b, err := ls.(*layerStore).RegisterByGraphID(graphID2, layer1a.ChainID(), diffID, newTarDataPath, size) 252 if err != nil { 253 t.Fatal(err) 254 } 255 assertReferences(t, layer2a, layer2b) 256 257 if metadata, err := ls.Release(layer2a); err != nil { 258 t.Fatal(err) 259 } else if len(metadata) > 0 { 260 t.Fatalf("Unexpected layer removal after first release: %#v", metadata) 261 } 262 263 metadata, err := ls.Release(layer2b) 264 if err != nil { 265 t.Fatal(err) 266 } 267 268 assertMetadata(t, metadata, createMetadata(layer2a)) 269 }