Permissions error with config mounted into MySQL container
11:42:05.293 [Test worker] ERROR 🐳 [mysql:5.7.22] - Container log output (if any) will follow:
11:42:05.304 [tc-okhttp-stream-474827747] INFO 🐳 [mysql:5.7.22] - STDERR:
11:42:05.305 [tc-okhttp-stream-474827747] INFO 🐳 [mysql:5.7.22] - STDERR: ERROR: mysqld failed while attempting to check config
11:42:05.305 [tc-okhttp-stream-474827747] INFO 🐳 [mysql:5.7.22] - STDERR: command was: "mysqld --verbose --help"
11:42:05.305 [tc-okhttp-stream-474827747] INFO 🐳 [mysql:5.7.22] - STDERR:
11:42:05.306 [tc-okhttp-stream-474827747] INFO 🐳 [mysql:5.7.22] - STDERR: mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
11:42:05.306 [tc-okhttp-stream-474827747] INFO 🐳 [mysql:5.7.22] - STDERR: mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
We see this in the log (look on the null):
Cmd: com.github.dockerjava.core.command.CopyArchiveToContainerCmdImpl@2c8c6bb[cp ,<null>, ,6ca1ea3ce4b2582536fac69ceeb991670930b1ac65a6b2206c1ab88f3c990b65,:,/etc/mysql/] 11:41:45.064 [Test worker] INFO 🐳 [mysql:5.7.22] - Starting container with ID: 6ca1ea3ce4b2582536fac69ceeb991670930b1ac65a6b2206c1ab88f3c990b65
If we override the MySQLContainer class and just rmove this line from the configure function:
optionallyMapResourceParameterAsVolume(MY_CNF_CONFIG_OVERRIDE_PARAM_NAME, "/etc/mysql/conf.d", "mysql-default-conf");
Everything is working. Looks like it is copying invalid file to the container
Hi @ezraroi, in which environment are you running? OS, Docker version?
OS is Ubunto 16.04 and Docker version 17.03.2-ce, build f5ec1e2
I am experiencing this same issue, also on Ubuntu 16.04 but on docker version 18.06.1-ce, build e68fc7a
And this is happening for Testcontainers 1.9.1? Because of the mapping, this is probably some file permissions problem on the host with the config file.
Since we changed most other parts of Testcontainers to favor copying the file into the container instead of mounting or mapping, it would probably solve this problem here as well.
Yes, version 1.9.1.
Same Issue here
<testcontainers.version>1.11.2</testcontainers.version>
build 24-May-2019 09:21:02 2019-05-24 09:21:02.234 ERROR 605 --- [ main] ?.7.23] : Log output from the failed container:
build 24-May-2019 09:21:02 ERROR: mysqld failed while attempting to check config
build 24-May-2019 09:21:02
build 24-May-2019 09:21:02 command was: "mysqld --verbose --help"
build 24-May-2019 09:21:02
build 24-May-2019 09:21:02 mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
build 24-May-2019 09:21:02 mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
I think @kiview is right - this will be down to permissions on the volume mounted configuration. The right long-term solution has to be to change the container code to copy config files in, rather than volume mount. This has been possible for a while.
A PR to do this would be welcomed if anyone is interested; we can help talk through the solution to clarify anything that is needed.
Same problem here Any immediate workaround? I'm on MacOs 10.14.5 and test containers 1.11.2
edit: same thing on 1.11.3
I am also facing this problem. A workaround which seems to work OK for me and is in the spirit of "copy config files in, rather than volume mount", is something like:
mysql = (MySQLContainer) new MySQLContainer().withDatabaseName("some_database")
.withCopyFileToContainer(MountableFile.forClasspathResource("db/testMySQL.cnf"), "/etc/mysql/conf.d/")
.withLogConsumer(logConsumer);
I haven't dug into this much further than that but I assume the ultimate PR would do something similar in the MySQLContainer class?
I also experienced this problem and looked into this further.
This was with
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>1.12.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
In my instance the problem is being caused when the mysql-default-conf resource (my.cnf) inside the mysql-1.12.4.jar is extracted into a temporary folder under /tmp on the host so it can be copied into the mysql container (destination /etc/mysql/conf.d).
The reason it was failing to copy was that the temporary folder was created with no read permission for all users due to my umask setting.
ls -lrat /tmp
...
drwxrwx---. 2 user user 20 Jan 14 22:34 .testcontainers-tmp-15478807415261855030
The solution for me was to change my umask setting so that all users could read the temp folder.
umask 002
@rnorth @kiview - from what I could tell all config files in modules are copied into the container instead of volume mapping (unless I'm missing something)? If you think this is worth documenting somewhere let me know and i'll make the change and submit a PR.
This is actually a bug in the testcontainers implementation in general, checking 1.14.3 and 1.15-rc2, that it almost always never explicitly sets the file permission on resources copied from the host system into a container, but instead relies on the file permissions being correctly set on the host system. This is a major problem, affecting multiple containers when trying to run the test suites.
In this particular case, regarding MySQLContainer, the automatic configuration is done in methods MySQLContainer.configure() and parent class method JdbcDatabaseContainer.optionallyMapResourceParameterAsVolume(), which internally calls MountableFile.forClasspathResource(resourceName) instead of MountableFile.forClasspathResource(resourceName, fileMode).
A sound approach and a proper fix is to explicitly set the file permissions in the implementation class MySQLContainer.configure() that knows about the requirements and change the calls appropriately.
Second, the approach of implicit file permissions in MountableFile.forClassPathResource() should be deprecated in favour of explicitly setting them, i.e. normal use case should be to explicitly set them, unless explicitly file permission are set to be default from the host system.
I experienced the same issue. @rottenha is correct about the root cause. Just want to give a workaround before the fix. Before starting the container, you can set the MY_CNF_CONFIG_OVERRIDE_PARAM_NAME(which value is TC_MY_CNF) to null in the container parameter, like this:
MySQLContainer mysql = new MySQLContainer("mysql:5.7");
mysql.addParameter("TC_MY_CNF", null);
mysql.start();
I am configuring my Test Container with an URL
spring.datasource.url=jdbc:tc:mysql:5.7.28:///scm_ccs?user=root&password=&TC_TMPFS=/testtmpfs-ccs:rw&TC_MY_CNF=mysql.test.cnf&TC_INITSCRIPT=tc_init_mysql.sql
When the container runs it is stopping with mysqld: Can't read dir of '/etc/mysql/conf.d' (Errcode 20 - Not a directory)
When I looked at the source code and one of the work arounds I was wondering if there is not simply a / missing in the file org.testcontainers.containers.MySQLContainer in line 64 at the end of the string "/etc/mysql/conf.d". Shouldn't it be "/etc/mysql/conf.d/"?
Any updates on this issue? @mkirchmann were you able to get your container to run from the URL?
This happens because umask in some Distros is by default 027, which means all permissions get created with no Others Execution
TestContainers by default in POSIX environments uses the default from the OS
777 - 027 = 750
Owner: Read-Write-Execute
Group: Read-Execute
Others: None (Docker volume falls here)
I created a PR to force the file permission to 755, which should fix this issue. Awaiting reviews from Maintainers
As @jarebudev was stating, if you add umask 022 to $HOME/.bashrc, this should workaround the current issue
Snippet:
echo "umask 022" >> $HOME/.bashrc
Hi, is there any solution to what @mkirchmann asked? I'm having the exact same behaviour. If I change this pathNameInContainer to "/etc/mysql/conf.d**/**", with a slash in the end, it works. The problem is that I don't see a way to do it, easily by just adding the dependency. Is there any solution/workaround to this? I tried @driverpt suggestion, but it didn't changed the erroneous behaviour.