Use aufs to handle parents whiteouts instead of doing it manually
| ... | ... |
@@ -150,6 +150,82 @@ func TestMultipleAttachRestart(t *testing.T) {
|
| 150 | 150 |
} |
| 151 | 151 |
} |
| 152 | 152 |
|
| 153 |
+func TestDiff(t *testing.T) {
|
|
| 154 |
+ runtime, err := newTestRuntime() |
|
| 155 |
+ if err != nil {
|
|
| 156 |
+ t.Fatal(err) |
|
| 157 |
+ } |
|
| 158 |
+ defer nuke(runtime) |
|
| 159 |
+ |
|
| 160 |
+ // Create a container and remove a file |
|
| 161 |
+ container1, err := runtime.Create( |
|
| 162 |
+ &Config{
|
|
| 163 |
+ Image: GetTestImage(runtime).Id, |
|
| 164 |
+ Cmd: []string{"/bin/rm", "/etc/passwd"},
|
|
| 165 |
+ }, |
|
| 166 |
+ ) |
|
| 167 |
+ if err != nil {
|
|
| 168 |
+ t.Fatal(err) |
|
| 169 |
+ } |
|
| 170 |
+ defer runtime.Destroy(container1) |
|
| 171 |
+ |
|
| 172 |
+ if err := container1.Run(); err != nil {
|
|
| 173 |
+ t.Fatal(err) |
|
| 174 |
+ } |
|
| 175 |
+ |
|
| 176 |
+ // Check the changelog |
|
| 177 |
+ c, err := container1.Changes() |
|
| 178 |
+ if err != nil {
|
|
| 179 |
+ t.Fatal(err) |
|
| 180 |
+ } |
|
| 181 |
+ success := false |
|
| 182 |
+ for _, elem := range c {
|
|
| 183 |
+ if elem.Path == "/etc/passwd" && elem.Kind == 2 {
|
|
| 184 |
+ success = true |
|
| 185 |
+ } |
|
| 186 |
+ } |
|
| 187 |
+ if !success {
|
|
| 188 |
+ t.Fatalf("/etc/passwd as been removed but is not present in the diff")
|
|
| 189 |
+ } |
|
| 190 |
+ |
|
| 191 |
+ // Commit the container |
|
| 192 |
+ rwTar, err := container1.ExportRw() |
|
| 193 |
+ if err != nil {
|
|
| 194 |
+ t.Error(err) |
|
| 195 |
+ } |
|
| 196 |
+ img, err := runtime.graph.Create(rwTar, container1, "unit test commited image - diff", "") |
|
| 197 |
+ if err != nil {
|
|
| 198 |
+ t.Error(err) |
|
| 199 |
+ } |
|
| 200 |
+ |
|
| 201 |
+ // Create a new container from the commited image |
|
| 202 |
+ container2, err := runtime.Create( |
|
| 203 |
+ &Config{
|
|
| 204 |
+ Image: img.Id, |
|
| 205 |
+ Cmd: []string{"cat", "/etc/passwd"},
|
|
| 206 |
+ }, |
|
| 207 |
+ ) |
|
| 208 |
+ if err != nil {
|
|
| 209 |
+ t.Fatal(err) |
|
| 210 |
+ } |
|
| 211 |
+ defer runtime.Destroy(container2) |
|
| 212 |
+ |
|
| 213 |
+ if err := container2.Run(); err != nil {
|
|
| 214 |
+ t.Fatal(err) |
|
| 215 |
+ } |
|
| 216 |
+ |
|
| 217 |
+ // Check the changelog |
|
| 218 |
+ c, err = container2.Changes() |
|
| 219 |
+ if err != nil {
|
|
| 220 |
+ t.Fatal(err) |
|
| 221 |
+ } |
|
| 222 |
+ for _, elem := range c {
|
|
| 223 |
+ if elem.Path == "/etc/passwd" {
|
|
| 224 |
+ t.Fatalf("/etc/passwd should not be present in the diff after commit.")
|
|
| 225 |
+ } |
|
| 226 |
+ } |
|
| 227 |
+} |
|
| 228 |
+ |
|
| 153 | 229 |
func TestCommitRun(t *testing.T) {
|
| 154 | 230 |
runtime, err := newTestRuntime() |
| 155 | 231 |
if err != nil {
|
| ... | ... |
@@ -92,7 +92,7 @@ func MountAUFS(ro []string, rw string, target string) error {
|
| 92 | 92 |
rwBranch := fmt.Sprintf("%v=rw", rw)
|
| 93 | 93 |
roBranches := "" |
| 94 | 94 |
for _, layer := range ro {
|
| 95 |
- roBranches += fmt.Sprintf("%v=ro:", layer)
|
|
| 95 |
+ roBranches += fmt.Sprintf("%v=ro+wh:", layer)
|
|
| 96 | 96 |
} |
| 97 | 97 |
branches := fmt.Sprintf("br:%v:%v", rwBranch, roBranches)
|
| 98 | 98 |
|
| ... | ... |
@@ -136,34 +136,9 @@ func (image *Image) Mount(root, rw string) error {
|
| 136 | 136 |
if err := os.Mkdir(rw, 0755); err != nil && !os.IsExist(err) {
|
| 137 | 137 |
return err |
| 138 | 138 |
} |
| 139 |
- // FIXME: @creack shouldn't we do this after going over changes? |
|
| 140 | 139 |
if err := MountAUFS(layers, rw, root); err != nil {
|
| 141 | 140 |
return err |
| 142 | 141 |
} |
| 143 |
- // FIXME: Create tests for deletion |
|
| 144 |
- // FIXME: move this part to change.go |
|
| 145 |
- // Retrieve the changeset from the parent and apply it to the container |
|
| 146 |
- // - Retrieve the changes |
|
| 147 |
- changes, err := Changes(layers, layers[0]) |
|
| 148 |
- if err != nil {
|
|
| 149 |
- return err |
|
| 150 |
- } |
|
| 151 |
- // Iterate on changes |
|
| 152 |
- for _, c := range changes {
|
|
| 153 |
- // If there is a delete |
|
| 154 |
- if c.Kind == ChangeDelete {
|
|
| 155 |
- // Make sure the directory exists |
|
| 156 |
- file_path, file_name := path.Dir(c.Path), path.Base(c.Path) |
|
| 157 |
- if err := os.MkdirAll(path.Join(rw, file_path), 0755); err != nil {
|
|
| 158 |
- return err |
|
| 159 |
- } |
|
| 160 |
- // And create the whiteout (we just need to create empty file, discard the return) |
|
| 161 |
- if _, err := os.Create(path.Join(path.Join(rw, file_path), |
|
| 162 |
- ".wh."+path.Base(file_name))); err != nil {
|
|
| 163 |
- return err |
|
| 164 |
- } |
|
| 165 |
- } |
|
| 166 |
- } |
|
| 167 | 142 |
return nil |
| 168 | 143 |
} |
| 169 | 144 |
|