aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools.go')
-rw-r--r--vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools.go195
1 files changed, 0 insertions, 195 deletions
diff --git a/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools.go b/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools.go
deleted file mode 100644
index a1301ee..0000000
--- a/vendor/github.com/fsouza/go-dockerclient/external/github.com/docker/docker/pkg/idtools/idtools.go
+++ /dev/null
@@ -1,195 +0,0 @@
1package idtools
2
3import (
4 "bufio"
5 "fmt"
6 "os"
7 "sort"
8 "strconv"
9 "strings"
10)
11
12// IDMap contains a single entry for user namespace range remapping. An array
13// of IDMap entries represents the structure that will be provided to the Linux
14// kernel for creating a user namespace.
15type IDMap struct {
16 ContainerID int `json:"container_id"`
17 HostID int `json:"host_id"`
18 Size int `json:"size"`
19}
20
21type subIDRange struct {
22 Start int
23 Length int
24}
25
26type ranges []subIDRange
27
28func (e ranges) Len() int { return len(e) }
29func (e ranges) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
30func (e ranges) Less(i, j int) bool { return e[i].Start < e[j].Start }
31
32const (
33 subuidFileName string = "/etc/subuid"
34 subgidFileName string = "/etc/subgid"
35)
36
37// MkdirAllAs creates a directory (include any along the path) and then modifies
38// ownership to the requested uid/gid. If the directory already exists, this
39// function will still change ownership to the requested uid/gid pair.
40func MkdirAllAs(path string, mode os.FileMode, ownerUID, ownerGID int) error {
41 return mkdirAs(path, mode, ownerUID, ownerGID, true, true)
42}
43
44// MkdirAllNewAs creates a directory (include any along the path) and then modifies
45// ownership ONLY of newly created directories to the requested uid/gid. If the
46// directories along the path exist, no change of ownership will be performed
47func MkdirAllNewAs(path string, mode os.FileMode, ownerUID, ownerGID int) error {
48 return mkdirAs(path, mode, ownerUID, ownerGID, true, false)
49}
50
51// MkdirAs creates a directory and then modifies ownership to the requested uid/gid.
52// If the directory already exists, this function still changes ownership
53func MkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int) error {
54 return mkdirAs(path, mode, ownerUID, ownerGID, false, true)
55}
56
57// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.
58// If the maps are empty, then the root uid/gid will default to "real" 0/0
59func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {
60 var uid, gid int
61
62 if uidMap != nil {
63 xUID, err := ToHost(0, uidMap)
64 if err != nil {
65 return -1, -1, err
66 }
67 uid = xUID
68 }
69 if gidMap != nil {
70 xGID, err := ToHost(0, gidMap)
71 if err != nil {
72 return -1, -1, err
73 }
74 gid = xGID
75 }
76 return uid, gid, nil
77}
78
79// ToContainer takes an id mapping, and uses it to translate a
80// host ID to the remapped ID. If no map is provided, then the translation
81// assumes a 1-to-1 mapping and returns the passed in id
82func ToContainer(hostID int, idMap []IDMap) (int, error) {
83 if idMap == nil {
84 return hostID, nil
85 }
86 for _, m := range idMap {
87 if (hostID >= m.HostID) && (hostID <= (m.HostID + m.Size - 1)) {
88 contID := m.ContainerID + (hostID - m.HostID)
89 return contID, nil
90 }
91 }
92 return -1, fmt.Errorf("Host ID %d cannot be mapped to a container ID", hostID)
93}
94
95// ToHost takes an id mapping and a remapped ID, and translates the
96// ID to the mapped host ID. If no map is provided, then the translation
97// assumes a 1-to-1 mapping and returns the passed in id #
98func ToHost(contID int, idMap []IDMap) (int, error) {
99 if idMap == nil {
100 return contID, nil
101 }
102 for _, m := range idMap {
103 if (contID >= m.ContainerID) && (contID <= (m.ContainerID + m.Size - 1)) {
104 hostID := m.HostID + (contID - m.ContainerID)
105 return hostID, nil
106 }
107 }
108 return -1, fmt.Errorf("Container ID %d cannot be mapped to a host ID", contID)
109}
110
111// CreateIDMappings takes a requested user and group name and
112// using the data from /etc/sub{uid,gid} ranges, creates the
113// proper uid and gid remapping ranges for that user/group pair
114func CreateIDMappings(username, groupname string) ([]IDMap, []IDMap, error) {
115 subuidRanges, err := parseSubuid(username)
116 if err != nil {
117 return nil, nil, err
118 }
119 subgidRanges, err := parseSubgid(groupname)
120 if err != nil {
121 return nil, nil, err
122 }
123 if len(subuidRanges) == 0 {
124 return nil, nil, fmt.Errorf("No subuid ranges found for user %q", username)
125 }
126 if len(subgidRanges) == 0 {
127 return nil, nil, fmt.Errorf("No subgid ranges found for group %q", groupname)
128 }
129
130 return createIDMap(subuidRanges), createIDMap(subgidRanges), nil
131}
132
133func createIDMap(subidRanges ranges) []IDMap {
134 idMap := []IDMap{}
135
136 // sort the ranges by lowest ID first
137 sort.Sort(subidRanges)
138 containerID := 0
139 for _, idrange := range subidRanges {
140 idMap = append(idMap, IDMap{
141 ContainerID: containerID,
142 HostID: idrange.Start,
143 Size: idrange.Length,
144 })
145 containerID = containerID + idrange.Length
146 }
147 return idMap
148}
149
150func parseSubuid(username string) (ranges, error) {
151 return parseSubidFile(subuidFileName, username)
152}
153
154func parseSubgid(username string) (ranges, error) {
155 return parseSubidFile(subgidFileName, username)
156}
157
158func parseSubidFile(path, username string) (ranges, error) {
159 var rangeList ranges
160
161 subidFile, err := os.Open(path)
162 if err != nil {
163 return rangeList, err
164 }
165 defer subidFile.Close()
166
167 s := bufio.NewScanner(subidFile)
168 for s.Scan() {
169 if err := s.Err(); err != nil {
170 return rangeList, err
171 }
172
173 text := strings.TrimSpace(s.Text())
174 if text == "" {
175 continue
176 }
177 parts := strings.Split(text, ":")
178 if len(parts) != 3 {
179 return rangeList, fmt.Errorf("Cannot parse subuid/gid information: Format not correct for %s file", path)
180 }
181 if parts[0] == username {
182 // return the first entry for a user; ignores potential for multiple ranges per user
183 startid, err := strconv.Atoi(parts[1])
184 if err != nil {
185 return rangeList, fmt.Errorf("String to int conversion failed during subuid/gid parsing of %s: %v", path, err)
186 }
187 length, err := strconv.Atoi(parts[2])
188 if err != nil {
189 return rangeList, fmt.Errorf("String to int conversion failed during subuid/gid parsing of %s: %v", path, err)
190 }
191 rangeList = append(rangeList, subIDRange{startid, length})
192 }
193 }
194 return rangeList, nil
195}