Commit Graph

5564 Commits

Author SHA1 Message Date
Kir Kolyshkin 3df6a02f5d libct/nsenter: test: improve newPipe
1. Make sure we close all file descriptors at the end of the test.

2. Make sure we close child fds after the start.

3. Use newPipe for logs as well, for simplicity and uniformity.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-09-02 10:37:02 -07:00
Akihiro Suda bd75bc2dc6 Merge pull request #3176 from kolyshkin/rm-config-error-alt
libct/error.go: rm ConfigError (alt)
2021-09-02 14:34:32 +09:00
Akihiro Suda bde65de7b1 Merge pull request #3192 from kinvolk/rata/cgo-warnings
CI: Mark CGO warnings as errors
2021-09-02 14:13:56 +09:00
Akihiro Suda 5fb9b2a006 Merge pull request #3185 from kolyshkin/go117-build-tags
Add go:build tags
2021-09-02 13:35:33 +09:00
Rodrigo Campos 347c371bf4 CI: Mark CGO warnings as errors
Treat warning as errors only in the CI. We can enforce it in the source
code (like setting CFLAGS in libcontainer/nsenter/nsenter.go), but that
can force other downstream to patch the code if thei C compiler produces
warnings. For that reason, we do it only on the CI.

Todays CGO warnings are quite hidden in the CI (only shown for the
compilation step, that is collapsed) and CI is green anyways. With this
patch, CI fails if a warning is introduced.

Signed-off-by: Rodrigo Campos <rodrigo@kinvolk.io>
2021-08-31 18:08:29 +02:00
Sebastiaan van Stijn b144f3d382 Merge pull request #2825 from lifubang/nodelete
proposal: add --keep to runc run
2021-08-31 10:04:58 +02:00
Akihiro Suda 0d193edbee Merge pull request #3190 from presztak/nsexec_bail_message_typo_fix
Fix typo in bail message
2021-08-31 14:29:02 +09:00
Kir Kolyshkin d8da00355e *: add go-1.17+ go:build tags
Go 1.17 introduce this new (and better) way to specify build tags.
For more info, see https://golang.org/design/draft-gobuild.

As a way to seamlessly switch from old to new build tags, gofmt (and
gopls) from go 1.17 adds the new tags along with the old ones.

Later, when go < 1.17 is no longer supported, the old build tags
can be removed.

Now, as I started to use latest gopls (v0.7.1), it adds these tags
while I edit. Rather than to randomly add new build tags, I guess
it is better to do it once for all files.

Mind that previous commits removed some tags that were useless,
so this one only touches packages that can at least be built
on non-linux.

Brought to you by

        go1.17 fmt ./...

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-30 20:58:22 -07:00
Kir Kolyshkin 1b17ec95af libct/cg: rm "unsupported.go" files
These are not needed as these packages (libcontainer/cgroups,
libcontainer/cgroups/fs, and libcontainer/cgroups/systemd) can
not be built under non-linux anyway (for various reasons).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-30 20:56:35 -07:00
Kir Kolyshkin dbb9fc03ae libct/*: remove linux build tag from some pkgs
Only some libcontainer packages can be built on non-linux platforms
(not that it make sense, but at least go build succeeds). Let's call
these "good" packages.

For all other packages (i.e. ones that fail to build with GOOS other
than linux), it does not make sense to have linux build tag (as they
are broken already, and thus are not and can not be used on anything
other than Linux).

Remove linux build tag for all non-"good" packages.

This was mostly done by the following script, with just a few manual
fixes on top.

function list_good_pkgs() {
	for pkg in $(find . -type d -print); do
		GOOS=freebsd go build $pkg 2>/dev/null \
		&& GOOS=solaris go build $pkg 2>/dev/null \
		&& echo $pkg
	done | sed -e 's|^./||' | tr '\n' '|' | sed -e 's/|$//'
}

function remove_tag() {
	sed -i -e '\|^// +build linux$|d' $1
	go fmt $1
}

SKIP="^("$(list_good_pkgs)")"
for f in $(git ls-files . | grep .go$); do
	if echo $f | grep -qE "$SKIP"; then
		echo skip $f
		continue
	fi
	echo proc $f
	remove_tag $f
done

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-30 20:52:07 -07:00
Kir Kolyshkin c5b0be78e8 Rm build tags from main pkg
This was added by commit 5aa82c950 back in the day when we thought
runc is going to be cross-platform. It's very clear now it's Linux-only
package.

While at it, further clarify it in README that we're Linux only.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-30 20:15:01 -07:00
Kir Kolyshkin 9ff64c3d97 *: rm redundant linux build tag
For files that end with _linux.go or _linux_test.go, there is no need to
specify linux build tag, as it is assumed from the file name.

In addition, rename libcontainer/notify_linux_v2.go -> libcontainer/notify_v2_linux.go
for the file name to make sense.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-30 20:15:00 -07:00
Kir Kolyshkin 3c7db3827c Merge pull request #2883 from flouthoc/master
Add support for rdma cgroup introduced in Linux Kernel 4.11
2021-08-30 20:02:04 -07:00
Kir Kolyshkin 62ec6dc973 Merge pull request #2920 from marquiz/devel/rdt
libcontainer/intelrdt: support ClosID parameter
2021-08-30 19:36:03 -07:00
Piotr Resztak 895e0a5cb3 nsenter: fix typo in bail message
Signed-off-by: Piotr Resztak <piotr.resztak@gmail.com>
2021-08-30 23:24:31 +02:00
Akihiro Suda 11d141bed2 Merge pull request #3090 from kolyshkin/cfq_quota_period
libct/cg/v1: work around CPU quota period set failure
2021-08-31 04:20:58 +09:00
Kir Kolyshkin 639445789d tests/int: add a "update cpu period with pod limit set" test
Add a test case for an issue fixed by the previous commit.

Unfortunately, this is somewhat complicated as there's no easy way to
create a transient unit, so a binary, sd-helper, had to be added. On top
of that, an ability to create a parent/pod cgroup is added to
helpers.bash, which might be useful for future integration tests.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-26 13:11:22 -07:00
Kir Kolyshkin 1b2adcfe56 libct/cg/v1: workaround CPU quota period set failure
As reported in issue 3084, sometimes setting CPU quota period fails
when a new period is lower and a parent cgroup has CPU quota limit set.

This happens as in cgroup v1 the quota and the period can not be set
together (this is fixed in v2), and since the period is being set first,
new_limit = old_quota/new_period may be higher than the parent cgroup
limit.

The fix is to retry setting the period after the quota, to cover all
possible scenarios.

Add a test case to cover a regression caused by an earlier version of
this patch (ignoring a failure of setting invalid period when quota is
not set).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-26 13:11:22 -07:00
Mrunal Patel 654f331976 Merge pull request #3175 from kolyshkin/tests-int-cleanups
tests/int/helpers: cleanup, enable shellcheck
2021-08-25 16:18:37 -07:00
Sebastiaan van Stijn 8b59b768a9 Merge pull request #3182 from cyphar/revert-3159
Revert "libct/devices: change devices.Type to be a string"
2021-08-25 10:55:04 +02:00
Qiang Huang b4b797200e Merge pull request #3136 from kolyshkin/cg-d-c
libct/cg: rm dead code to improve clarity
2021-08-25 14:46:27 +08:00
Aleksa Sarai 09b80811f6 Revert "libct/devices: change devices.Type to be a string"
This reverts commit 814f3ae1d9. This
changed the on-disk state which breaks runc when it has to operate on
containers started with an older runc version. Working around this is
far more complicated than just reverting it.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2021-08-25 14:11:32 +10:00
Sebastiaan van Stijn f67f1efc70 Merge pull request #3110 from kolyshkin/parse-devices
libct/cg/devices: stop using regex
2021-08-24 08:49:19 +02:00
Kir Kolyshkin 538ba846dd libct/error.go: rm ConfigError
ConfigError was added by commit e918d02139, while removing runc own
error system, to preserve a way for a libcontainer user to distinguish
between a configuration error and something else.

The way ConfigError is implemented requires a different type of check
(compared to all other errors defined by error.go). An attempt was made
to rectify this, but the resulting code became even more complicated.

As no one is using this functionality (of differentiating a "bad config"
type of error from other errors), let's just drop the ConfigError type.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-23 18:56:08 -07:00
Kir Kolyshkin 6145628fff configs/validate: audit all returned errors
All the errors returned from Validate should tell about a configuration
error. Some were lacking a context, so add it.

While at it, fix abusing fmt.Errorf and logrus.Warnf where the argument
do not contain %-style formatting.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-23 18:54:47 -07:00
Kir Kolyshkin bbcf96f91f libct/cg/devices: stop using regex
Looking into data generated by setting

	GODEBUG="inittrace=1"

I have noticed this line:

init github.com/opencontainers/runc/libcontainer/cgroups/devices @1.2 ms, 0.020 ms clock, 10512 bytes, 133 allocs

This is the leader for both bytes and allocs among the packages from
this repo, and all of it is caused by a single regex:

> var devicesListRegexp = regexp.MustCompile(`^([abc])\s+(\d+|\*):(\d+|\*)\s+([rwm]+)$`)

It seems that the same parsing can be done without relying on
a regular expression, no decrease in readability, and 2x faster
(according to the benchmark added), and also makes runc start
slightly faster and leaner.

Before:
    BenchmarkParseLine-4   	  176240	      6768 ns/op	    6576 B/op	      64 allocs/op

After:
    BenchmarkParseLine-4   	  322441	      3535 ns/op	    5520 B/op	      53 allocs/op

[v2: single split with SplitFunc; fix a typo in error message]
[v3: rebase after 3159 merge; re-ran benchmarks (results are similar)]

Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-23 17:04:09 -07:00
Kir Kolyshkin 34df203d13 Merge pull request #3159 from thaJeztah/norunes
libct/devices: change devices.Type to be a string
2021-08-23 16:58:34 -07:00
Kir Kolyshkin fb629db693 tests/int/helpers: fix shellcheck warnings
... and add the file to be checked by shellcheck.

The warnings fixed are:

In tests/integration/helpers.bash line 10:
INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")")
                                           ^----------^ SC2128: Expanding an array without an index only gives the first element.

In tests/integration/helpers.bash line 22:
TESTDATA="${INTEGRATION_ROOT}/testdata"
^------^ SC2034: TESTDATA appears unused. Verify use (or export if used externally).

In tests/integration/helpers.bash line 42:
	echo "runc $@ (status=$status):" >&2
                   ^-- SC2145: Argument mixes string and array. Use * or separate argument.
                              ^-----^ SC2154: status is referenced but not assigned.

In tests/integration/helpers.bash line 43:
	echo "$output" >&2
              ^-----^ SC2154: output is referenced but not assigned.

In tests/integration/helpers.bash line 77:
			| .linux.gidMappings += [{"hostID": '"$(($ROOTLESS_GIDMAP_START + 10))"', "containerID": 1, "size": 20}]
                                                                 ^--------------------^ SC2004: $/${} is unnecessary on arithmetic variables.

In tests/integration/helpers.bash line 78:
			| .linux.gidMappings += [{"hostID": '"$(($ROOTLESS_GIDMAP_START + 100))"', "containerID": 1000, "size": '"$(($ROOTLESS_GIDMAP_LENGTH - 1000))"'}]'
                                                                 ^--------------------^ SC2004: $/${} is unnecessary on arithmetic variables.
                                                                                                                                     ^---------------------^ SC2004: $/${} is unnecessary on arithmetic variables.

In tests/integration/helpers.bash line 125:
			base_path=$(gawk '$(NF-2) == "cgroup" && $NF ~ /\<'${g}'\>/ { print $5; exit }' /proc/self/mountinfo)
                                                                           ^--^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
			base_path=$(gawk '$(NF-2) == "cgroup" && $NF ~ /\<'"${g}"'\>/ { print $5; exit }' /proc/self/mountinfo)

In tests/integration/helpers.bash line 127:
			eval CGROUP_${g^^}_BASE_PATH="${base_path}"
                                    ^----^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
			eval CGROUP_"${g^^}"_BASE_PATH="${base_path}"

In tests/integration/helpers.bash line 229:
	if [ "x$CGROUP_UNIFIED" = "xyes" ]; then
             ^----------------^ SC2268: Avoid x-prefix in comparisons as it no longer serves a purpose.

Did you mean:
	if [ "$CGROUP_UNIFIED" = "yes" ]; then

In tests/integration/helpers.bash line 234:
		eval cgroup=\$${var}${REL_CGROUPS_PATH}
                              ^----^ SC2086: Double quote to prevent globbing and word splitting.
                                    ^-----------------^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
		eval cgroup=\$"${var}""${REL_CGROUPS_PATH}"

In tests/integration/helpers.bash line 236:
	cat $cgroup/$source
            ^-----^ SC2086: Double quote to prevent globbing and word splitting.
                    ^-----^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	cat "$cgroup"/"$source"

In tests/integration/helpers.bash line 242:
	current="$(get_cgroup_value $1)"
                                    ^-- SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	current="$(get_cgroup_value "$1")"

In tests/integration/helpers.bash line 245:
	echo "current" $current "!?" "$expected"
                       ^------^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	echo "current" "$current" "!?" "$expected"

In tests/integration/helpers.bash line 257:
	[ $(id -u) != "0" ] && user="--user"
          ^------^ SC2046: Quote this to prevent word splitting.

In tests/integration/helpers.bash line 259:
	current=$(systemctl show $user --property $source $SD_UNIT_NAME | awk -F= '{print $2}')
                                                  ^-----^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	current=$(systemctl show $user --property "$source" $SD_UNIT_NAME | awk -F= '{print $2}')

In tests/integration/helpers.bash line 261:
	[ "$current" = "$expected" ] || [ -n "$expected2" -a "$current" = "$expected2" ]
                                                          ^-- SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.

In tests/integration/helpers.bash line 309:
	check_cgroup_value "cpu.weight" $weight
                                        ^-----^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	check_cgroup_value "cpu.weight" "$weight"

In tests/integration/helpers.bash line 310:
	check_systemd_value "CPUWeight" $weight
                                        ^-----^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	check_systemd_value "CPUWeight" "$weight"

In tests/integration/helpers.bash line 383:
			if [ $CGROUP_UNIFIED = "no" -a ! -e "${CGROUP_MEMORY_BASE_PATH}/memory.memsw.limit_in_bytes" ]; then
                                                    ^-- SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.

In tests/integration/helpers.bash line 412:
			local cpu_count=$(grep -c '^processor' /proc/cpuinfo)
                              ^-------^ SC2155: Declare and assign separately to avoid masking return values.

In tests/integration/helpers.bash line 450:
		sleep $delay
                      ^----^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
		sleep "$delay"

In tests/integration/helpers.bash line 453:
	echo "Command \"$@\" failed $attempts times. Output: $output"
                        ^-- SC2145: Argument mixes string and array. Use * or separate argument.

In tests/integration/helpers.bash line 471:
	runc state $1
                   ^-- SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	runc state "$1"

In tests/integration/helpers.bash line 472:
	if [ $2 == "checkpointed" ]; then
             ^-- SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	if [ "$2" == "checkpointed" ]; then

In tests/integration/helpers.bash line 484:
	mkdir $dir
              ^--^ SC2086: Double quote to prevent globbing and word splitting.

Did you mean:
	mkdir "$dir"

In tests/integration/helpers.bash line 497:
		kill -9 $(cat "$dir/pid")
                        ^---------------^ SC2046: Quote this to prevent word splitting.

In tests/integration/helpers.bash line 508:
	export ROOT=$(mktemp -d "$BATS_RUN_TMPDIR/runc.XXXXXX")
               ^--^ SC2155: Declare and assign separately to avoid masking return values.

In tests/integration/helpers.bash line 512:
	cd "$ROOT/bundle"
        ^---------------^ SC2164: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

Did you mean:
	cd "$ROOT/bundle" || exit

In tests/integration/helpers.bash line 535:
	cd "$INTEGRATION_ROOT"
        ^--------------------^ SC2164: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

Did you mean:
	cd "$INTEGRATION_ROOT" || exit

For more information:
  https://www.shellcheck.net/wiki/SC2145 -- Argument mixes string and array. ...
  https://www.shellcheck.net/wiki/SC2034 -- TESTDATA appears unused. Verify u...
  https://www.shellcheck.net/wiki/SC2046 -- Quote this to prevent word splitt...

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-23 15:53:26 -07:00
Kir Kolyshkin f65276db35 tests/int/helpers: rm $bundle handling
It is not used since PR 2757, as all tests are run with cd to bundle
directory.

runc_spec argument count checking is removed since otherwise shellcheck
complains:

> SC2120: runc_spec references arguments, but none are ever passed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-23 15:49:45 -07:00
flouthoc b3d14488b5 Add support for rdma cgroup introduced in Linux Kernel 4.11
Signed-off-by: Aditya Rajan <flouthoc.git@gmail.com>
2021-08-23 12:25:33 +05:30
Markus Lehtonen 9393700003 libcontainer/intelrdt: update code comments
Use the term "clos group" instead of "container_id group" as the group
that a container belongs to is not necessarily tied to its container id.

Signed-off-by: Markus Lehtonen <markus.lehtonen@intel.com>
2021-08-20 07:47:07 +03:00
Kir Kolyshkin 3023e6c625 Merge pull request #3166 from kolyshkin/fix-freeze-before-set-alt-2
libct/cg/sd/v1: fix freezeBeforeSet (alt 2)
2021-08-19 11:40:06 -07:00
Sebastiaan van Stijn 926a9a088f Merge pull request #3171 from kolyshkin/try-bullseye
Dockerfile: switch to bullseye
2021-08-19 18:16:11 +02:00
Sebastiaan van Stijn 8e6871a3b1 Merge pull request #3116 from kolyshkin/ci-add-criu-dev
ci/gha: add latest criu-dev test run
2021-08-19 09:46:52 +02:00
Kir Kolyshkin 24d318b8bb Dockerfile: switch to bullseye
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-18 15:59:22 -07:00
Mrunal Patel 9835e9c6b2 Merge pull request #3021 from kolyshkin/go-1.17beta1
ci: add go1.17
2021-08-18 13:32:05 -07:00
Kir Kolyshkin 9a095e44db libct/cg/sd/v1: add SkipFreezeOnSet knob
This is helpful to kubernetes in cases it knows for sure that the freeze
is not required (since it created the systemd unit with no device
restrictions).

As the code is trivial, no tests are required.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-18 12:43:55 -07:00
Kir Kolyshkin fec49f2a6c libct/cg/sd/v1: add freezeBeforeSet unit test
Add a test for freezeBeforeSet, checking various scenarios including
those that were failing before the fix in the previous commit.

[v2: add more cases, add a check before creating a unit.]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-18 12:43:55 -07:00
Odin Ugedal 41043673b7 libct/cg/sd/v1: Fix unnecessary freeze/thaw
This fixes the behavior intended to avoid freezing containers/control
groups without it being necessary. This is important for end users of
libcontainer who rely on the behavior of no freeze.

The previous implementation would always get error trying to get
DevicePolicy from the Unit via dbus, since the Unit interface doesn't
contain DevicePolicy.

Signed-off-by: Odin Ugedal <odin@uged.al>
2021-08-18 12:43:36 -07:00
Akihiro Suda 4d26c4a0a1 Merge pull request #3144 from kolyshkin/codespell
Fix codespell warnings, add codespell to ci
2021-08-18 11:42:36 +09:00
Akihiro Suda ba7a87730d Merge pull request #3168 from kolyshkin/fix-cc-warn
libct/nsenter: fix unused-result warning
2021-08-18 11:37:59 +09:00
Kir Kolyshkin a587180136 ci: add go1.17
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-17 17:49:44 -07:00
Kir Kolyshkin 75761bccf7 Fix codespell warnings, add codespell to ci
The two exceptions I had to add to codespellrc are:
 - CLOS (used by intelrtd);
 - creat (syscall name used in tests/integration/testdata/seccomp_*.json).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-17 16:12:35 -07:00
Kir Kolyshkin db8330c9e5 libct/nsenter: fix unused-result warning
Commit 2bab4a5 resulted in a warning from gcc:

	nsexec.c: In function ‘write_log’:
	nsexec.c:171:2: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result]
	  171 |  write(logfd, json, ret);
	      |  ^~~~~~~~~~~~~~~~~~~~~~~

As there's nothing we can or want to do in case write fails,
let's just tell the compiler we're not going to use it.

Fixes: 2bab4a5
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2021-08-17 15:19:31 -07:00
Sebastiaan van Stijn e53e97a875 Merge pull request #3164 from kinvolk/rata/make-no-buildtags
CI: Validate compilation without buildtags
2021-08-17 23:04:50 +02:00
Akihiro Suda dff416868e Merge pull request #3160 from kailun-qin/fix-check
libct/nsenter: no need to check size_t less than 0
2021-08-18 02:34:33 +09:00
Sebastiaan van Stijn ca4433f613 Merge pull request #3153 from kolyshkin/cirrus-robust
.cirrus.yml: simplify for centos, retry yum
2021-08-17 15:34:39 +02:00
Kir Kolyshkin 10f179c8c2 Merge pull request #3162 from kailun-qin/null-on-error
libct/nsenter: nullify pointer on asprintf error
2021-08-16 16:18:52 -07:00
Rodrigo Campos 844d6774e0 CI: Validate compilation without buildtags
Today we support the seccomp build tag only that is used by default.
However, we are not testing that compiling without any build tag works.

I found the CI didn't catch this when working on #2682, that the CI was
green but compilation without build tags was broken.

We test compilation without build tags only, compilation with the only
build tag supported is done extensively in other actions.

Signed-off-by: Rodrigo Campos <rodrigo@kinvolk.io>
2021-08-16 17:44:54 +02:00
Akihiro Suda 55e93b89f1 Merge pull request #3150 from kolyshkin/maintainers
MAINTAINERS: add Sebastiaan van Stijn
2021-08-16 22:51:53 +09:00