Skip to content

Commit a3880ed

Browse files
committed
Implemente Device parser
Signed-off-by: Kanstantsin Shautsou <kanstantsin.sha@gmail.com>
1 parent 0a1b34c commit a3880ed

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

src/main/java/com/github/dockerjava/api/model/Device.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.github.dockerjava.api.model;
22

33
import static com.google.common.base.Preconditions.checkNotNull;
4+
import static org.apache.commons.lang.BooleanUtils.isNotTrue;
5+
import static org.apache.commons.lang.StringUtils.isEmpty;
46

57
import org.apache.commons.lang.builder.EqualsBuilder;
68
import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -9,6 +11,10 @@
911
import com.fasterxml.jackson.annotation.JsonInclude.Include;
1012
import com.fasterxml.jackson.annotation.JsonProperty;
1113

14+
import javax.annotation.Nonnull;
15+
import java.util.HashMap;
16+
import java.util.Map;
17+
1218
@JsonInclude(Include.NON_NULL)
1319
public class Device {
1420

@@ -45,6 +51,66 @@ public String getPathOnHost() {
4551
return pathOnHost;
4652
}
4753

54+
@Nonnull
55+
public static Device parse(@Nonnull String deviceStr) {
56+
String src = "";
57+
String dst = "";
58+
String permissions = "rwm";
59+
final String[] arr = deviceStr.split(":");
60+
switch (arr.length) {
61+
case 3: {
62+
permissions = arr[2];
63+
}
64+
case 2: {
65+
if (validDeviceMode(arr[1])) {
66+
permissions = arr[1];
67+
} else {
68+
dst = arr[1];
69+
}
70+
}
71+
case 1: {
72+
src = arr[0];
73+
break;
74+
}
75+
default: {
76+
throw new IllegalArgumentException("invalid device specification: " + deviceStr);
77+
}
78+
}
79+
80+
if (isEmpty(dst)) {
81+
dst = src;
82+
}
83+
84+
return new Device(permissions, dst, src);
85+
}
86+
87+
/**
88+
* ValidDeviceMode checks if the mode for device is valid or not.
89+
* Valid mode is a composition of r (read), w (write), and m (mknod).
90+
*
91+
* @link https://github.com/docker/docker/blob/6b4a46f28266031ce1a1315f17fb69113a06efe1/runconfig/opts/parse.go#L796
92+
*/
93+
private static boolean validDeviceMode(String deviceMode) {
94+
Map<String, Boolean> validModes = new HashMap<>(3);
95+
validModes.put("r", true);
96+
validModes.put("w", true);
97+
validModes.put("m", true);
98+
99+
if (isEmpty(deviceMode)) {
100+
return false;
101+
}
102+
103+
for (char ch : deviceMode.toCharArray()) {
104+
final String mode = String.valueOf(ch);
105+
if (isNotTrue(validModes.get(mode))) {
106+
return false; // wrong mode
107+
}
108+
validModes.put(mode, false);
109+
}
110+
111+
return true;
112+
}
113+
48114
@Override
49115
public boolean equals(Object obj) {
50116
if (obj instanceof Device) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.github.dockerjava.api.model;
2+
3+
import org.testng.annotations.Test;
4+
5+
import static org.hamcrest.MatcherAssert.assertThat;
6+
import static org.hamcrest.Matchers.equalTo;
7+
8+
/**
9+
* @author Kanstantsin Shautsou
10+
*/
11+
public class DeviceTest {
12+
@Test
13+
public void testParse() throws Exception {
14+
assertThat(Device.parse("/dev/sda:/dev/xvdc:r"),
15+
equalTo(new Device("r", "/dev/xvdc", "/dev/sda")));
16+
17+
assertThat(Device.parse("/dev/snd:rw"),
18+
equalTo(new Device("rw", "/dev/snd", "/dev/snd")));
19+
20+
assertThat(Device.parse("/dev/snd:/something"),
21+
equalTo(new Device("rwm", "/something", "/dev/snd")));
22+
23+
assertThat(Device.parse("/dev/snd:/something:rw"),
24+
equalTo(new Device("rw", "/something", "/dev/snd")));
25+
26+
}
27+
}

0 commit comments

Comments
 (0)