Commit graph

101 commits

Author SHA1 Message Date
Paweł Gronowski
c35376c455
volume/local: Don't unmount, restore mounted status
On startup all local volumes were unmounted as a cleanup mechanism for
the non-clean exit of the last engine process.

This caused live-restored volumes that used special volume opt mount
flags to be broken. While the refcount was restored, the _data directory
was just unmounted, so all new containers mounting this volume would
just have the access to the empty _data directory instead of the real
volume.

With this patch, the mountpoint isn't unmounted. Instead, if the volume
is already mounted, just mark it as mounted, so the next time Mount is
called only the ref count is incremented, but no second attempt to mount
it is performed.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 2689484402)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-08-29 19:59:05 +02:00
Paweł Gronowski
3897724f4a
volume/local: Fix debug log typo
Active count is incremented, but message claimed the opposite.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 7f965d55c7)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-08-18 13:12:57 +02:00
Brian Goff
c24c37bd8a
Restore active mount counts on live-restore
When live-restoring a container the volume driver needs be notified that
there is an active mount for the volume.
Before this change the count is zero until the container stops and the
uint64 overflows pretty much making it so the volume can never be
removed until another daemon restart.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 647c2a6cdd)
Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-28 09:45:07 +02:00
Sebastiaan van Stijn
01fd23b625
Fix volume CreatedAt being altered on initialization
The CreatedAt date was determined from the volume's `_data`
directory (`/var/lib/docker/volumes/<volumename>/_data`).
However, when initializing a volume, this directory is updated,
causing the date to change.

Instead of using the `_data` directory, use its parent directory,
which is not updated afterwards, and should reflect the time that
the volume was created.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-01-03 16:57:04 +01:00
Sebastiaan van Stijn
64adea1ce1
volume: use strings.Cut() and minor refactor
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-12-21 11:09:00 +01:00
Sebastiaan van Stijn
188724a597
volume: fix empty-lines (revive)
volume/mounts/parser_test.go:42:39: empty-lines: extra empty line at the end of a block (revive)
    volume/mounts/windows_parser.go:129:24: empty-lines: extra empty line at the end of a block (revive)
    volume/local/local_test.go:16:35: empty-lines: extra empty line at the end of a block (revive)
    volume/local/local_unix.go:145:3: early-return: if c {...} else {... return } can be simplified to if !c { ... return } ... (revive)
    volume/service/service_test.go:18:38: 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:50 +02:00
Sebastiaan van Stijn
cd58d11b2a
volume/local.New(): extract loading options to a function
Note that Windows does not support options, so strictly doesn't need
to have this code, but keeping it in case we're adding support.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:29 +02:00
Sebastiaan van Stijn
7e907e29a3
volume/local.New() always unmount existing mounts
Unmounting does not depend on wether or not loading options failed.

This code-path seemed to be used as a "hack" to prevent hitting the
unmount on Windows (which does not support unmounting).

Moving it outside of the "if" to make more clear that it's independent
of loading the options.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:27 +02:00
Sebastiaan van Stijn
c0f0cf6c19
volume/local: extract saving options to a separate method
Differentiate between Windows and Linux, as Windows doesn't support
options, so there's no need to save options to disk,

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:25 +02:00
Sebastiaan van Stijn
d3930330a7
volume/local: store both volume's "data" and "root" path
Instead of evaluating these paths each time (appending `_data`, or using
`filepath.Dir()` to find the root path from the `_data_` path).

This also removes the `root.DataPath()` utility, which is now no longer needed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:24 +02:00
Sebastiaan van Stijn
e106e3f5c6
volume/local: make "validateOpts()" a method on Root
This way we can validate if Root supports quotaCtl, allowing us to
fail early, before creating any of the directories.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:22 +02:00
Sebastiaan van Stijn
29c6224fe9
volume/local.Create(): validate early
This moves validation of options to the start of the Create function
to prevent hitting the filesystem and having to remove the volume
from disk.

Also addressing some minor nits w.r.t. errors.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:21 +02:00
Sebastiaan van Stijn
a77b90c35e
volume/local: make setOpts() a method of localVolume
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:19 +02:00
Sebastiaan van Stijn
b56fc2d0f8
volume/local.New(): don't register volume before we're done
Loading options may fail, in which case we don't have to add
the volume to the list.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:17 +02:00
Sebastiaan van Stijn
eecf7a0840
volume/local: localVolume.mount() move errors.Wrap()
While the current code is correct (as errors.Wrap() returns nil if
err is nil), relying on this behavior has caused some confusion in
the past, resulting in regressions.

This patch makes the error-handling code slightly more idiomatic and
defensive against such regressions.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:16 +02:00
Sebastiaan van Stijn
c1671abf14
volume/local: add test for validation
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-06-03 00:34:08 +02:00
Sebastiaan van Stijn
32f7551e61
Merge pull request #43597 from shoeffner/43596-mask-cifs-passwords
volume: mask password in cifs mount error messages
2022-05-19 22:52:26 +02:00
Sebastian Höffner
9a7298a3e6
volume: mask password in cifs mount error messages
In managed environment (such as Nomad clusters), users are not always
supposed to see credentials used to mount volumes.
However, if errors occur (most commonly, misspelled mount paths), the
error messages will output the full mount command -- which might contain
a username and a password in the case of CIFS mounts.

This PR detects password=... when error messages are wrapped and masks
them with ********.

Closes https://github.com/fsouza/go-dockerclient/issues/905.
Closes https://github.com/hashicorp/nomad/issues/12296.
Closes https://github.com/moby/moby/issues/43596.

Signed-off-by: Sebastian Höffner <sebastian.hoeffner@mevis.fraunhofer.de>
2022-05-14 02:45:06 +02:00
Sebastiaan van Stijn
73f0b01da1
volume/local.New(): remove redundant filepath.Base()
FileInfo.Name() returns the base name, so no need to remove
path information.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-05-13 00:38:38 +02:00
Sebastiaan van Stijn
a4bfd9788f
volume/local.New(): remove some intermediate variables
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-05-13 00:38:22 +02:00
Sebastiaan van Stijn
74be0fed6f
volume/local: remove redundant Root.scopedPath(), Root.scope
Now that there's no differentiation between Linux and Windows
for this check, we can remove the two implementations and move
the code inline as it's only used in a single location and moving
it inline makes it more transparent on what's being checked.

As part of this change, the now unused "scope" field is also removed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-05-13 00:34:08 +02:00
Sebastiaan van Stijn
0abd7ba229
volume/local: remove hack for downgrading docker 1.7 to 1.6
This was added in bd9814f0db to support downgrading
docker 1.7 to 1.6.

The related migration code was removed in 0023abbad3
(Docker 18.05), which was also the last consumer of VolumeDataPathName outside
of the package, so that const can be un-exported.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-05-13 00:33:50 +02: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
Brian Goff
7f5e39bd4f
Use real root with 0701 perms
Various dirs in /var/lib/docker contain data that needs to be mounted
into a container. For this reason, these dirs are set to be owned by the
remapped root user, otherwise there can be permissions issues.
However, this uneccessarily exposes these dirs to an unprivileged user
on the host.

Instead, set the ownership of these dirs to the real root (or rather the
UID/GID of dockerd) with 0701 permissions, which allows the remapped
root to enter the directories but not read/write to them.
The remapped root needs to enter these dirs so the container's rootfs
can be configured... e.g. to mount /etc/resolve.conf.

This prevents an unprivileged user from having read/write access to
these dirs on the host.
The flip side of this is now any user can enter these directories.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit e908cc3901)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-02 13:01:25 +01:00
Sebastiaan van Stijn
4f36640553
volumes/local: gofmt
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-01-14 14:54:37 +01:00
Sebastiaan van Stijn
32d506b394
vendor: moby/sys mountinfo/v0.4.0
full diff: https://github.com/moby/sys/compare/mountinfo/v0.1.3...mountinfo/v0.4.0

> Note that this dependency uses submodules, providing "github.com/moby/sys/mount"
> and "github.com/moby/sys/mountinfo". Our vendoring tool (vndr) currently doesn't
> support submodules, so we vendor the top-level moby/sys repository (which contains
> both) and pick the most recent tag, which could be either `mountinfo/vXXX` or
> `mount/vXXX`.

github.com/moby/sys/mountinfo v0.4.0
--------------------------------------------------------------------------------

Breaking changes:

- `PidMountInfo` is now deprecated and will be removed before v1.0; users should switch to `GetMountsFromReader`

Fixes and improvements:

- run filter after all fields are parsed
- correct handling errors from bufio.Scan
- documentation formatting fixes

github.com/moby/sys/mountinfo v0.3.1
--------------------------------------------------------------------------------

- mount: use MNT_* flags from golang.org/x/sys/unix on freebsd
- various godoc and CI fixes
- mountinfo: make GetMountinfoFromReader Linux-specific
- Add support for OpenBSD in addition to FreeBSD
- mountinfo: use idiomatic naming for fields

github.com/moby/sys/mountinfo v0.2.0
--------------------------------------------------------------------------------

Bug fixes:

- Fix path unescaping for paths with double quotes

Improvements:

- Mounted: speed up by adding fast paths using openat2 (Linux-only) and stat
- Mounted: relax path requirements (allow relative, non-cleaned paths, symlinks)
- Unescape fstype and source fields
- Documentation improvements

Testing/CI:

- Unit tests: exclude darwin
- CI: run tests under Fedora 32 to test openat2
- TestGetMounts: fix for Ubuntu build system
- Makefile: fix ignoring test failures
- CI: add cross build

github.com/moby/sys/mount v0.1.1
--------------------------------------------------------------------------------

https://github.com/moby/sys/releases/tag/mount%2Fv0.1.1

Improvements:

- RecursiveUnmount: add a fast path (#26)
- Unmount: improve doc
- fix CI linter warning on Windows

Testing/CI:

- Unit tests: exclude darwin
- Makefile: fix ignoring test failures
- CI: add cross build

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-29 23:02:28 +01:00
Sebastiaan van Stijn
182795cff6
Do not call mount.RecursiveUnmount() on Windows
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-29 23:00:16 +01:00
Timo Rothenpieler
8c31e4536a volume/local: add tests for size quota
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
2020-10-05 13:28:25 +00:00
Timo Rothenpieler
6d593fe6cc volume/local: decouple presence of options from mounting
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
2020-10-05 13:28:25 +00:00
Kir Kolyshkin
39048cf656 Really switch to moby/sys/mount*
Switch to moby/sys/mount and mountinfo. Keep the pkg/mount for potential
outside users.

This commit was generated by the following bash script:

```
set -e -u -o pipefail

for file in $(git grep -l 'docker/docker/pkg/mount"' | grep -v ^pkg/mount); do
	sed -i -e 's#/docker/docker/pkg/mount"#/moby/sys/mount"#' \
		-e 's#mount\.\(GetMounts\|Mounted\|Info\|[A-Za-z]*Filter\)#mountinfo.\1#g' \
		$file
	goimports -w $file
done
```

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2020-03-20 09:46:25 -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
ad95c6315d
volume/local fix file permissions
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-09-18 12:57:09 +02:00
Sebastiaan van Stijn
c2532d56b0
volume Create: fix incorrect file permissions (staticcheck)
```
14:01:54 volume/local/local.go:175:80: SA9002: file mode '600' evaluates to 01130; did you mean '0600'? (staticcheck)
14:01:54 		if err = ioutil.WriteFile(filepath.Join(filepath.Dir(path), "opts.json"), b, 600); err != nil {
```

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-09-18 12:55:47 +02:00
Chow
75a59c6588 Enable DNS Lookups for CIFS Volumes
This comes from an old suggestion (https://github.com/docker/cli/issues/706#issuecomment-371157691) on an issue we were having and has since popped up again.  For NFS volumes, Docker will do an IP lookup on the volume name.  This is not done for CIFS volumes, which forces you to add the volume via IP address instead.  This change will enable the IP lookup also for CIFS volumes.

Signed-off-by: Shu-Wai Chow <shu-wai.chow@seattlechildrens.org>
2019-05-21 14:34:53 -07:00
Sebastiaan van Stijn
0d6dd91e13
Move validateOpts() to local_unix.go as it is not used on Windows
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-12-23 00:53:23 +01:00
Sebastiaan van Stijn
11b88be247
Remove validationError type, and use errdefs.InvalidParameter
Using `errors.Errorf()` passes the error with the stack trace for
debugging purposes.

Also using `errdefs.InvalidParameter` for Windows, so that the API
will return a 4xx status, instead of a 5xx, and added tests for
both validations.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-12-22 16:04:52 +01:00
Sebastiaan van Stijn
342f7a357a
Use a map[string]struct{} for validOpts
For consistency with `mandatoryOpts`, and because it is a
tiny-tiny bit more efficient.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-12-22 16:04:45 +01:00
Vincent Demeester
d5b271c155
add check for local volume option
Description:
When using local volume option such as size=10G, type=tmpfs, if we provide wrong options, we could create volume successfully.
But when we are ready to use it, it will fail to start container by failing to mount the local volume(invalid option).

We should check the options at when we create it.

Signed-off-by: Wentao Zhang <zhangwentao234@huawei.com>
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-12-22 16:02:50 +01:00
Kir Kolyshkin
6533136961 pkg/mount: wrap mount/umount errors
The errors returned from Mount and Unmount functions are raw
syscall.Errno errors (like EPERM or EINVAL), which provides
no context about what has happened and why.

Similar to os.PathError type, introduce mount.Error type
with some context. The error messages will now look like this:

> mount /tmp/mount-tests/source:/tmp/mount-tests/target, flags: 0x1001: operation not permitted

or

> mount tmpfs:/tmp/mount-test-source-516297835: operation not permitted

Before this patch, it was just

> operation not permitted

[v2: add Cause()]
[v3: rename MountError to Error, document Cause()]
[v4: fixes; audited all users]
[v5: make Error type private; changes after @cpuguy83 reviews]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-12-10 20:07:02 -08: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
Jonathan Choy
e4186ba708 Amended per cleanup request.
Signed-off-by: Jonathan Choy <oni@tetsujinlabs.com>
2018-05-18 11:09:35 -04:00
Jonathan Choy
1845cd0d86 Rewrote data-root escape error message
Signed-off-by: Jonathan Choy <jonathan.j.choy@gmail.com>
2018-05-17 21:52:03 -04:00
Brian Goff
d15734ec3c Fix issues with running volume tests as non-root.
- Volume store created dir with wrong permissions
- Local volume driver hardcoded uid/gid 0

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2018-04-24 10:26:10 -04: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
Kir Kolyshkin
ce468f0ad0 volume/local/TestCreateWithOpts(): use mount filter
This is not for the sake of test to run faster of course;
this is to simplify the code as well as have some more
testing for mount.SingleEntryFilter().

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-04-19 14:50:03 -07:00
Kir Kolyshkin
ac39a95ea6 volume/local: call umount unconditionally
There is no need to parse mount table and iterate through the list of
mounts, and then call Unmount() which again parses the mount table and
iterates through the list of mounts.

It is totally OK to call Unmount() unconditionally.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-04-19 14:49:54 -07:00
Kir Kolyshkin
bb934c6aca pkg/mount: implement/use filter for mountinfo parsing
Functions `GetMounts()` and `parseMountTable()` return all the entries
as read and parsed from /proc/self/mountinfo. In many cases the caller
is only interested only one or a few entries, not all of them.

One good example is `Mounted()` function, which looks for a specific
entry only. Another example is `RecursiveUnmount()` which is only
interested in mount under a specific path.

This commit adds `filter` argument to `GetMounts()` to implement
two things:
 1. filter out entries a caller is not interested in
 2. stop processing if a caller is found what it wanted

`nil` can be passed to get a backward-compatible behavior, i.e. return
all the entries.

A few filters are implemented:
 - `PrefixFilter`: filters out all entries not under `prefix`
 - `SingleEntryFilter`: looks for a specific entry

Finally, `Mounted()` is modified to use `SingleEntryFilter()`, and
`RecursiveUnmount()` is using `PrefixFilter()`.

Unit tests are added to check filters are working.

[v2: ditch NoFilter, use nil]
[v3: ditch GetMountsFiltered()]
[v4: add unit test for filters]
[v5: switch to gotestyourself]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2018-04-19 14:48:09 -07:00