@ -17,20 +17,30 @@
package org.springframework.boot.launchscript ;
package org.springframework.boot.launchscript ;
import java.io.File ;
import java.io.File ;
import java.io.FileInputStream ;
import java.io.IOException ;
import java.io.InputStream ;
import java.util.ArrayList ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.List ;
import java.util.concurrent.TimeUnit ;
import java.util.concurrent.TimeUnit ;
import java.util.regex.Pattern ;
import java.util.regex.Pattern ;
import javax.ws.rs.client.ClientRequestContext ;
import javax.ws.rs.client.ClientRequestFilter ;
import javax.ws.rs.client.Entity ;
import javax.ws.rs.client.WebTarget ;
import com.github.dockerjava.api.DockerClient ;
import com.github.dockerjava.api.DockerClient ;
import com.github.dockerjava.api.exception.DockerClientException ;
import com.github.dockerjava.api.command.DockerCmd ;
import com.github.dockerjava.api.model.Frame ;
import com.github.dockerjava.api.model.Frame ;
import com.github.dockerjava.core.CompressArchiveUtil ;
import com.github.dockerjava.core.DockerClientBuilder ;
import com.github.dockerjava.core.DockerClientBuilder ;
import com.github.dockerjava.core.DockerClientConfig ;
import com.github.dockerjava.core.DockerClientConfig ;
import com.github.dockerjava.core.DockerClientConfig.DockerClientConfigBuilder ;
import com.github.dockerjava.core.command.AttachContainerResultCallback ;
import com.github.dockerjava.core.command.AttachContainerResultCallback ;
import com.github.dockerjava.core.command.BuildImageResultCallback ;
import com.github.dockerjava.core.command.BuildImageResultCallback ;
import com.github.dockerjava.core.command.WaitContainerResultCallback ;
import com.github.dockerjava.jaxrs.AbstrSyncDockerCmdExec ;
import com.github.dockerjava.jaxrs.DockerCmdExecFactoryImpl ;
import org.assertj.core.api.Condition ;
import org.assertj.core.api.Condition ;
import org.junit.Test ;
import org.junit.Test ;
import org.junit.runner.RunWith ;
import org.junit.runner.RunWith ;
@ -53,6 +63,8 @@ import static org.junit.Assume.assumeThat;
@RunWith ( Parameterized . class )
@RunWith ( Parameterized . class )
public class SysVinitLaunchScriptIT {
public class SysVinitLaunchScriptIT {
private final SpringBootDockerCmdExecFactory commandExecFactory = new SpringBootDockerCmdExecFactory ( ) ;
private static final char ESC = 27 ;
private static final char ESC = 27 ;
private final String os ;
private final String os ;
@ -211,8 +223,7 @@ public class SysVinitLaunchScriptIT {
} ) ;
} ) ;
resultCallback . awaitCompletion ( 60 , TimeUnit . SECONDS ) . close ( ) ;
resultCallback . awaitCompletion ( 60 , TimeUnit . SECONDS ) . close ( ) ;
docker . waitContainerCmd ( container ) . exec ( new WaitContainerResultCallback ( ) )
docker . waitContainerCmd ( container ) . exec ( ) ;
. awaitCompletion ( 60 , TimeUnit . SECONDS ) ;
return output . toString ( ) ;
return output . toString ( ) ;
}
}
finally {
finally {
@ -221,16 +232,11 @@ public class SysVinitLaunchScriptIT {
}
}
private DockerClient createClient ( ) {
private DockerClient createClient ( ) {
DockerClientConfigBuilder builder = DockerClientConfig
DockerClientConfig config = DockerClientConfig . createDefaultConfigBuilder ( )
. createDefaultConfigBuilder ( ) ;
. build ( ) ;
DockerClientConfig config ;
DockerClient docker = DockerClientBuilder . getInstance ( config )
try {
. withDockerCmdExecFactory ( this . commandExecFactory ) . build ( ) ;
config = builder . build ( ) ;
return docker ;
}
catch ( DockerClientException ex ) {
config = builder . withDockerTlsVerify ( false ) . build ( ) ;
}
return DockerClientBuilder . getInstance ( config ) . build ( ) ;
}
}
private String buildImage ( DockerClient docker ) {
private String buildImage ( DockerClient docker ) {
@ -258,9 +264,10 @@ public class SysVinitLaunchScriptIT {
new File ( "src/test/resources/scripts/" + script ) ) ;
new File ( "src/test/resources/scripts/" + script ) ) ;
}
}
private void copyToContainer ( DockerClient docker , String container , File file ) {
private void copyToContainer ( DockerClient docker , final String container ,
docker . copyArchiveToContainerCmd ( container )
final File file ) {
. withHostResource ( file . getAbsolutePath ( ) ) . exec ( ) ;
this . commandExecFactory . createCopyToContainerCmdExec ( )
. exec ( new CopyToContainerCmd ( container , file ) ) ;
}
}
private File findApplication ( ) {
private File findApplication ( ) {
@ -302,4 +309,81 @@ public class SysVinitLaunchScriptIT {
"Failed to extract " + label + " from output: " + output ) ;
"Failed to extract " + label + " from output: " + output ) ;
}
}
private static final class CopyToContainerCmdExec
extends AbstrSyncDockerCmdExec < CopyToContainerCmd , Void > {
private CopyToContainerCmdExec ( WebTarget baseResource ,
DockerClientConfig dockerClientConfig ) {
super ( baseResource , dockerClientConfig ) ;
}
@Override
protected Void execute ( CopyToContainerCmd command ) {
try {
InputStream streamToUpload = new FileInputStream ( CompressArchiveUtil
. archiveTARFiles ( command . getFile ( ) . getParentFile ( ) ,
Arrays . asList ( command . getFile ( ) ) ,
command . getFile ( ) . getName ( ) ) ) ;
WebTarget webResource = getBaseResource ( ) . path ( "/containers/{id}/archive" )
. resolveTemplate ( "id" , command . getContainer ( ) ) ;
webResource . queryParam ( "path" , "." )
. queryParam ( "noOverwriteDirNonDir" , false ) . request ( )
. put ( Entity . entity ( streamToUpload , "application/x-tar" ) ) . close ( ) ;
return null ;
}
catch ( Exception ex ) {
throw new RuntimeException ( ex ) ;
}
}
}
private static final class CopyToContainerCmd implements DockerCmd < Void > {
private final String container ;
private final File file ;
private CopyToContainerCmd ( String container , File file ) {
this . container = container ;
this . file = file ;
}
public String getContainer ( ) {
return this . container ;
}
public File getFile ( ) {
return this . file ;
}
@Override
public void close ( ) {
}
}
private static final class SpringBootDockerCmdExecFactory
extends DockerCmdExecFactoryImpl {
private SpringBootDockerCmdExecFactory ( ) {
withClientRequestFilters ( new ClientRequestFilter ( ) {
@Override
public void filter ( ClientRequestContext requestContext )
throws IOException {
// Workaround for https://go-review.googlesource.com/#/c/3821/
requestContext . getHeaders ( ) . add ( "Connection" , "close" ) ;
}
} ) ;
}
private CopyToContainerCmdExec createCopyToContainerCmdExec ( ) {
return new CopyToContainerCmdExec ( getBaseResource ( ) , getDockerClientConfig ( ) ) ;
}
}
}
}