hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
705 stars 179 forks source link

Building SMBJ: integrationTest FAILED: Status 500: Ports are not available + duplicated code question #812

Open pekuz opened 6 months ago

pekuz commented 6 months ago

Trying to run integrationTest on Windows 10, JDK 11, getting:

        Caused by:
        org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
            at app//org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
            at app//org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:346)
            ... 72 more

            Caused by:
            org.testcontainers.containers.ContainerLaunchException: Could not create/start container
                at app//org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:565)
                at app//org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:356)
                at app//org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
                ... 73 more

                Caused by:
                com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: Ports are not available: exposing port TCP 0.0.0.0:445 -> 0.0.0.0:0: listen tcp 0.0.0.0:445: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247)
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.post(DefaultInvocationBuilder.java:102)
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.exec.StartContainerCmdExec.execute(StartContainerCmdExec.java:31)
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.exec.StartContainerCmdExec.execute(StartContainerCmdExec.java:13)
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.exec.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:21)
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33)
                    at app//org.testcontainers.shaded.com.github.dockerjava.core.command.StartContainerCmdImpl.exec(StartContainerCmdImpl.java:42)
                    at app//org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:453)
                    ... 75 more
? Test com.hierynomus.smbj.AnonymousIntegrationTest; Executed: 1/0/1

IMHO on Windows, the 445 is by default bound to serve the hidden admin shares.

if I speculatively change SambaContainer.java:

    public SambaContainer(Future<String> imageName) {
        super(imageName);
        withExposedPorts(445);
// my try       addFixedExposedPort(445, 445);
        setWaitStrategy(Wait.forListeningPort());
        withLogConsumer(outputFrame -> {

then getting:

        Caused by:
        org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
            at app//org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
            at app//org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:346)
            ... 72 more

            Caused by:
            org.testcontainers.containers.ContainerLaunchException: Could not create/start container
                at app//org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:565)
                at app//org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:356)
                at app//org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
                ... 73 more

                Caused by:
                org.testcontainers.containers.ContainerLaunchException: Timed out waiting for container port to open (localhost ports: [63789] should be listening)
                    at app//org.testcontainers.containers.wait.strategy.HostPortWaitStrategy.waitUntilReady(HostPortWaitStrategy.java:112)
                    at app//org.testcontainers.containers.wait.strategy.AbstractWaitStrategy.waitUntilReady(AbstractWaitStrategy.java:52)
                    at app//org.testcontainers.containers.GenericContainer.waitUntilContainerStarted(GenericContainer.java:978)
                    at app//org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:502)
                    ... 75 more
? Test com.hierynomus.smbj.AnonymousIntegrationTest; Executed: 1/0/1

Seeing SambaContainer.java, I also wonder why:

@Override public void accept(DockerfileBuilder t) {

duplicates content of Dockerfile.

pekuz commented 6 months ago

FYI, after the speculative change, with failed wait for the ephemeral listening port, the container log started with:

/usr/lib/python3.11/site-packages/supervisor/options.py:474: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
  self.warnings.warn(
2024-02-06 09:15:45,972 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
2024-02-06 09:15:46,212 INFO supervisord started with pid 8
2024-02-06 09:15:47,272 INFO spawned: 'nmbd' with pid 158
2024-02-06 09:15:47,322 INFO spawned: 'smbd' with pid 159
2024-02-06 09:15:48,242 INFO success: nmbd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-02-06 09:15:48,412 INFO success: smbd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-02-06 09:15:48,422 WARN exited: nmbd (exit status 1; not expected)
2024-02-06 09:15:48,762 INFO spawned: 'nmbd' with pid 188
2024-02-06 09:15:49,172 WARN exited: smbd (exit status 1; not expected)
2024-02-06 09:15:50,052 INFO success: nmbd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-02-06 09:15:50,142 INFO spawned: 'smbd' with pid 211

and after figuring out how to get preserved /var/log/samba.log:

/ # tail /var/log/samba.log
  interpret_interface: Can't determine ip for broadcast address 192.168.2.0/24
  added interface eth0 ip=172.17.0.2 bcast=172.17.255.255 netmask=255.255.0.0
[2024/02/06 12:12:06.327143,  3] ../../source3/smbd/server.c:1813(main)
  loaded services
[2024/02/06 12:12:06.327171,  1] ../../source3/profile/profile_dummy.c:30(set_profile_level)
  INFO: Profiling support unavailable in this build.
[2024/02/06 12:12:06.327178,  3] ../../source3/smbd/server.c:1845(main)
  Becoming a daemon.
[2024/02/06 12:12:06.327181,  0] ../../lib/util/become_daemon.c:119(exit_daemon)
  exit_daemon: daemon failed to start: Failed to create session, error code 1
pekuz commented 6 months ago

Next speculative change was to follow https://github.com/NullYing/alpine-samba/commit/d11329ef56854e57a7d890cac1405ee31dcf55fe i.e. changing command to:

[program:smbd]
/* command=/usr/sbin/smbd -i --daemon --foreground --log-stdout */
command=/usr/sbin/smbd --foreground --configfile=/etc/samba/smb.conf --no-process-group
/*redirect_stderr=true*/

and then getting:

AnonymousIntegrationTest > shouldConnectToPublicShare(SMB2Dialect, boolean, boolean, AuthenticationContext) > Should connect to public share using (SMB_3_1_1, true, false) with AuthenticationContext[@null] FAILED
    java.lang.NullPointerException
        at com.hierynomus.smbj.connection.SMBSessionBuilder.deriveKey(SMBSessionBuilder.java:324)
        at com.hierynomus.smbj.connection.SMBSessionBuilder.deriveKeys(SMBSessionBuilder.java:290)
        at com.hierynomus.smbj.connection.SMBSessionBuilder.setupSession(SMBSessionBuilder.java:174)
        at com.hierynomus.smbj.connection.SMBSessionBuilder.setupSession(SMBSessionBuilder.java:152)
        at com.hierynomus.smbj.connection.SMBSessionBuilder.establish(SMBSessionBuilder.java:119)
        at com.hierynomus.smbj.connection.Connection.authenticate(Connection.java:202)
        at com.hierynomus.smbj.AnonymousIntegrationTest.lambda$shouldConnectToPublicShare$3(AnonymousIntegrationTest.java:93)
        at com.hierynomus.smbj.testcontainers.SambaContainer.withConnectedClient(SambaContainer.java:118)
        at com.hierynomus.smbj.AnonymousIntegrationTest.shouldConnectToPublicShare(AnonymousIntegrationTest.java:92)
? Test shouldConnectToPublicShare(SMB2Dialect, boolean, boolean, AuthenticationContext); Executed: 13/7/6
? Test com.hierynomus.smbj.AnonymousIntegrationTest; Executed: 27/14/13
? Test shouldCancelChangeNotify(SmbConfig); Executed: 1/1/0
? Test shouldWatchChanges(SmbConfig); Executed: 1/1/0
? Test com.hierynomus.smbj.ChangeNotifyIntegrationTest; Executed: 2/2/0

DfsIntegrationTest > shouldListDfsVirtualDirectory(SmbConfig) > should list contents of DFS virtual directory FAILED
    com.hierynomus.mssmb2.SMBApiException: STATUS_LOGON_FAILURE (0xc000006d): Authentication failed for 'smbj' using com.hierynomus.smbj.auth.NtlmSealer@6aa70f5b

which looks to be on correct way (integration tests effectively covering features).