Commit graph

69 commits

Author SHA1 Message Date
Sebastiaan van Stijn
df3a321164
migrate to github.com/moby/sys/user
The github.com/opencontainers/runc/libcontainer/user package was moved
to a separate module. While there's still uses of the old module in
our code-base, runc itself is migrating to the new module, and deprecated
the old package (for runc 1.2).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-24 15:45:02 +02:00
Sebastiaan van Stijn
b5376c7cec
pkg/idtools: remove sync.Once, and include lookup error
When running a `docker cp` to copy files to/from a container, the
lookup of the `getent` executable happens within the container's
filesystem, so we cannot re-use the results.

Unfortunately, that also means we can't preserve the results for
any other uses of these functions, but probably the lookup should not
be "too" costly.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-09-06 17:34:26 +02:00
Sebastiaan van Stijn
1da079f211
pkg/idtools: use string-literals for easier grep'ing
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-07-05 12:27:01 +02:00
Nicolas De Loof
3cc5d62f8a
run getent with a noop stdin
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2023-06-12 09:35:40 +02:00
Sebastiaan van Stijn
ab35df454d
remove pre-go1.17 build-tags
Removed pre-go1.17 build-tags with go fix;

    go mod init
    go fix -mod=readonly ./...
    rm go.mod

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-19 20:38:51 +02:00
Sebastiaan van Stijn
1e88fe578e
pkg/idtools: remove execCmd() utility
The `execCmd()` utility was a basic wrapper around `exec.Command()`. Inlining it
makes the code more transparent.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-01 21:13:10 +01:00
Sebastiaan van Stijn
69f72417f4
pkg/idtools: remove CanAccess(), and move to daemon
The implementation of CanAccess() is very rudimentary, and should
not be used for anything other than a basic check (and maybe not
even for that). It's only used in a single location in the daemon,
so move it there, and un-export it to not encourage others to use
it out of context.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 22:42:39 +02:00
Sebastiaan van Stijn
ee34a8ac29
pkg/idtools: setPermissions() accept Identity as argument
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 22:42:39 +02:00
Sebastiaan van Stijn
bca90530fa
pkg/idtools: simplify if-statement
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 22:42:38 +02:00
Sebastiaan van Stijn
d68fa0382d
pkg/idtools: don't use system.Stat() on unix
Looks like we don't need the abstraction, so we can reduce the
dependency on pkg/system.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-15 22:42:35 +02:00
Sebastiaan van Stijn
11cceea58a
pkg/idtools: cleanup errors
Most of the package was using stdlib's errors package, so replacing two calls
to pkg/errors with stdlib. Also fixing capitalization of error strings.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 21:56:28 +02:00
Sebastiaan van Stijn
8d5b17e939
pkg/idtools: don't use system.MkdirAll() where not needed
On unix, it's an alias for os.MkdirAll, so remove its use to be
more transparent what's being used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 21:55:18 +02:00
Sebastiaan van Stijn
2e74e307d0
pkg/idtools: format code with gofumpt
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 21:55:04 +02:00
Sebastiaan van Stijn
0fc13104e7
pkg/idtools: CanAccess(): reorder checks to allow early return
Merge the accessible() function into CanAccess, and check world-
readable permissions first, before checking owner and group.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 21:54:23 +02:00
Sebastiaan van Stijn
1fccb39316
pkg/idtools: remove unused CanAccess() stub for Windows
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 18:46:05 +02:00
Sebastiaan van Stijn
3b9b5842b3
pkg/idtools: mkdirAs(): move var and comment to where it's used
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 18:45:33 +02:00
Sebastiaan van Stijn
27aea4956c
pkg/idtools: mkdirAs() be more explicit about ignored args on Windows
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-08 17:11:05 +02:00
Sebastiaan van Stijn
07b1aa822c
pkg/system: move GetExitCode() to pkg/idtools, and un-export
This utility was only used in a single place, and had no external consumers.
Move it to where it's used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-05 16:20:33 +02:00
Sebastiaan van Stijn
412c650e05
pkg/*: fix "empty-lines" (revive)
pkg/directory/directory.go:9:49: empty-lines: extra empty line at the start of a block (revive)
    pkg/pubsub/publisher.go:8:48: empty-lines: extra empty line at the start of a block (revive)
    pkg/loopback/attach_loopback.go:96:69: empty-lines: extra empty line at the start of a block (revive)
    pkg/devicemapper/devmapper_wrapper.go:136:48: empty-lines: extra empty line at the start of a block (revive)
    pkg/devicemapper/devmapper.go:391:35: empty-lines: extra empty line at the end of a block (revive)
    pkg/devicemapper/devmapper.go:676:35: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/changes_posix_test.go:15:38: empty-lines: extra empty line at the end of a block (revive)
    pkg/devicemapper/devmapper.go:241:51: empty-lines: extra empty line at the start of a block (revive)
    pkg/fileutils/fileutils_test.go:17:47: empty-lines: extra empty line at the end of a block (revive)
    pkg/fileutils/fileutils_test.go:34:48: empty-lines: extra empty line at the end of a block (revive)
    pkg/fileutils/fileutils_test.go:318:32: empty-lines: extra empty line at the end of a block (revive)
    pkg/tailfile/tailfile.go:171:6: empty-lines: extra empty line at the end of a block (revive)
    pkg/tarsum/fileinfosums_test.go:16:41: empty-lines: extra empty line at the end of a block (revive)
    pkg/tarsum/tarsum_test.go:198:42: empty-lines: extra empty line at the start of a block (revive)
    pkg/tarsum/tarsum_test.go:294:25: empty-lines: extra empty line at the start of a block (revive)
    pkg/tarsum/tarsum_test.go:407:34: empty-lines: extra empty line at the end of a block (revive)
    pkg/ioutils/fswriters_test.go:52:45: empty-lines: extra empty line at the end of a block (revive)
    pkg/ioutils/writers_test.go:24:39: empty-lines: extra empty line at the end of a block (revive)
    pkg/ioutils/bytespipe_test.go:78:26: empty-lines: extra empty line at the end of a block (revive)
    pkg/sysinfo/sysinfo_linux_test.go:13:37: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/archive_linux_test.go:57:64: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/changes.go:248:72: empty-lines: extra empty line at the start of a block (revive)
    pkg/archive/changes_posix_test.go:15:38: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/copy.go:248:124: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/diff_test.go:198:44: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/archive.go:304:12: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/archive.go:749:37: empty-lines: extra empty line at the end of a block (revive)
    pkg/archive/archive.go:812:81: empty-lines: extra empty line at the start of a block (revive)
    pkg/archive/copy_unix_test.go:347:34: empty-lines: extra empty line at the end of a block (revive)
    pkg/system/path.go:11:39: empty-lines: extra empty line at the end of a block (revive)
    pkg/system/meminfo_linux.go:29:21: empty-lines: extra empty line at the end of a block (revive)
    pkg/plugins/plugins.go:135:32: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/response.go:71:48: empty-lines: extra empty line at the start of a block (revive)
    pkg/authorization/api_test.go:18:51: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/middleware_test.go:23:44: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/middleware_unix_test.go:17:46: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/api_test.go:57:45: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/response.go:83:50: empty-lines: extra empty line at the start of a block (revive)
    pkg/authorization/api_test.go:66:47: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/middleware_unix_test.go:45:48: empty-lines: extra empty line at the end of a block (revive)
    pkg/authorization/response.go:145:75: empty-lines: extra empty line at the start of a block (revive)
    pkg/authorization/middleware_unix_test.go:56:51: empty-lines: extra empty line at the end of a block (revive)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-28 01:58:49 +02:00
Sebastiaan van Stijn
1e13247d6d
pkg/idtools: mkdirAs(): fix infinite loops and repeated "chown"
This fixes an inifinite loop in mkdirAs(), used by `MkdirAllAndChown`,
`MkdirAndChown`, and `MkdirAllAndChownNew`, as well as directories being
chown'd multiple times when relative paths are used.

The for loop in this function was incorrectly assuming that;

1. `filepath.Dir()` would always return the parent directory of any given path
2. traversing any given path to ultimately result in "/"

While this is correct for absolute and "cleaned" paths, both assumptions are
incorrect in some variations of "path";

1. for paths with a trailing path-separator ("some/path/"), or dot ("."),
   `filepath.Dir()` considers the (implicit) "." to be a location _within_ the
   directory, and returns "some/path" as ("parent") directory. This resulted
   in the path itself to be included _twice_ in the list of paths to chown.
2. for relative paths ("./some-path", "../some-path"), "traversing" the path
   would never end in "/", causing the for loop to run indefinitely:

    ```go
    // walk back to "/" looking for directories which do not exist
    // and add them to the paths array for chown after creation
    dirPath := path
    for {
        dirPath = filepath.Dir(dirPath)
        if dirPath == "/" {
            break
        }
        if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) {
            paths = append(paths, dirPath)
        }
    }
    ```

A _partial_ mitigation for this would be to use `filepath.Clean()` before using
the path (while `filepath.Dir()` _does_ call `filepath.Clean()`, it only does so
_after_ some processing, so only cleans the result). Doing so would prevent the
double chown from happening, but would not prevent the "final" path to be "."
or ".." (in the relative path case), still causing an infinite loop, or
additional checks for "." / ".." to be needed.

| path           | filepath.Dir(path) | filepath.Dir(filepath.Clean(path)) |
|----------------|--------------------|------------------------------------|
| some-path      | .                  | .                                  |
| ./some-path    | .                  | .                                  |
| ../some-path   | ..                 | ..                                 |
| some/path/     | some/path          | some                               |
| ./some/path/   | some/path          | some                               |
| ../some/path/  | ../some/path       | ../some                            |
| some/path/.    | some/path          | some                               |
| ./some/path/.  | some/path          | some                               |
| ../some/path/. | ../some/path       | ../some                            |
| /some/path/    | /some/path         | /some                              |
| /some/path/.   | /some/path         | /some                              |

Instead, this patch adds a `filepath.Abs()` to the function, so make sure that
paths are both cleaned, and not resulting in an infinite loop.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-27 19:15:16 +02:00
Sebastiaan van Stijn
df965f51bf
pkg/idtools: remove deprecated NewIdentityMapping, UIDS() and GIDS()
These were deprecated in 098a44c07f, which is
in the 22.06 branch, and no longer in use since e05f614267
so we can remove them from the master branch.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-08-09 18:03:29 +02:00
Cory Snider
098a44c07f Finish refactor of UID/GID usage to a new struct
Finish the refactor which was partially completed with commit
34536c498d, passing around IdentityMapping structs instead of pairs of
[]IDMap slices.

Existing code which uses []IDMap relies on zero-valued fields to be
valid, empty mappings. So in order to successfully finish the
refactoring without introducing bugs, their replacement therefore also
needs to have a useful zero value which represents an empty mapping.
Change IdentityMapping to be a pass-by-value type so that there are no
nil pointers to worry about.

The functionality provided by the deprecated NewIDMappingsFromMaps
function is required by unit tests to to construct arbitrary
IdentityMapping values. And the daemon will always need to access the
mappings to pass them to the Linux kernel. Accommodate these use cases
by exporting the struct fields instead. BuildKit currently depends on
the UIDs and GIDs methods so we cannot get rid of them yet.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-03-14 16:28:57 -04:00
Eng Zer Jun
c55a4ac779
refactor: move from io/ioutil to io and os package
The io/ioutil package has been deprecated in Go 1.16. This commit
replaces the existing io/ioutil functions with their new definitions in
io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-08-27 14:56:57 +08:00
Sebastiaan van Stijn
686be57d0a
Update to Go 1.17.0, and gofmt with Go 1.17
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-08-24 23:33:27 +02:00
Sebastiaan van Stijn
46c591b045
pkg/system: deprecate some consts and move them to pkg/idtools
These consts were used in combination with idtools utilities, which
makes it a more logical location for these consts to live.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-06-18 23:16:15 +02:00
Grant Millar
2ad187fd4a Fix userns-remap option when username & UID match
Signed-off-by: Grant Millar <rid@cylo.io>
2021-02-10 15:58:34 +00:00
Brian Goff
66dffbec86
Ensure MkdirAllAndChown also sets perms
Generally if we ever need to change perms of a dir, between versions,
this ensures the permissions actually change when we think it should
change without having to handle special cases if it already existed.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit edb62a3ace)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-02 13:01:20 +01:00
Sebastiaan van Stijn
ea9886cec4
pkg/idtools: refactor to avoid string-splitting
The package used a lot of string-formatting, followed by string-splitting.
This looked to originate from attempts to use templating to allow future
extensibility (9a3ab0358e).

Looking at the history of the package, only a single update was made to
these templates, 5 years go, which makes it unlikely that more templating
will be needed.

This patch simplifies the handling of arguments to use `[]string` instead
of a single `string` (and splitting to a `[]string`). This both simplifies
the code somewhat, and prevents user/group-names containing spaces to be
splitted (causing, e.g. `getent` to fail).

Note that user/group-names containing spaces are invalid (or at least
discouraged), there are situations where such names may be used, so we
should avoid breaking on such names.

Before this change, a user/group name with a space in its name would fail;

    dockerd --userns-remap="user:domain users"
    INFO[2020-08-19T10:26:59.288868661+02:00] Starting up
    Error during groupname lookup for "domain users": getent unable to find entry "domain" in group database

With this change:

    # Add some possibly problematic usernames for testing
    # need to do this manually, as `adduser` / `useradd` won't accept these names
    echo 'user name1002:1002::/home/one:/bin/false' >> /etc/passwd; \
    echo 'user name1002:' >> /etc/group; \
    echo 'user name:1266401166:65536' >> /etc/subuid; \
    echo 'user name:1266401153:65536' >> /etc/subgid; \
    echo 'user$HOME1003:1003::/home/one:/bin/false' >> /etc/passwd; \
    echo 'user$HOME1003:' >> /etc/group; \
    echo 'user$HOME:1266401166:65536' >> /etc/subuid; \
    echo 'user$HOME:1266401153:65536' >> /etc/subgid; \
    echo 'user'"'"'name1004:1004::/home/one:/bin/false' >> /etc/passwd; \
    echo 'user'"'"'name1004:' >> /etc/group; \
    echo 'user'"'"'name:1266401166:65536' >> /etc/subuid; \
    echo 'user'"'"'name:1266401153:65536' >> /etc/subgid; \
    echo 'user"name1005:1005::/home/one:/bin/false' >> /etc/passwd; \
    echo 'user"name1005:' >> /etc/group; \
    echo 'user"name:1266401166:65536' >> /etc/subuid; \
    echo 'user"name:1266401153:65536' >> /etc/subgid;

    # Start the daemon using those users
    dockerd --userns-remap="user name:user name"
    dockerd --userns-remap='user$HOME:user$HOME'
    dockerd --userns-remap="user'name":"user'name"
    dockerd --userns-remap='user"name':'user"name'

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-20 12:24:38 +02:00
Akhil Mohan
7ad0da7051
remove group name from identity mapping
NewIdentityMapping took group name as an argument, and used
the group name also to parse the /etc/sub{uid,gui}. But as per
linux man pages, the sub{uid,gid} file maps username or uid,
not a group name.

Therefore, all occurrences where mapping is used need to
consider only username and uid. Code trying to map using gid
and group name in the daemon is also removed.

Signed-off-by: Akhil Mohan <akhil.mohan@mayadata.io>
2020-06-03 20:04:42 +05:30
Kir Kolyshkin
745ed9686b pkg/idtools: fix use of bufio.Scanner.Err
The Err() method should be called after the Scan() loop,
not inside it.

Fixes: 9a3ab0358e
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2020-03-31 14:32:49 -07:00
Sebastiaan van Stijn
9f0b3f5609
bump gotest.tools v3.0.1 for compatibility with Go 1.14
full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-02-11 00:06:42 +01:00
Sebastiaan van Stijn
a45b3a92f6
pkg/idtools: normalize comment formatting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-11-27 15:40:23 +01:00
Sebastiaan van Stijn
2c31edbbb6
unconvert: remove unnescessary conversions
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-09-18 12:57:33 +02:00
Sebastiaan van Stijn
e554ab5589
Allow system.MkDirAll() to be used as drop-in for os.MkDirAll()
also renamed the non-windows variant of this file to be
consistent with other files in this package

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-08-08 15:05:49 +02:00
Jonas Dohse
c4628d79d2 Stop sorting uid and gid ranges in id maps
Moby currently sorts uid and gid ranges in id maps. This causes subuid
and subgid files to be interpreted wrongly.

The subuid file

```
> cat /etc/subuid
jonas:100000:1000
jonas:1000:1
```

configures that the container uids 0-999 are mapped to the host uids
100000-100999 and uid 1000 in the container is mapped to uid 1000 on the
host. The expected uid_map is:

```
> docker run ubuntu cat /proc/self/uid_map
         0     100000       1000
      1000       1000          1
```

Moby currently sorts the ranges by the first id in the range. Therefore
with the subuid file above the uid 0 in the container is mapped to uid
100000 on host and the uids 1-1000 in container are mapped to the uids
1-1000 on the host. The resulting uid_map is:

```
> docker run ubuntu cat /proc/self/uid_map
         0       1000          1
         1     100000       1000
```

The ordering was implemented to work around a limitation in Linux 3.8.
This is fixed since Linux 3.9 as stated on the user namespaces manpage
[1]:

> In the initial implementation (Linux 3.8), this requirement was
> satisfied by a simplistic implementation that imposed the further
> requirement that the values in both field 1 and field 2 of successive
> lines must be in ascending numerical order, which prevented some
> otherwise valid maps from being created.  Linux 3.9 and later fix this
> limitation, allowing any valid set of nonoverlapping maps.

This fix changes the interpretation of subuid and subgid files which do
not have the ids of in the numerical order for each individual user.
This breaks users that rely on the current behaviour.

The desired mapping above - map low user ids in the container to high
user ids on the host and some higher user ids in the container to lower
user on host - can unfortunately not archived with the current
behaviour.

[1] http://man7.org/linux/man-pages/man7/user_namespaces.7.html

Signed-off-by: Jonas Dohse <jonas@dohse.ch>
2019-06-03 15:50:26 +02:00
Salahuddin Khan
763d839261 Add ADD/COPY --chown flag support to Windows
This implements chown support on Windows. Built-in accounts as well
as accounts included in the SAM database of the container are supported.

NOTE: IDPair is now named Identity and IDMappings is now named
IdentityMapping.

The following are valid examples:
ADD --chown=Guest . <some directory>
COPY --chown=Administrator . <some directory>
COPY --chown=Guests . <some directory>
COPY --chown=ContainerUser . <some directory>

On Windows an owner is only granted the permission to read the security
descriptor and read/write the discretionary access control list. This
fix also grants read/write and execute permissions to the owner.

Signed-off-by: Salahuddin Khan <salah@docker.com>
2018-08-13 21:59:11 -07:00
Vincent Demeester
3845728524
Update tests to use gotest.tools 👼
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-06-13 09:04:30 +02:00
Sebastiaan van Stijn
f23c00d870
Various code-cleanup
remove unnescessary import aliases, brackets, and so on.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-05-23 17:50:54 +02:00
Vincent Demeester
a7999aaa53
Skip some tests requires root uid when run as user
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-04-23 10:14:39 +02:00
Vincent Demeester
5d8b88b114
Fix typo in idtools tests
It should check `os.Geteuid` with `uid` instead of `os.Getegid`.
On the container (where the tests run), the uid and gid seems to be
the same, thus this doesn't fail.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-04-23 10:14:07 +02:00
Daniel Nephin
6be0f70983 Automated migration using
gty-migrate-from-testify --ignore-build-tags

Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-03-16 11:03:43 -04:00
Daniel Nephin
4f0d95fa6e Add canonical import comment
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-02-05 16:51:57 -05:00
Sebastiaan van Stijn
6ed1163c98
Remove redundant build-tags
Files that are suffixed with `_linux.go` or `_windows.go` are
already only built on Linux / Windows, so these build-tags
were redundant.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-12-18 17:41:53 +01:00
Kir Kolyshkin
516010e92d Simplify/fix MkdirAll usage
This subtle bug keeps lurking in because error checking for `Mkdir()`
and `MkdirAll()` is slightly different wrt to `EEXIST`/`IsExist`:

 - for `Mkdir()`, `IsExist` error should (usually) be ignored
   (unless you want to make sure directory was not there before)
   as it means "the destination directory was already there"

 - for `MkdirAll()`, `IsExist` error should NEVER be ignored.

Mostly, this commit just removes ignoring the IsExist error, as it
should not be ignored.

Also, there are a couple of cases then IsExist is handled as
"directory already exist" which is wrong. As a result, some code
that never worked as intended is now removed.

NOTE that `idtools.MkdirAndChown()` behaves like `os.MkdirAll()`
rather than `os.Mkdir()` -- so its description is amended accordingly,
and its usage is handled as such (i.e. IsExist error is not ignored).

For more details, a quote from my runc commit 6f82d4b (July 2015):

    TL;DR: check for IsExist(err) after a failed MkdirAll() is both
    redundant and wrong -- so two reasons to remove it.

    Quoting MkdirAll documentation:

    > MkdirAll creates a directory named path, along with any necessary
    > parents, and returns nil, or else returns an error. If path
    > is already a directory, MkdirAll does nothing and returns nil.

    This means two things:

    1. If a directory to be created already exists, no error is
    returned.

    2. If the error returned is IsExist (EEXIST), it means there exists
    a non-directory with the same name as MkdirAll need to use for
    directory. Example: we want to MkdirAll("a/b"), but file "a"
    (or "a/b") already exists, so MkdirAll fails.

    The above is a theory, based on quoted documentation and my UNIX
    knowledge.

    3. In practice, though, current MkdirAll implementation [1] returns
    ENOTDIR in most of cases described in #2, with the exception when
    there is a race between MkdirAll and someone else creating the
    last component of MkdirAll argument as a file. In this very case
    MkdirAll() will indeed return EEXIST.

    Because of #1, IsExist check after MkdirAll is not needed.

    Because of #2 and #3, ignoring IsExist error is just plain wrong,
    as directory we require is not created. It's cleaner to report
    the error now.

    Note this error is all over the tree, I guess due to copy-paste,
    or trying to follow the same usage pattern as for Mkdir(),
    or some not quite correct examples on the Internet.

    [1] https://github.com/golang/go/blob/f9ed2f75/src/os/path.go

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2017-11-27 17:32:12 -08:00
Kir Kolyshkin
2aa13f86f0 idtools.MkdirAs*: error out if dir exists as file
Standard golang's `os.MkdirAll()` function returns "not a directory" error
in case a directory to be created already exists but is not a directory
(e.g. a file). Our own `idtools.MkdirAs*()` functions do not replicate
the behavior.

This is a bug since all `Mkdir()`-like functions are expected to ensure
the required directory exists and is indeed a directory, and return an
error otherwise.

As the code is using our in-house `system.Stat()` call returning a type
which is incompatible with that of golang's `os.Stat()`, I had to amend
the `system` package with `IsDir()`.

A test case is also provided.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2017-11-27 13:25:44 -08:00
Sebastiaan van Stijn
38b3af567f
Remove deprecated MkdirAllAs(), MkdirAs()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-11-21 13:53:54 +01:00
Sebastiaan van Stijn
ce66470f54
Minor refactor in idtools
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-11-21 13:49:58 +01:00
Sebastiaan van Stijn
9aba019b72
Update idtools tests to test non-deprecated functions
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-11-21 13:47:17 +01:00
Yong Tang
113bebe0ee Merge pull request #35059 from cpuguy83/35002_handle_bind_create_errors
idtools don't chown if not needed
2017-10-20 08:39:23 -07:00
Brian Goff
fa9709a3fc idtools don't chown if not needed
In some cases (e.g. NFS), a chown may technically be a no-op but still
return `EPERM`, so only call `chown` when neccessary.

This is particularly problematic for docker users bind-mounting an NFS
share into a container.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2017-10-19 16:06:25 -04:00