Skip to content

Commit 4394a31

Browse files
committed
Issue docker-java#2: Switched to Java 7. Dockerfile is now using PosixFilePermission API to read file metadata and set correct file mode in tar header
1 parent 1aa0242 commit 4394a31

6 files changed

Lines changed: 169 additions & 4 deletions

File tree

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@ Java API client for [Docker](http://docs.docker.io/ "Docker")
44

55
Supports Docker Client API v1.3, Server version 0.5.0
66

7+
Java-7 branch is using new Java 7 API for file manipulations to keep metadata while building Dockerbuild file.
8+
With new API, there's *NO NEED* to explicitly set executable bit, e.g.
9+
10+
run cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh
11+
12+
713
## Build with Maven
814

915
###### Prerequisites:
1016

11-
* Java 1.6+
17+
* Java 1.7+
1218
* Maven 3.0.5
1319
* Docker daemon running
1420

src/main/java/com/kpelykh/docker/client/DockerClient.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import javax.ws.rs.core.MultivaluedMap;
2929
import java.io.File;
3030
import java.io.IOException;
31-
import java.io.InputStream;
3231
import java.util.List;
3332
import java.util.UUID;
3433

src/main/java/com/kpelykh/docker/client/utils/CompressArchiveUtil.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,27 @@
55
import java.io.FileInputStream;
66
import java.io.FileOutputStream;
77
import java.io.IOException;
8+
import java.nio.file.Files;
9+
import java.nio.file.Paths;
10+
import java.nio.file.attribute.PosixFilePermission;
11+
import java.nio.file.attribute.PosixFilePermissions;
812
import java.util.Collection;
13+
import java.util.Set;
914

1015
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
1116
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
1217
import org.apache.commons.io.FileUtils;
1318
import org.apache.commons.io.filefilter.RegexFileFilter;
1419
import org.apache.commons.lang.StringUtils;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
1522

1623
import static org.apache.commons.io.filefilter.FileFilterUtils.*;
1724

1825
public class CompressArchiveUtil {
1926

27+
private static final Logger LOGGER = LoggerFactory.getLogger(CompressArchiveUtil.class);
28+
2029
public static File archiveTARFiles(File baseDir, String archiveNameWithOutExtension) throws IOException {
2130

2231
File tarFile = null;
@@ -38,6 +47,13 @@ public static File archiveTARFiles(File baseDir, String archiveNameWithOutExtens
3847
for (File file : files) {
3948
TarArchiveEntry tarEntry = new TarArchiveEntry(file);
4049
tarEntry.setName(StringUtils.substringAfter(file.toString(), baseDir.getPath()));
50+
Set<PosixFilePermission> filePerm = null;
51+
try {
52+
filePerm = Files.getPosixFilePermissions(Paths.get(file.toURI()));
53+
tarEntry.setMode(new Permission('-' + PosixFilePermissions.toString(filePerm)).getOctalCode());
54+
} catch (IOException e) {
55+
LOGGER.trace("Could't read Posix file permissions for " + file.getPath());
56+
}
4157

4258
tos.putArchiveEntry(tarEntry);
4359

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package com.kpelykh.docker.client.utils;
2+
3+
import java.util.Arrays;
4+
5+
6+
/**
7+
* Encapsulating unix file permissions.
8+
*
9+
* @version $Id$
10+
*/
11+
public class Permission {
12+
13+
private String mask;
14+
15+
// {read, write, execute}
16+
private boolean[] owner = new boolean[3];
17+
private boolean[] group = new boolean[3];
18+
private boolean[] other = new boolean[3];
19+
20+
/**
21+
* @param mask the access string to parse the permissions from.
22+
* Must be someting like -rwxrwxrwx
23+
*/
24+
public Permission(String mask) {
25+
this.mask = mask;
26+
this.owner = this.getOwnerPermissions(mask);
27+
this.group = this.getGroupPermissions(mask);
28+
this.other = this.getOtherPermissions(mask);
29+
// log.debug("Permission:"+this.toString());
30+
}
31+
32+
/**
33+
* @return The unix access permissions including the the first bit
34+
*/
35+
public String getMask() {
36+
return this.mask;
37+
}
38+
39+
/**
40+
* @return a thee-dimensional boolean array representing read, write
41+
* and execute permissions (in that order) of the file owner.
42+
*/
43+
public boolean[] getOwnerPermissions() {
44+
return owner;
45+
}
46+
47+
/**
48+
* @return a thee-dimensional boolean array representing read, write
49+
* and execute permissions (in that order) of the group
50+
*/
51+
public boolean[] getGroupPermissions() {
52+
return group;
53+
}
54+
55+
/**
56+
* @return a thee-dimensional boolean array representing read, write
57+
* and execute permissions (in that order) of any user
58+
*/
59+
public boolean[] getOtherPermissions() {
60+
return other;
61+
}
62+
63+
private boolean[] getOwnerPermissions(String s) {
64+
boolean[] b = {
65+
s.charAt(1) == 'r',
66+
s.charAt(2) == 'w',
67+
s.charAt(3) == 'x' || s.charAt(3) == 's' || s.charAt(3) == 'S' || s.charAt(3) == 't' || s.charAt(3) == 'T' || s.charAt(3) == 'L'};
68+
return b;
69+
}
70+
71+
private boolean[] getGroupPermissions(String s) {
72+
boolean[] b = {
73+
s.charAt(4) == 'r',
74+
s.charAt(5) == 'w',
75+
s.charAt(6) == 'x' || s.charAt(6) == 's' || s.charAt(6) == 'S' || s.charAt(6) == 't' || s.charAt(6) == 'T' || s.charAt(6) == 'L'};
76+
return b;
77+
}
78+
79+
private boolean[] getOtherPermissions(String s) {
80+
boolean[] b = {
81+
s.charAt(7) == 'r',
82+
s.charAt(8) == 'w',
83+
s.charAt(9) == 'x' || s.charAt(9) == 's' || s.charAt(9) == 'S' || s.charAt(9) == 't' || s.charAt(9) == 'T' || s.charAt(9) == 'L'};
84+
return b;
85+
}
86+
87+
/**
88+
* @return i.e. rwxrwxrwx (777)
89+
*/
90+
public String toString() {
91+
return this.getMask() + " (" + this.getOctalCode() + ")";
92+
}
93+
94+
/**
95+
* @return The unix equivalent octal access code like 777
96+
*/
97+
public int getOctalCode() {
98+
String owner = "" + this.getOctalAccessNumber(this.getOwnerPermissions());
99+
String group = "" + this.getOctalAccessNumber(this.getGroupPermissions());
100+
String other = "" + this.getOctalAccessNumber(this.getOtherPermissions());
101+
return Integer.parseInt(owner + group + other);
102+
}
103+
104+
/*
105+
* 0 = no permissions whatsoever; this person cannot read, write, or execute the file
106+
* 1 = execute only
107+
* 2 = write only
108+
* 3 = write and execute (1+2)
109+
* 4 = read only
110+
* 5 = read and execute (4+1)
111+
* 6 = read and write (4+2)
112+
* 7 = read and write and execute (4+2+1)
113+
*/
114+
115+
//-rwxrwxrwx
116+
117+
private int getOctalAccessNumber(boolean[] permissions) {
118+
if (Arrays.equals(permissions, new boolean[]{false, false, false})) {
119+
return 0;
120+
}
121+
if (Arrays.equals(permissions, new boolean[]{false, false, true})) {
122+
return 1;
123+
}
124+
if (Arrays.equals(permissions, new boolean[]{false, true, false})) {
125+
return 2;
126+
}
127+
if (Arrays.equals(permissions, new boolean[]{false, true, true})) {
128+
return 3;
129+
}
130+
if (Arrays.equals(permissions, new boolean[]{true, false, false})) {
131+
return 4;
132+
}
133+
if (Arrays.equals(permissions, new boolean[]{true, false, true})) {
134+
return 5;
135+
}
136+
if (Arrays.equals(permissions, new boolean[]{true, true, false})) {
137+
return 6;
138+
}
139+
if (Arrays.equals(permissions, new boolean[]{true, true, true})) {
140+
return 7;
141+
}
142+
return -1;
143+
}
144+
}

src/test/resources/testAddFile/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ FROM ubuntu
44

55
add ./testrun.sh /tmp/
66

7-
run cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh
7+
run cp /tmp/testrun.sh /usr/local/bin/
88

99
CMD ["testrun.sh"]

src/test/resources/testAddFolder/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ add . /src/
66

77
run ls -la /src
88

9-
run cp /src/folderA/testAddFolder.sh /usr/local/bin/ && chmod +x /usr/local/bin/testAddFolder.sh
9+
run cp /src/folderA/testAddFolder.sh /usr/local/bin/
1010

1111
CMD ["testAddFolder.sh"]

0 commit comments

Comments
 (0)