Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)
unclejack authored on 2014/05/14 03:49:12... | ... |
@@ -2,8 +2,10 @@ package main |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 |
+ "os" |
|
5 | 6 |
"os/exec" |
6 | 7 |
"path/filepath" |
8 |
+ "strings" |
|
7 | 9 |
"testing" |
8 | 10 |
) |
9 | 11 |
|
... | ... |
@@ -119,6 +121,92 @@ func TestAddWholeDirToRoot(t *testing.T) { |
119 | 119 |
logDone("build - add whole directory to root") |
120 | 120 |
} |
121 | 121 |
|
122 |
+// Issue #5270 - ensure we throw a better error than "unexpected EOF" |
|
123 |
+// when we can't access files in the context. |
|
124 |
+func TestBuildWithInaccessibleFilesInContext(t *testing.T) { |
|
125 |
+ buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildWithInaccessibleFilesInContext") |
|
126 |
+ addUserCmd := exec.Command("adduser", "unprivilegeduser") |
|
127 |
+ out, _, err := runCommandWithOutput(addUserCmd) |
|
128 |
+ errorOut(err, t, fmt.Sprintf("failed to add user: %v %v", out, err)) |
|
129 |
+ |
|
130 |
+ { |
|
131 |
+ // This is used to ensure we detect inaccessible files early during build in the cli client |
|
132 |
+ pathToInaccessibleFileBuildDirectory := filepath.Join(buildDirectory, "inaccessiblefile") |
|
133 |
+ pathToFileWithoutReadAccess := filepath.Join(pathToInaccessibleFileBuildDirectory, "fileWithoutReadAccess") |
|
134 |
+ |
|
135 |
+ err = os.Chown(pathToFileWithoutReadAccess, 0, 0) |
|
136 |
+ errorOut(err, t, fmt.Sprintf("failed to chown file to root: %s", err)) |
|
137 |
+ err = os.Chmod(pathToFileWithoutReadAccess, 0700) |
|
138 |
+ errorOut(err, t, fmt.Sprintf("failed to chmod file to 700: %s", err)) |
|
139 |
+ |
|
140 |
+ buildCommandStatement := fmt.Sprintf("%s build -t inaccessiblefiles .", dockerBinary) |
|
141 |
+ buildCmd := exec.Command("su", "unprivilegeduser", "-c", buildCommandStatement) |
|
142 |
+ buildCmd.Dir = pathToInaccessibleFileBuildDirectory |
|
143 |
+ out, exitCode, err := runCommandWithOutput(buildCmd) |
|
144 |
+ if err == nil || exitCode == 0 { |
|
145 |
+ t.Fatalf("build should have failed: %s %s", err, out) |
|
146 |
+ } |
|
147 |
+ |
|
148 |
+ // check if we've detected the failure before we started building |
|
149 |
+ if !strings.Contains(out, "no permission to read from ") { |
|
150 |
+ t.Fatalf("output should've contained the string: no permission to read from ") |
|
151 |
+ } |
|
152 |
+ |
|
153 |
+ if !strings.Contains(out, "Error checking context is accessible") { |
|
154 |
+ t.Fatalf("output should've contained the string: Error checking context is accessible") |
|
155 |
+ } |
|
156 |
+ } |
|
157 |
+ { |
|
158 |
+ // This is used to ensure we detect inaccessible directories early during build in the cli client |
|
159 |
+ pathToInaccessibleDirectoryBuildDirectory := filepath.Join(buildDirectory, "inaccessibledirectory") |
|
160 |
+ pathToDirectoryWithoutReadAccess := filepath.Join(pathToInaccessibleDirectoryBuildDirectory, "directoryWeCantStat") |
|
161 |
+ pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar") |
|
162 |
+ |
|
163 |
+ err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0) |
|
164 |
+ errorOut(err, t, fmt.Sprintf("failed to chown directory to root: %s", err)) |
|
165 |
+ err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444) |
|
166 |
+ errorOut(err, t, fmt.Sprintf("failed to chmod directory to 755: %s", err)) |
|
167 |
+ err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700) |
|
168 |
+ errorOut(err, t, fmt.Sprintf("failed to chmod file to 444: %s", err)) |
|
169 |
+ |
|
170 |
+ buildCommandStatement := fmt.Sprintf("%s build -t inaccessiblefiles .", dockerBinary) |
|
171 |
+ buildCmd := exec.Command("su", "unprivilegeduser", "-c", buildCommandStatement) |
|
172 |
+ buildCmd.Dir = pathToInaccessibleDirectoryBuildDirectory |
|
173 |
+ out, exitCode, err := runCommandWithOutput(buildCmd) |
|
174 |
+ if err == nil || exitCode == 0 { |
|
175 |
+ t.Fatalf("build should have failed: %s %s", err, out) |
|
176 |
+ } |
|
177 |
+ |
|
178 |
+ // check if we've detected the failure before we started building |
|
179 |
+ if !strings.Contains(out, "can't stat") { |
|
180 |
+ t.Fatalf("output should've contained the string: can't access %s", out) |
|
181 |
+ } |
|
182 |
+ |
|
183 |
+ if !strings.Contains(out, "Error checking context is accessible") { |
|
184 |
+ t.Fatalf("output should've contained the string: Error checking context is accessible") |
|
185 |
+ } |
|
186 |
+ |
|
187 |
+ } |
|
188 |
+ { |
|
189 |
+ // This is used to ensure we don't follow links when checking if everything in the context is accessible |
|
190 |
+ // This test doesn't require that we run commands as an unprivileged user |
|
191 |
+ pathToDirectoryWhichContainsLinks := filepath.Join(buildDirectory, "linksdirectory") |
|
192 |
+ |
|
193 |
+ buildCmd := exec.Command(dockerBinary, "build", "-t", "testlinksok", ".") |
|
194 |
+ buildCmd.Dir = pathToDirectoryWhichContainsLinks |
|
195 |
+ out, exitCode, err := runCommandWithOutput(buildCmd) |
|
196 |
+ if err != nil || exitCode != 0 { |
|
197 |
+ t.Fatalf("build should have worked: %s %s", err, out) |
|
198 |
+ } |
|
199 |
+ |
|
200 |
+ deleteImages("testlinksok") |
|
201 |
+ |
|
202 |
+ } |
|
203 |
+ deleteImages("inaccessiblefiles") |
|
204 |
+ logDone("build - ADD from context with inaccessible files must fail") |
|
205 |
+ logDone("build - ADD from context with accessible links must work") |
|
206 |
+} |
|
207 |
+ |
|
122 | 208 |
// TODO: TestCaching |
123 | 209 |
|
124 | 210 |
// TODO: TestADDCacheInvalidation |