Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

io.etcd.jetcd.launcher.EtcdContainer -- Error deleting directory when using jetcd-tests on unit-testing. #1310

Closed
matheuscirillo opened this issue Jan 31, 2024 · 25 comments

Comments

@matheuscirillo
Copy link

matheuscirillo commented Jan 31, 2024

Versions

  • etcd: 3.5.10
  • jetcd: 0.7.7
  • java: 21

Describe the bug
At the end of unit tests when using jetcd-tests, an error io.etcd.jetcd.launcher.EtcdContainer -- Error deleting directory is thrown. It doesn't prevent the test to run successfully, but I wonder if it's something wrong I'm doing.

To Reproduce

import io.etcd.jetcd.ByteSequence;
import io.etcd.jetcd.Client;
import io.etcd.jetcd.KV;
import io.etcd.jetcd.kv.GetResponse;
import io.etcd.jetcd.kv.PutResponse;
import io.etcd.jetcd.test.EtcdClusterExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class SimpleTest {

    @RegisterExtension
    public static final EtcdClusterExtension cluster = EtcdClusterExtension.builder()
            .withNodes(1)
            .build();

    Client client = Client.builder().endpoints(cluster.clientEndpoints()).build();

    @Test
    public void testing() throws ExecutionException, InterruptedException {
        KV kvClient = client.getKVClient();
        CompletableFuture<PutResponse> put = kvClient.put(ByteSequence.from("a", StandardCharsets.UTF_8), ByteSequence.from("v", StandardCharsets.UTF_8));
        put.join();
        CompletableFuture<GetResponse> get = kvClient.get(ByteSequence.from("a", StandardCharsets.UTF_8));
        Assertions.assertEquals(get.get().getCount(), 1);
    }

Unit test logs:

21:34:20.504 [main] INFO org.testcontainers.images.PullPolicy -- Image pull policy will be performed by: DefaultPullPolicy()
21:34:20.507 [main] INFO org.testcontainers.utility.ImageNameSubstitutor -- Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
21:34:20.791 [Thread-0] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy -- Found Docker environment with Environment variables, system properties and defaults. Resolved dockerHost=unix:///var/run/docker.sock
21:34:20.792 [Thread-0] INFO org.testcontainers.DockerClientFactory -- Docker host IP address is localhost
21:34:20.802 [Thread-0] INFO org.testcontainers.DockerClientFactory -- Connected to docker: 
  Server Version: 25.0.1
  API Version: 1.44
  Operating System: Ubuntu 22.04.3 LTS
  Total Memory: 15885 MB
21:34:20.814 [Thread-0] INFO tc.testcontainers/ryuk:0.5.1 -- Creating container for image: testcontainers/ryuk:0.5.1
21:34:20.877 [Thread-0] INFO tc.testcontainers/ryuk:0.5.1 -- Container testcontainers/ryuk:0.5.1 is starting: 52e65e1102df9efa2ac0feb6a54528e2c7a346a7e575ae14a57b43d2d19c14ed
21:34:21.169 [Thread-0] INFO tc.testcontainers/ryuk:0.5.1 -- Container testcontainers/ryuk:0.5.1 started in PT0.355794278S
21:34:21.172 [Thread-0] INFO org.testcontainers.utility.RyukResourceReaper -- Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
21:34:21.172 [Thread-0] INFO org.testcontainers.DockerClientFactory -- Checking the system...
21:34:21.172 [Thread-0] INFO org.testcontainers.DockerClientFactory -- ✔︎ Docker server version should be at least 1.6.0
21:34:21.176 [Thread-0] INFO tc.gcr.io/etcd-development/etcd:v3.5.10 -- Creating container for image: gcr.io/etcd-development/etcd:v3.5.10
21:34:21.837 [Thread-0] INFO tc.gcr.io/etcd-development/etcd:v3.5.10 -- Container gcr.io/etcd-development/etcd:v3.5.10 is starting: 9ca6709f3771ba2abb87a9a852cf991fcc5ecc3fec7cdca86c9350e01566f605
21:34:22.172 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.171838Z","caller":"flags/flag.go:113","msg":"recognized and used environment variable","variable-name":"ETCD_LOG_LEVEL","variable-value":"info"}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.171953Z","caller":"flags/flag.go:113","msg":"recognized and used environment variable","variable-name":"ETCD_LOGGER","variable-value":"zap"}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"warn","ts":"2024-01-31T00:34:22.172227Z","caller":"embed/config.go:676","msg":"Running http and grpc server on single port. This is not recommended for production."}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.172247Z","caller":"etcdmain/etcd.go:73","msg":"Running: ","args":["etcd","--name","etcd0","--advertise-client-urls","http://0.0.0.0:2379","--listen-client-urls","http://0.0.0.0:2379","--data-dir","/data.etcd"]}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"warn","ts":"2024-01-31T00:34:22.172308Z","caller":"embed/config.go:676","msg":"Running http and grpc server on single port. This is not recommended for production."}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.172315Z","caller":"embed/etcd.go:127","msg":"configuring peer listeners","listen-peer-urls":["http://localhost:2380"]}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.172774Z","caller":"embed/etcd.go:135","msg":"configuring client listeners","listen-client-urls":["http://0.0.0.0:2379"]}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.17286Z","caller":"embed/etcd.go:309","msg":"starting an etcd server","etcd-version":"3.5.10","git-sha":"0223ca52b","go-version":"go1.20.10","go-os":"linux","go-arch":"amd64","max-cpu-set":24,"max-cpu-available":24,"member-initialized":false,"name":"etcd0","data-dir":"/data.etcd","wal-dir":"","wal-dir-dedicated":"","member-dir":"/data.etcd/member","force-new-cluster":false,"heartbeat-interval":"100ms","election-timeout":"1s","initial-election-tick-advance":true,"snapshot-count":100000,"max-wals":5,"max-snapshots":5,"snapshot-catchup-entries":5000,"initial-advertise-peer-urls":["http://localhost:2380"],"listen-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://0.0.0.0:2379"],"listen-client-urls":["http://0.0.0.0:2379"],"listen-metrics-urls":[],"cors":["*"],"host-whitelist":["*"],"initial-cluster":"etcd0=http://localhost:2380","initial-cluster-state":"new","initial-cluster-token":"etcd-cluster","quota-backend-bytes":2147483648,"max-request-bytes":1572864,"max-concurrent-streams":4294967295,"pre-vote":true,"initial-corrupt-check":false,"corrupt-check-time-interval":"0s","compact-check-time-enabled":false,"compact-check-time-interval":"1m0s","auto-compaction-mode":"periodic","auto-compaction-retention":"0s","auto-compaction-interval":"0s","discovery-url":"","discovery-proxy":"","downgrade-check-interval":"5s"}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"warn","ts":"2024-01-31T00:34:22.172899Z","caller":"fileutil/fileutil.go:53","msg":"check file permission","error":"directory \"/data.etcd\" exist, but the permission is \"drwxrwxr-x\". The recommended permission is \"-rwx------\" to prevent possible unprivileged access to the data"}
21:34:22.173 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.173622Z","caller":"etcdserver/backend.go:81","msg":"opened backend db","path":"/data.etcd/member/snap/db","took":"527.12µs"}
21:34:22.175 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.175746Z","caller":"etcdserver/raft.go:495","msg":"starting local member","local-member-id":"8e9e05c52164694d","cluster-id":"cdf818194e3a8c32"}
21:34:22.175 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.175779Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d switched to configuration voters=()"}
21:34:22.176 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.175796Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d became follower at term 0"}
21:34:22.176 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.175801Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"newRaft 8e9e05c52164694d [peers: [], term: 0, commit: 0, applied: 0, lastindex: 0, lastterm: 0]"}
21:34:22.176 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.175805Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d became follower at term 1"}
21:34:22.176 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.175823Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d switched to configuration voters=(10276657743932975437)"}
21:34:22.176 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"warn","ts":"2024-01-31T00:34:22.176635Z","caller":"auth/store.go:1241","msg":"simple token is not cryptographically signed"}
21:34:22.177 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.177236Z","caller":"mvcc/kvstore.go:407","msg":"kvstore restored","current-rev":1}
21:34:22.177 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.17757Z","caller":"etcdserver/quota.go:94","msg":"enabled backend quota with default value","quota-name":"v3-applier","quota-size-bytes":2147483648,"quota-size":"2.1 GB"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.177898Z","caller":"etcdserver/server.go:854","msg":"starting etcd server","local-member-id":"8e9e05c52164694d","local-server-version":"3.5.10","cluster-version":"to_be_decided"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.177945Z","caller":"etcdserver/server.go:738","msg":"started as single-node; fast-forwarding election ticks","local-member-id":"8e9e05c52164694d","forward-ticks":9,"forward-duration":"900ms","election-ticks":10,"election-timeout":"1s"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.177953Z","caller":"fileutil/purge.go:44","msg":"started to purge file","dir":"/data.etcd/member/snap","suffix":"snap.db","max":5,"interval":"30s"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.178Z","caller":"fileutil/purge.go:44","msg":"started to purge file","dir":"/data.etcd/member/snap","suffix":"snap","max":5,"interval":"30s"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.178012Z","caller":"fileutil/purge.go:44","msg":"started to purge file","dir":"/data.etcd/member/wal","suffix":"wal","max":5,"interval":"30s"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.178514Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d switched to configuration voters=(10276657743932975437)"}
21:34:22.178 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.178765Z","caller":"membership/cluster.go:421","msg":"added member","cluster-id":"cdf818194e3a8c32","local-member-id":"8e9e05c52164694d","added-peer-id":"8e9e05c52164694d","added-peer-peer-urls":["http://localhost:2380"]}
21:34:22.179 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.179325Z","caller":"embed/etcd.go:278","msg":"now serving peer/client/metrics","local-member-id":"8e9e05c52164694d","initial-advertise-peer-urls":["http://localhost:2380"],"listen-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://0.0.0.0:2379"],"listen-client-urls":["http://0.0.0.0:2379"],"listen-metrics-urls":[]}
21:34:22.179 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.179355Z","caller":"embed/etcd.go:597","msg":"serving peer traffic","address":"127.0.0.1:2380"}
21:34:22.179 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.179365Z","caller":"embed/etcd.go:569","msg":"cmux::serve","address":"127.0.0.1:2380"}
21:34:22.255 [Thread-0] INFO org.testcontainers.containers.wait.strategy.HttpWaitStrategy -- /stoic_galileo: Waiting for 60 seconds for URL: http://localhost:32813/health (where port 32813 maps to container port 2379)
21:34:22.977 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976537Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d is starting a new election at term 1"}
21:34:22.977 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976572Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d became pre-candidate at term 1"}
21:34:22.977 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976588Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d received MsgPreVoteResp from 8e9e05c52164694d at term 1"}
21:34:22.977 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976602Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d became candidate at term 2"}
21:34:22.977 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976628Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d received MsgVoteResp from 8e9e05c52164694d at term 2"}
21:34:22.977 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976639Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"8e9e05c52164694d became leader at term 2"}
21:34:22.978 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.976648Z","logger":"raft","caller":"etcdserver/zap_raft.go:77","msg":"raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2"}
21:34:22.986 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986573Z","caller":"etcdserver/server.go:2062","msg":"published local member to cluster through raft","local-member-id":"8e9e05c52164694d","local-member-attributes":"{Name:etcd0 ClientURLs:[http://0.0.0.0:2379]}","request-path":"/0/members/8e9e05c52164694d/attributes","cluster-id":"cdf818194e3a8c32","publish-timeout":"7s"}
21:34:22.986 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986575Z","caller":"embed/serve.go:103","msg":"ready to serve client requests"}
21:34:22.986 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986574Z","caller":"etcdserver/server.go:2571","msg":"setting up initial cluster version using v2 API","cluster-version":"3.5"}
21:34:22.986 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986714Z","caller":"etcdmain/main.go:44","msg":"notifying init daemon"}
21:34:22.987 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.98676Z","caller":"etcdmain/main.go:50","msg":"successfully notified init daemon"}
21:34:22.987 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986875Z","caller":"membership/cluster.go:584","msg":"set initial cluster version","cluster-id":"cdf818194e3a8c32","local-member-id":"8e9e05c52164694d","cluster-version":"3.5"}
21:34:22.987 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986944Z","caller":"api/capability.go:75","msg":"enabled capabilities for version","cluster-version":"3.5"}
21:34:22.987 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.986963Z","caller":"etcdserver/server.go:2595","msg":"cluster version is updated","cluster-version":"3.5"}
21:34:22.987 [docker-java-stream--1960887894] INFO io.etcd.jetcd.launcher.EtcdContainer -- [etcd0] STDERR: {"level":"info","ts":"2024-01-31T00:34:22.987399Z","caller":"embed/serve.go:187","msg":"serving client traffic insecurely; this is strongly discouraged!","traffic":"grpc+http","address":"[::]:2379"}
21:34:22.989 [Thread-0] INFO tc.gcr.io/etcd-development/etcd:v3.5.10 -- Container gcr.io/etcd-development/etcd:v3.5.10 started in PT1.813295367S
21:34:23.702 [main] ERROR io.etcd.jetcd.launcher.EtcdContainer -- Error deleting directory /tmp/jetcd_test_etcd0_9431954294630948422
java.io.UncheckedIOException: java.nio.file.AccessDeniedException: /tmp/jetcd_test_etcd0_9431954294630948422/member
	at java.base/java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:87)
	at java.base/java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:103)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at io.etcd.jetcd.launcher.EtcdContainer.deleteDataDirectory(EtcdContainer.java:218)
	at io.etcd.jetcd.launcher.EtcdContainer.close(EtcdContainer.java:251)
	at io.etcd.jetcd.launcher.EtcdClusterImpl.close(EtcdClusterImpl.java:102)
	at io.etcd.jetcd.test.EtcdClusterExtension.after(EtcdClusterExtension.java:108)
	at io.etcd.jetcd.test.EtcdClusterExtension.afterAll(EtcdClusterExtension.java:90)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$18(ClassBasedTestDescriptor.java:462)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$19(ClassBasedTestDescriptor.java:462)
	at org.junit.platform.commons.util.CollectionUtils.forEachInReverseOrder(CollectionUtils.java:217)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:461)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:236)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:85)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
	at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:63)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.nio.file.AccessDeniedException: /tmp/jetcd_test_etcd0_9431954294630948422/member
	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
	at java.base/sun.nio.fs.UnixException.asIOException(UnixException.java:115)
	at java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:477)
	at java.base/java.nio.file.Files.newDirectoryStream(Files.java:481)
	at java.base/java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:301)
	at java.base/java.nio.file.FileTreeWalker.next(FileTreeWalker.java:374)
	at java.base/java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:83)
	... 58 common frames omitted

Expected behavior
It is expected that this AccessDeniedException don't appear at all.

Additional context

  • The tests are running successfully.
  • Using JUnit 5 with jetcd-tests and jetcd-launcher. Docker version is 25.0.1, as shown in the logs
@linghengqian
Copy link
Contributor

linghengqian commented Feb 5, 2024

if (shouldMountDataDirectory) {
    dataDirectory = createDataDirectory(node);
    addFileSystemBind(dataDirectory.toString(), Etcd.ETCD_DATA_DIR, BindMode.READ_WRITE, SelinuxContext.SHARED);
}
  • To be honest, I can't think of a reason why the directory needs to be mounted by default. Because using the Docker Image of quay.io/coreos/etcd does not require this.

  • Of course, there is an option for io.etcd.jetcd.test.EtcdClusterExtension to modify all subcontainers. So here's my thinking.

@RegisterExtension
public static final EtcdClusterExtension CLUSTER = EtcdClusterExtension.builder()
            .withNodes(1)
            .withMountDirectory(false)
            .build();

@lburgazzoli
Copy link
Collaborator

lburgazzoli commented Feb 5, 2024

  • To be honest, I can't think of a reason why the directory needs to be mounted by default. Because using the Docker Image of quay.io/coreos/etcd does not require this.

This is something that has nothing to do with the requirement of the container image but it is something implemented for our test suite which for some tests requires to manipulate the content of the data dir.

* @lburgazzoli I noticed recently that it's you who changed https://github.com/etcd-io/jetcd/blob/jetcd-0.7.7/jetcd-launcher/src/main/java/io/etcd/jetcd/launcher/EtcdContainer.java , can we change the default value of the `shouldMountDataDirectory` property to `false`? Because when unit tests are executed under GraalVM Native Image, the permissions of external files are usually designed not to be changed, see [`java.nio.file.Files#setPosixFilePermissions` cannot be used under Native Image oracle/graal#7860](https://github.com/oracle/graal/issues/7860) .

Before changing the behavior, you need to check what the current test suite is doing.

In any case, this does not solve the issue but just hide it so it would be nice to find out if there is a way to make it working regardless of the flag.

@linghengqian
Copy link
Contributor

In any case, this does not solve the issue but just hide it so it would be nice to find out if there is a way to make it working regardless of the flag.

  • @lburgazzoli I also noticed this issue when investigating embedded HiveServer2, see https://issues.apache.org/jira/browse/HIVE-28418 . It's just that jetcd asks for read, write and execute permissions on the /tmp/ directory from the currently logged in Linux user, while embedded HiveServer2 asks for read, write and execute permissions on the /tmp/hive directory from the currently logged in Linux user. Of course, this can be solved with commands like mkdir -p /tmp/ and chmod -R 777 /tmp/.

  • The humor here is that in all devices of Github Actions, the currently logged in user is given read, write and execute permissions to the /tmp/ directory, but this is not actually the case. At least for Pengwin WSL and Ubuntu 22.04.4 WSL, the corresponding 777 UNIX permissions do not exist for the initial user. Of course, this not only concerns the initial Linux user, but also the user of the Docker Daemon counterpart.

  • That's why I said that containers created by jetcd should not mount the host by default.

@lburgazzoli
Copy link
Collaborator

As stated in the previous comment, I do not have any issue to change it but:

  • we should understand the impact on the test suite
  • we should investigate any possible alternative solution that would work out of the box

Can you help us on that ?

@linghengqian
Copy link
Contributor

linghengqian commented Aug 7, 2024

  • Apart from changing the default value of withMountDirectory, there is probably no clear solution for the current issue. Because etcd server seems unable to load the stored content into memory? No directory can always be assumed to be used at will.

  • Or to put it another way, do we need to document that the /tmp/ directory needs 777 UNIX permissions?

@lburgazzoli
Copy link
Collaborator

So I guess you can:

  • set the java.io.tmpdir to another location on system where the logged in user cannot create/delete directories under /tmp
  • add an option to set the data directory location to the builder

@linghengqian
Copy link
Contributor

  • Considering jetcd-test's use of Files#createTempDirectory, I kind of suspect this is because the system environment variable TMPDIR is undefined. Let me observe locally what happens after changing the EtcdContainer logic in the main branch.

  • By the way, the current issue seems to only be available on Linux

@linghengqian
Copy link
Contributor

  • Actually, for non-root users in Linux, changing the Unix permission of a folder in Java code has no effect at all. If I turn on -Dmaven.surefire.debug for the unit test and execute a bash command like sudo chmod -R 777 ./jetcd_test_etcd0_3046788024186283122/ before executing io.etcd.jetcd.launcher.EtcdContainer#deleteDataDirectory(java.nio.file.Path), this issue is resolved.
  • If I don't manually execute a command like sudo chmod -R 777 ./jetcd_test_etcd0_3046788024186283122/, the entire /tmp/jetcd_test_etcd0_3046788024186283122/member/ folder is not readable, writable, or executable by the current user. This can be visually discovered through nautilus. The owner of the folder is root, not the current user, and the corresponding Unix permissions are 700.
  • image
  • image
  • This will not be solved by changing the logic to the following. Unix permissions are not actually changed.
private static void deleteDataDirectory(Path dir) {
        if (dir != null && Files.exists(dir)) {
            try {
                try (Stream<Path> stream = Files.walk(dir)) {
                    stream.sorted(Comparator.reverseOrder())
                        .map(Path::toFile)
                        .forEach(file -> {
                            file.setReadable(true, false);
                            file.setWritable(true, false);
                            file.setExecutable(true, false);
                            file.delete();
                        });
                } catch (IOException e) {
                    LOGGER.error("Error deleting directory {}", dir, e);
                }
            } catch (Exception e) {
                LOGGER.error("Error deleting directory {}", dir, e);
            }
        }
    }·
  • This is another peculiarity of Github Actions. Github Actions uses the root user. From my perspective, this is not something that can be modified at the Java code level, because the permissions of the subfolder are obtained from the etcd server, which is actually the unix permission inside the docker image of the etcd server.
  • Since etcd server designs Dockerfile in this way, the default value of withMountDirectory should be false, because the current user is often not root.

@lburgazzoli
Copy link
Collaborator

I think this is an issue with your linux distro/WSL because on my linux computer, where I'm not root, this is what I get in my /tmp folder:

➜ ls -la .   
total 144
drwxrwxrwt. 34 root root    820 Aug  7 16:48 .
dr-xr-xr-x. 19 root root    253 Apr 15 00:56 ..
drwxr-xr-x.  3 luca luca     60 Aug  7 16:48 jetcd_test_etcd0_9838939329950072537

@lburgazzoli
Copy link
Collaborator

Again, I can change it to default but I need some help understanding the impact on the actual test suite of jetcd.
Also, can you please set the java.io.tmpdir to something else to see if it actually works ?

@linghengqian
Copy link
Contributor

I think this is an issue with your linux distro/WSL because on my linux computer, where I'm not root, this is what I get in my /tmp folder:

➜ ls -la .   
total 144
drwxrwxrwt. 34 root root    820 Aug  7 16:48 .
dr-xr-xr-x. 19 root root    253 Apr 15 00:56 ..
drwxr-xr-x.  3 luca luca     60 Aug  7 16:48 jetcd_test_etcd0_9838939329950072537
  • This makes sense because I can see this as well.
linghengqian@DESKTOP-2OCN434:/tmp$ ls -la
总计 76
drwxr-xr-x  3 linghengqian linghengqian  4096  8月  7 22:31 jetcd_test_etcd0_15814517176251913946
drwxr-xr-x  3 linghengqian linghengqian  4096  8月  7 22:04 jetcd_test_etcd0_6561556027985872395
  • But if I click in and look at the folder inside, it's clear that the permissions are inconsistent with the external folder. See /tmp/jetcd_test_etcd0_6561556027985872395/member.
linghengqian@DESKTOP-2OCN434:/tmp/jetcd_test_etcd0_15814517176251913946$ ls -la
总计 40
drwxr-xr-x  3 linghengqian linghengqian  4096  8月  7 22:31 .
drwxrwxrwt 13 root         root         28672  8月  7 22:40 ..
drwx------  4 root         root          4096  8月  7 22:31 member

@lburgazzoli
Copy link
Collaborator

Not on my system:

➜ ls -Rl jetcd_test_etcd0_11872653127992502127
jetcd_test_etcd0_11872653127992502127:
total 0
drwx------. 4 luca luca 80 Aug  7 16:48 member

jetcd_test_etcd0_11872653127992502127/member:
total 0
drwx------. 2 luca luca 60 Aug  7 16:48 snap
drwx------. 2 luca luca 80 Aug  7 16:48 wal

jetcd_test_etcd0_11872653127992502127/member/snap:
total 28
-rw-------. 1 luca luca 16801792 Aug  7 16:48 db

jetcd_test_etcd0_11872653127992502127/member/wal:
total 125000
-rw-------. 1 luca luca 64000000 Aug  7 16:48 0000000000000000-0000000000000000.wal
-rw-------. 1 luca luca 64000000 Aug  7 16:48 0.tmp

@lburgazzoli
Copy link
Collaborator

since those files are created by the etcd container, then it may be the docker setup.

@linghengqian
Copy link
Contributor

Again, I can change it to default but I need some help understanding the impact on the actual test suite of jetcd. Also, can you please set the java.io.tmpdir to something else to see if it actually works ?

  • I added -Djava.io.tmpdir=/home/linghengqian/TwinklingLiftWorks/git/public/shardingsphere/test/native/src/test/resources/jetcd_test_etcd to the run settings of the unit tests in IntelliJ IDEA. This is for io.etcd:jetcd-test:0.7.7 to test.
  • image
  • But changing java.io.tmpdir is actually meaningless, and the mounted /member/ folder still has no permissions.
Error Log🙌
[ERROR] 2024-08-07 23:15:52.502 [main] io.etcd.jetcd.launcher.EtcdContainer - Error deleting directory /home/linghengqian/TwinklingLiftWorks/git/public/shardingsphere/test/native/src/test/resources/jetcd_test_etcd/jetcd_test_etcd0_8823803269529779473
java.io.UncheckedIOException: java.nio.file.AccessDeniedException: /home/linghengqian/TwinklingLiftWorks/git/public/shardingsphere/test/native/src/test/resources/jetcd_test_etcd/jetcd_test_etcd0_8823803269529779473/member
	at java.base/java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:87)
	at java.base/java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:103)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:556)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:546)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:611)
	at io.etcd.jetcd.launcher.EtcdContainer.deleteDataDirectory(EtcdContainer.java:218)
	at io.etcd.jetcd.launcher.EtcdContainer.close(EtcdContainer.java:251)
	at io.etcd.jetcd.launcher.EtcdClusterImpl.close(EtcdClusterImpl.java:102)
	at io.etcd.jetcd.test.EtcdClusterExtension.after(EtcdClusterExtension.java:108)
	at io.etcd.jetcd.test.EtcdClusterExtension.afterAll(EtcdClusterExtension.java:90)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$18(ClassBasedTestDescriptor.java:462)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$19(ClassBasedTestDescriptor.java:462)
	at org.junit.platform.commons.util.CollectionUtils.forEachInReverseOrder(CollectionUtils.java:217)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:461)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:236)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:85)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
	at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:63)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.nio.file.AccessDeniedException: /home/linghengqian/TwinklingLiftWorks/git/public/shardingsphere/test/native/src/test/resources/jetcd_test_etcd/jetcd_test_etcd0_8823803269529779473/member
	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
	at java.base/sun.nio.fs.UnixException.asIOException(UnixException.java:115)
	at java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:477)
	at java.base/java.nio.file.Files.newDirectoryStream(Files.java:481)
	at java.base/java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:301)
	at java.base/java.nio.file.FileTreeWalker.next(FileTreeWalker.java:374)
	at java.base/java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:83)
	... 58 common frames omitted

@linghengqian
Copy link
Contributor

since those files are created by the etcd container, then it may be the docker setup.

  • On my Ubuntu 22.04.4 WSL distribution, I have configured Docker to be managed as a non-root user. The installation process is as follows,
sudo apt update && sudo apt upgrade -y
sudo apt-get remove docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc
cd /tmp/
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world
  • If solving this issue requires a rootless Docker daemon, I would say that is completely beyond my imagination. I believe that using a rootless Docker daemon is not the norm.

@lburgazzoli
Copy link
Collaborator

maybe it could be possible to configure the user the container runs as when starting the etcd container but I don't have any experience on WSL nor a computer to test. I would appreciate if you can investigate more and I'd be happy to review a patch.

@linghengqian
Copy link
Contributor

scripts for etcd development

  • There doesn't seem to be any available tool methods in testcontainers-java. This is a bit tricky in the context of the current issue.

@matheuscirillo
Copy link
Author

  • @matheuscirillo I wonder if you are running docker engine in rootless mode? After all, it was you who raised the issue.

Hi @linghengqian! No, I'm not running docker in rootless mode.

@linghengqian
Copy link
Contributor

@lburgazzoli
Copy link
Collaborator

  • To be honest, I don't really know how to run full tests for etcd-io/jetcd in bash, and I haven't seen any documentation for it.

https://github.com/etcd-io/jetcd#running-tests

@linghengqian
Copy link
Contributor

  • To be honest, I don't really know how to run full tests for etcd-io/jetcd in bash, and I haven't seen any documentation for it.

https://github.com/etcd-io/jetcd#running-tests

@linghengqian
Copy link
Contributor

  • So for the master branch of jetcd, there are 3 ways to solve this issue.
  1. Set the TC_USER environment variable to 1000:1000 . At least on Ubuntu 22.04.4 WSL, 1000:1000 is the default logged in user's uid:gid . At this point the currently logged in user can obtain Unix permissions to delete folders.
    @RegisterExtension
    public static final EtcdClusterExtension CLUSTER = EtcdClusterExtension.builder()
            .withNodes(1)
            .build();
  1. Use the currently logged in Linux user as the user to create the Etcd container. This will ensure that we have Unix permissions to delete the folder mounted by the docker volume. For Ubuntu 22.04.4 WSL, the default logged in user's uid:gid is 1000:1000.
    @RegisterExtension
    public static final EtcdClusterExtension CLUSTER = EtcdClusterExtension.builder()
            .withNodes(1)
            .withUser("1000:1000")
            .build();
  1. Do not mount volumes to host directories at all to avoid inconsistent Unix permissions.
    @RegisterExtension
    public static final EtcdClusterExtension CLUSTER = EtcdClusterExtension.builder()
            .withNodes(1)
            .withMountDirectory(false)
            .build();

@lburgazzoli
Copy link
Collaborator

* The only reason I didn't set [jetcd-launcher: allow starting Etcd Container via non-root user on Linux #1390](https://github.com/etcd-io/jetcd/pull/1390) to close the current issue is that I think the default value of `withMountDirectory` is worth changing, but such a change would indeed break forward compatibility. @matheuscirillo  Your opinion?

Please open a dedicated issue

@linghengqian
Copy link
Contributor

* The only reason I didn't set [jetcd-launcher: allow starting Etcd Container via non-root user on Linux #1390](https://github.com/etcd-io/jetcd/pull/1390) to close the current issue is that I think the default value of `withMountDirectory` is worth changing, but such a change would indeed break forward compatibility. @matheuscirillo  Your opinion?

Please open a dedicated issue

  • The current issue can be closed. I am currently out of the office, new issues can be opened by other friends.

@lburgazzoli
Copy link
Collaborator

Fixed by #1390

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants