diff --git a/.gitignore b/.gitignore
index 8f1fdc779..a705c1129 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,5 @@ target
*.log
#Ignore Test Output
-test-output
\ No newline at end of file
+test-output
+/.checkstyle
diff --git a/.travis.yml b/.travis.yml
index 1d78b3bb9..d055f76e0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,52 @@
+sudo: required
+dist: trusty
language: java
+
+services:
+ - docker
+
jdk:
- oraclejdk7
+
+install: true
+
+env:
+ global:
+ - DOCKER_TLS_VERIFY=""
+ # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
+ # via the "travis encrypt" command using the project repo's public key
+ - secure: "GonzmzvnXsTNQV+6sKtBSSPiwbpMZjxumNt5LFp1g77/afLxw9kl2EQOXbUe308vFOwRVqeY7drBvNJa8aJkTUClfMaGRjfZ9DUwm6doMKMUYrdEkYoQTcH7yDX5K5w9MT6m+Izj+BK2gB7nK3yFlYG6COeXCdFbQ4/cf3/xfRc="
+ - COVERITY_SCAN_PROJECT_NAME="docker-java/docker-java"
+ - COVERITY_SCAN_BRANCH_PATTERN="master"
+ - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com"
+
+ matrix:
+ - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.1-0~trusty" CODECOV=true
+ - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.1-0~trusty" CODECOV=true
+ - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true COVERITY=true CODECOV=true
+ - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" CODECOV=true
+ - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" CODECOV=true
+ - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" CODECOV=true
+# - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375"
+# - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock"
+# - repo="experimental" DOCKER_HOST="tcp://127.0.0.1:2375"
+# - repo="experimental" DOCKER_HOST="unix:///var/run/docker.sock"
+
+cache:
+ directories:
+ - $HOME/.travis_cache
+ - /tmp/coverity-cache
+ - $HOME/.m2 # install will pollute it
+
before_install:
- - pip install --user codecov
+ - pip install --user codecov
+ - ./.travis/travis-before-install.sh
+
+script:
+ - ./.travis/travis-script.sh
+
after_success:
- - ./travis-after-success.sh
+ - ./.travis/travis-after-success.sh
+
+after_script:
+ - sudo cat /var/log/upstart/docker.log
diff --git a/.travis/get-docker-com.sh b/.travis/get-docker-com.sh
new file mode 100755
index 000000000..d9c0142a2
--- /dev/null
+++ b/.travis/get-docker-com.sh
@@ -0,0 +1,313 @@
+#!/bin/sh
+set -e
+#
+# This script is meant for quick & easy install via:
+# 'curl -sSL https://get.docker.com/ | sh'
+# or:
+# 'wget -qO- https://get.docker.com/ | sh'
+#
+# For test builds (ie. release candidates):
+# 'curl -fsSL https://test.docker.com/ | sh'
+# or:
+# 'wget -qO- https://test.docker.com/ | sh'
+#
+# For experimental builds:
+# 'curl -fsSL https://experimental.docker.com/ | sh'
+# or:
+# 'wget -qO- https://experimental.docker.com/ | sh'
+#
+# Docker Maintainers:
+# To update this script on https://get.docker.com,
+# use hack/release.sh during a normal release,
+# or the following one-liner for script hotfixes:
+# aws s3 cp --acl public-read hack/install.sh s3://get.docker.com/index
+#
+
+url="https://get.docker.com/"
+apt_url="https://apt.dockerproject.org"
+yum_url="https://yum.dockerproject.org"
+gpg_fingerprint="58118E89F3A912897C070ADBF76221572C52609D"
+
+key_servers="
+ha.pool.sks-keyservers.net
+pgp.mit.edu
+keyserver.ubuntu.com
+"
+
+command_exists() {
+ command -v "$@" > /dev/null 2>&1
+}
+
+semverParse() {
+ major="${1%%.*}"
+ minor="${1#$major.}"
+ minor="${minor%%.*}"
+ patch="${1#$major.$minor.}"
+ patch="${patch%%[-.]*}"
+}
+
+do_install() {
+ case "$(uname -m)" in
+ *64)
+ ;;
+ *)
+ cat >&2 <<-'EOF'
+ Error: you are not using a 64bit platform.
+ Docker currently only supports 64bit platforms.
+ EOF
+ exit 1
+ ;;
+ esac
+
+ user="$(id -un 2>/dev/null || true)"
+
+ sh_c='sh -c'
+ if [ "$user" != 'root' ]; then
+ if command_exists sudo; then
+ sh_c='sudo -E sh -c'
+ elif command_exists su; then
+ sh_c='su -c'
+ else
+ cat >&2 <<-'EOF'
+ Error: this installer needs the ability to run commands as root.
+ We are unable to find either "sudo" or "su" available to make this happen.
+ EOF
+ exit 1
+ fi
+ fi
+
+ curl=''
+ if command_exists curl; then
+ curl='curl -sSL'
+ elif command_exists wget; then
+ curl='wget -qO-'
+ elif command_exists busybox && busybox --list-modules | grep -q wget; then
+ curl='busybox wget -qO-'
+ fi
+
+ # check to see which repo they are trying to install from
+ if [ -z "$repo" ]; then
+ repo='main'
+ if [ "https://test.docker.com/" = "$url" ]; then
+ repo='testing'
+ elif [ "https://experimental.docker.com/" = "$url" ]; then
+ repo='experimental'
+ fi
+ fi
+
+ # perform some very rudimentary platform detection
+ lsb_dist=''
+ dist_version=''
+ if command_exists lsb_release; then
+ lsb_dist="$(lsb_release -si)"
+ fi
+ if [ -z "$lsb_dist" ] && [ -r /etc/lsb-release ]; then
+ lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")"
+ fi
+ if [ -z "$lsb_dist" ] && [ -r /etc/debian_version ]; then
+ lsb_dist='debian'
+ fi
+ if [ -z "$lsb_dist" ] && [ -r /etc/fedora-release ]; then
+ lsb_dist='fedora'
+ fi
+ if [ -z "$lsb_dist" ] && [ -r /etc/oracle-release ]; then
+ lsb_dist='oracleserver'
+ fi
+ if [ -z "$lsb_dist" ]; then
+ if [ -r /etc/centos-release ] || [ -r /etc/redhat-release ]; then
+ lsb_dist='centos'
+ fi
+ fi
+ if [ -z "$lsb_dist" ] && [ -r /etc/os-release ]; then
+ lsb_dist="$(. /etc/os-release && echo "$ID")"
+ fi
+
+ lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
+
+ case "$lsb_dist" in
+
+ ubuntu)
+ if command_exists lsb_release; then
+ dist_version="$(lsb_release --codename | cut -f2)"
+ fi
+ if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
+ dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
+ fi
+ ;;
+
+ debian)
+ dist_version="$(cat /etc/debian_version | sed 's/\/.*//' | sed 's/\..*//')"
+ case "$dist_version" in
+ 8)
+ dist_version="jessie"
+ ;;
+ 7)
+ dist_version="wheezy"
+ ;;
+ esac
+ ;;
+
+ oracleserver)
+ # need to switch lsb_dist to match yum repo URL
+ lsb_dist="oraclelinux"
+ dist_version="$(rpm -q --whatprovides redhat-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//')"
+ ;;
+
+ fedora|centos)
+ dist_version="$(rpm -q --whatprovides redhat-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//')"
+ ;;
+
+ *)
+ if command_exists lsb_release; then
+ dist_version="$(lsb_release --codename | cut -f2)"
+ fi
+ if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
+ dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
+ fi
+ ;;
+
+
+ esac
+
+
+ # Run setup for each distro accordingly
+ case "$lsb_dist" in
+ ubuntu|debian)
+ export DEBIAN_FRONTEND=noninteractive
+
+ did_apt_get_update=
+ apt_get_update() {
+ if [ -z "$did_apt_get_update" ]; then
+ ( set -x; $sh_c 'sleep 3; apt-get update' )
+ did_apt_get_update=1
+ fi
+ }
+
+ # aufs is preferred over devicemapper; try to ensure the driver is available.
+ if ! grep -q aufs /proc/filesystems && ! $sh_c 'modprobe aufs'; then
+ if uname -r | grep -q -- '-generic' && dpkg -l 'linux-image-*-generic' | grep -qE '^ii|^hi' 2>/dev/null; then
+ kern_extras="linux-image-extra-$(uname -r) linux-image-extra-virtual"
+
+ apt_get_update
+ ( set -x; $sh_c 'sleep 3; apt-get install -y -q '"$kern_extras" ) || true
+
+ if ! grep -q aufs /proc/filesystems && ! $sh_c 'modprobe aufs'; then
+ echo >&2 'Warning: tried to install '"$kern_extras"' (for AUFS)'
+ echo >&2 ' but we still have no AUFS. Docker may not work. Proceeding anyways!'
+ ( set -x; sleep 10 )
+ fi
+ else
+ echo >&2 'Warning: current kernel is not supported by the linux-image-extra-virtual'
+ echo >&2 ' package. We have no AUFS support. Consider installing the packages'
+ echo >&2 ' linux-image-virtual kernel and linux-image-extra-virtual for AUFS support.'
+ ( set -x; sleep 10 )
+ fi
+ fi
+
+ # install apparmor utils if they're missing and apparmor is enabled in the kernel
+ # otherwise Docker will fail to start
+ if [ "$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null)" = 'Y' ]; then
+ if command -v apparmor_parser >/dev/null 2>&1; then
+ echo 'apparmor is enabled in the kernel and apparmor utils were already installed'
+ else
+ echo 'apparmor is enabled in the kernel, but apparmor_parser missing'
+ apt_get_update
+ ( set -x; $sh_c 'sleep 3; apt-get install -y -q apparmor' )
+ fi
+ fi
+
+ if [ ! -e /usr/lib/apt/methods/https ]; then
+ apt_get_update
+ ( set -x; $sh_c 'sleep 3; apt-get install -y -q apt-transport-https ca-certificates' )
+ fi
+ if [ -z "$curl" ]; then
+ apt_get_update
+ ( set -x; $sh_c 'sleep 3; apt-get install -y -q curl ca-certificates' )
+ curl='curl -sSL'
+ fi
+ (
+ set -x
+ for key_server in $key_servers ; do
+ $sh_c "apt-key adv --keyserver hkp://${key_server}:80 --recv-keys ${gpg_fingerprint}" && break
+ done
+ $sh_c "apt-key adv -k ${gpg_fingerprint} >/dev/null"
+ $sh_c "mkdir -p /etc/apt/sources.list.d"
+ $sh_c "echo deb [arch=$(dpkg --print-architecture)] ${apt_url}/repo ${lsb_dist}-${dist_version} ${repo} > /etc/apt/sources.list.d/docker.list"
+ $sh_c 'sleep 3; apt-get update'
+ if [ -z "$DOCKER_VERSION" ]; then
+ $sh_c 'apt-get -o Dpkg::Options::="--force-confnew" install -y -q docker-engine'
+ else
+ $sh_c "apt-get -o Dpkg::Options::=\"--force-confnew\" install -y -q docker-engine=$DOCKER_VERSION"
+ fi
+ )
+ exit 0
+ ;;
+
+ fedora|centos|oraclelinux)
+ $sh_c "cat >/etc/yum.repos.d/docker-${repo}.repo" <<-EOF
+ [docker-${repo}-repo]
+ name=Docker ${repo} Repository
+ baseurl=${yum_url}/repo/${repo}/${lsb_dist}/${dist_version}
+ enabled=1
+ gpgcheck=1
+ gpgkey=${yum_url}/gpg
+ EOF
+ if [ "$lsb_dist" = "fedora" ] && [ "$dist_version" -ge "22" ]; then
+ (
+ set -x
+ $sh_c 'sleep 3; dnf -y -q install docker-engine'
+ )
+ else
+ (
+ set -x
+ $sh_c 'sleep 3; yum -y -q install docker-engine'
+ )
+ fi
+ exit 0
+ ;;
+ gentoo)
+ if [ "$url" = "https://test.docker.com/" ]; then
+ # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output
+ cat >&2 <<-'EOF'
+
+ You appear to be trying to install the latest nightly build in Gentoo.'
+ The portage tree should contain the latest stable release of Docker, but'
+ if you want something more recent, you can always use the live ebuild'
+ provided in the "docker" overlay available via layman. For more'
+ instructions, please see the following URL:'
+
+ https://github.com/tianon/docker-overlay#using-this-overlay'
+
+ After adding the "docker" overlay, you should be able to:'
+
+ emerge -av =app-emulation/docker-9999'
+
+ EOF
+ exit 1
+ fi
+
+ (
+ set -x
+ $sh_c 'sleep 3; emerge app-emulation/docker'
+ )
+ exit 0
+ ;;
+ esac
+
+ # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output
+ cat >&2 <<-'EOF'
+
+ Either your platform is not easily detectable, is not supported by this
+ installer script (yet - PRs welcome! [hack/install.sh]), or does not yet have
+ a package for Docker. Please visit the following URL for more detailed
+ installation instructions:
+
+ https://docs.docker.com/engine/installation/
+
+ EOF
+ exit 1
+}
+
+# wrapped up in a function so that we have some protection against only getting
+# half the file during "curl | sh"
+do_install
diff --git a/travis-after-success.sh b/.travis/travis-after-success.sh
similarity index 72%
rename from travis-after-success.sh
rename to .travis/travis-after-success.sh
index aeb3c12c7..695358122 100755
--- a/travis-after-success.sh
+++ b/.travis/travis-after-success.sh
@@ -1,9 +1,12 @@
#!/usr/bin/env bash
-codecov
-if [[ $TRAVIS_BRANCH == "master" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]];
+if [[ $CODECOV == "true" ]]; then
+ codecov
+fi
+
+if [[ $TRAVIS_BRANCH == "master" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $DEPLOY == "true" ]];
then
- cat << EOF >> ~/settings.xml
+ cat <> ~/settings.xml
diff --git a/.travis/travis-before-install.sh b/.travis/travis-before-install.sh
new file mode 100755
index 000000000..6935f7a7d
--- /dev/null
+++ b/.travis/travis-before-install.sh
@@ -0,0 +1,91 @@
+#!/usr/bin/env bash
+
+
+sudo apt-get install -y -q ca-certificates
+
+export HOST_PORT=2375
+echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt
+
+
+if [ "$FAST_BUILD" == true ]; then
+ echo "Fast build, skipping docker installations."
+ exit 0
+fi
+
+set -exu
+
+docker info
+docker version
+
+sudo -E apt-get update
+sudo -E apt-get install -q -y wget
+sudo -E apt-get -q -y --purge remove docker-engine
+sudo -E apt-cache policy docker-engine
+
+./.travis/get-docker-com.sh
+
+sudo -E stop docker
+
+#mkdir "${HOME}/.cache" || :
+#pushd "${HOME}/.cache"
+# wget -N "https://apt.dockerproject.org/repo/pool/main/d/docker-engine/docker-engine_${DOCKER_VERSION}_amd64.deb"
+# sudo apt-get -f install
+# sudo dpkg -i "$(ls *${DOCKER_VERSION}*)"
+#popd
+#rm -f "src/test/resources/logback.xml"
+mv "src/test/resources/travis-logback.xml" "src/test/resources/logback.xml"
+
+# https://github.com/docker/docker/issues/18113
+sudo rm /var/lib/docker/network/files/local-kv.db
+
+sudo cat /etc/default/docker
+
+cat << EOF | sudo tee /etc/default/docker
+DOCKER_OPTS="\
+--dns 8.8.8.8 \
+--dns 8.8.4.4 \
+-D \
+-H=unix:///var/run/docker.sock \
+-H=tcp://0.0.0.0:${HOST_PORT} \
+"
+EOF
+
+sudo cat /etc/default/docker
+sudo bash -c ':> /var/log/upstart/docker.log'
+
+date
+sudo -E start docker
+
+tries=20
+sleep=5
+for i in $(seq 1 $tries); do
+ if sudo grep "API listen on" /var/log/upstart/docker.log ; then
+ echo "Docker started. Delay $(($i * $sleep))"
+ break
+ elif [[ $i -ge $tries ]]; then
+ echo "Docker didn't start. Exiting!"
+ sudo cat /var/log/upstart/docker.log
+ exit 1
+ else
+ echo "Docker didn't start, sleeping for 5 secs..."
+ sleep $sleep
+ fi
+done
+
+
+sudo ss -antpl
+
+curl -V
+
+docker version || sudo cat /var/log/upstart/docker.log
+docker info
+
+set +u
+
+cat < "${HOME}/.docker-java.properties"
+registry.username=${registry_username}
+registry.password=${registry_password}
+registry.email=${registry_email}
+registry.url=https://index.docker.io/v1/
+
+EOF
diff --git a/.travis/travis-script.sh b/.travis/travis-script.sh
new file mode 100755
index 000000000..1cdc84fa5
--- /dev/null
+++ b/.travis/travis-script.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+
+
+IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"`
+
+export COVERITY_ALLOWED=true
+# Verify upload is permitted
+AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted`
+if [ "$AUTH_RES" = "Access denied" ]; then
+ echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m"
+ COVERITY_ALLOWED=false
+else
+ AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"`
+ if [ "$AUTH" = "true" ]; then
+ echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m"
+ else
+ WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"`
+ echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m"
+
+ COVERITY_ALLOWED=false
+ fi
+fi
+
+set -ex
+
+if [ "${FAST_BUILD}" == "true" ]; then
+ if [ "$TRAVIS_PULL_REQUEST" == "false" ] &&
+ [ "$COVERITY" == "true" ] &&
+ [ "$IS_COVERITY_SCAN_BRANCH" = "1" ] &&
+ [ "$COVERITY_ALLOWED" == "true" ]; then
+ export COVERITY_SCAN_BUILD_COMMAND="mvn package"
+ #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash
+ ./.travis/travisci_build_coverity_scan.sh
+ else
+ mvn package
+ fi
+else
+ if [ "$TRAVIS_PULL_REQUEST" == "false" ] &&
+ [ "$COVERITY" == "true" ] &&
+ [ "$IS_COVERITY_SCAN_BRANCH" = "1" ] &&
+ [ "$COVERITY_ALLOWED" == "true" ]; then
+ export COVERITY_SCAN_BUILD_COMMAND="mvn verify"
+ #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash
+ ./.travis/travisci_build_coverity_scan.sh
+ else
+ mvn verify
+ fi
+fi
diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh
new file mode 100755
index 000000000..074d0a46f
--- /dev/null
+++ b/.travis/travisci_build_coverity_scan.sh
@@ -0,0 +1,113 @@
+#!/bin/bash
+
+set -e
+
+# Environment check
+echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m"
+[ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1
+[ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1
+[ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1
+[ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1
+[ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1
+
+PLATFORM=`uname`
+TOOL_ARCHIVE=/tmp/coverity-cache/cov-analysis-${PLATFORM}.tgz
+TOOL_URL=https://scan.coverity.com/download/${PLATFORM}
+TOOL_BASE=/tmp/coverity-scan-analysis
+UPLOAD_URL="https://scan.coverity.com/builds"
+SCAN_URL="https://scan.coverity.com"
+
+# Do not run on pull requests
+if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then
+ echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m"
+ exit 0
+fi
+
+# Verify this branch should run
+IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"`
+if [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then
+ echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m"
+else
+ echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m"
+ exit 1
+fi
+
+# Verify upload is permitted
+AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted`
+if [ "$AUTH_RES" = "Access denied" ]; then
+ echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m"
+ exit 1
+else
+ AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"`
+ if [ "$AUTH" = "true" ]; then
+ echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m"
+ else
+ WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"`
+ echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m"
+
+ exit 1
+ fi
+fi
+
+mkdir -p /tmp/coverity-cache || :
+
+if [ ! -d $TOOL_BASE ]; then
+
+ # verify that binary is right
+ if file $TOOL_ARCHIVE | grep HTML ; then
+ echo "Removing $TOOL_ARCHIVE"
+ rm -f $TOOL_ARCHIVE
+ fi
+
+ # Download Coverity Scan Analysis Tool
+ if [ ! -e $TOOL_ARCHIVE ]; then
+ echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m"
+ wget -nv -N -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN"
+ fi
+
+ # Extract Coverity Scan Analysis Tool
+ echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m"
+ mkdir -p $TOOL_BASE
+ pushd $TOOL_BASE
+ du -sh $TOOL_ARCHIVE
+ file $TOOL_ARCHIVE
+ file $TOOL_ARCHIVE | grep HTML && cat $TOOL_ARCHIVE || :
+ ls -la $TOOL_ARCHIVE
+ tar -xf $TOOL_ARCHIVE #|& grep -v "Ignoring unknown extended header keyword"
+ popd
+fi
+
+TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'`
+export PATH=$TOOL_DIR/bin:$PATH
+
+# Build
+echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m"
+COV_BUILD_OPTIONS=""
+#COV_BUILD_OPTIONS="--return-emit-failures 8 --parse-error-threshold 85"
+RESULTS_DIR="cov-int"
+eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}"
+COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $COV_BUILD_OPTIONS $COVERITY_SCAN_BUILD_COMMAND
+cov-import-scm --dir $RESULTS_DIR --scm git --log $RESULTS_DIR/scm_log.txt 2>&1
+
+# Upload results
+echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m"
+RESULTS_ARCHIVE=analysis-results.tgz
+tar czf $RESULTS_ARCHIVE $RESULTS_DIR
+SHA=`git rev-parse --short HEAD`
+
+echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m"
+response=$(curl \
+ --silent --write-out "\n%{http_code}\n" \
+ --form project=$COVERITY_SCAN_PROJECT_NAME \
+ --form token=$COVERITY_SCAN_TOKEN \
+ --form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \
+ --form file=@$RESULTS_ARCHIVE \
+ --form version=$SHA \
+ --form description="Travis CI build" \
+ $UPLOAD_URL)
+status_code=$(echo "$response" | sed -n '$p')
+if [ "$status_code" != "201" ]; then
+ TEXT=$(echo "$response" | sed '$d')
+ echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m"
+ exit 1
+fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee0dae776..8f41b2938 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,47 @@
Change Log
===
+## Next 3.0.7
+ * Label image during build
+ * Expose 'User' property on ExecCreateCmd #707 #708
-3.0.0-SNAPSHOT
+## 3.0.6
+ * Fixed issue with jersey and unix domain sockets.
+ * [#703](https://github.com/docker-java/docker-java/pull/703) Allow to configure connection pool timeout.
+ * Make all models Serializable.
+ * [NETTY] Fix loadImage responce on 1.24 API.
+ * LogPath field for inspect container.
+ * [#700] (https://github.com/docker-java/docker-java/pull/700) Bugfix:donot throw RuntimeException when a error occured in awaitCompletion(long,TimeUnit)
+
+## 3.0.5
+ * Events updated to 1.24 API model.
+
+## 3.0.4
+ * Make cert util methods public.
+
+## 3.0.3
+ * [JERSEY] Don't send body for start container request.
+
+## 3.0.2
+ * Enhanced Dockerignore filtering.
+ * Added shmsize for hostconfig.
+ * Exposed HostConfig instead of spaghetty calls.
+
+## 3.0.1
+
+All changes
+* Updated all dependencies
+* [#643] (https://github.com/docker-java/docker-java/pull/643) Fixes for .dockerignore filtering
+* [#627] (https://github.com/docker-java/docker-java/pull/627) Implementation of POST /images/load endpoint
+* [#630] (https://github.com/docker-java/docker-java/pull/630) Fix: Second execution of a docker command in Netty implementation always fails
+* [#596] (https://github.com/docker-java/docker-java/pull/596) Refactor configuration of SSL to allow override with custom config
+* [#529] (https://github.com/docker-java/docker-java/pull/529) Refactor CertUtils. Support ECDSA and PrivateKey
+* [#593] (https://github.com/docker-java/docker-java/pull/593) Added Device.parse() method with simple verification.
+
+v3.0.0
---
Notes
-* The upcoming release will contain multiple API breaking changes therefore the major version switch. It will support a subset of v.1.22 of the docker remote API. It also includes an experimental netty based implementation of `DockerCmdExecFactory` that probably will replace the current jersey/httpclient based one in a later release.
+* The 3.0.0 release contains multiple API breaking changes compared to 2.x therefore the major version switch. It supports a subset of v.1.22 of the docker remote API. It also includes an experimental netty based implementation of `DockerCmdExecFactory` that probably will replace the current jersey/httpclient based one in a later release. Take a look at the [Wiki](https://github.com/docker-java/docker-java/wiki#intialize-docker-client-advanced) how to use it.
* The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details.
All changes
diff --git a/README.md b/README.md
index f2135f61b..d5052e6b9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,11 @@
+[](https://mvnrepository.com/artifact/com.github.docker-java/docker-java)
+[](https://bintray.com/kostyasha/maven/com.github.docker-java%3Adocker-java/_latestVersion)
+[](https://www.versioneye.com/java/com.github.docker-java:docker-java/references)
[](https://travis-ci.org/docker-java/docker-java)
+[](https://scan.coverity.com/projects/9177)
+[](http://codecov.io/github/docker-java/docker-java?branch=master)
+[](https://github.com/docker-java/docker-java/blob/master/LICENSE)
+
# docker-java
@@ -8,16 +15,15 @@ Java API client for [Docker](http://docs.docker.io/ "Docker")
Developer forum for [docker-java](https://groups.google.com/forum/?#!forum/docker-java-dev "docker-java")
+[Changelog](https://github.com/docker-java/docker-java/blob/master/CHANGELOG.md)
+[Wiki](https://github.com/docker-java/docker-java/wiki)
+
## Build with Maven
###### Prerequisites:
-* Java 1.7
-* Maven 3.0.5
-
-If you need SSL, then you'll need to put your `*.pem` file into `~/.docker/`, if you're using boot2docker, do this:
-
- $ ln -s /Users/alex.collins/.boot2docker/certs/boot2docker-vm .docker
+* Java min 1.7
+* Maven 3
Build and run integration tests as follows:
@@ -27,63 +33,41 @@ If you do not have access to a Docker server or just want to execute the build q
$ mvn clean install -DskipITs
-By default Docker server is using UNIX sockets for communication with the Docker client, however docker-java
-client uses TCP/IP to connect to the Docker server by default, so you will need to make sure that your Docker server is
-listening on TCP port. To allow Docker server to use TCP add the following line to /etc/default/docker
+By default the docker engine is using local UNIX sockets for communication with the docker CLI so docker-java
+client also uses UNIX domain sockets to connect to the docker daemon by default. To make the docker daemon listening on a TCP (http/https) port you have to configure it by setting the DOCKER_OPTS environment variable to something like the following:
DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock"
-
-However you can force docker-java to use UNIX socket communication by configure the following (see [Configuration](.#Configuration) for details):
-
- DOCKER_HOST=unix:///var/run/docker.sock
- DOCKER_TLS_VERIFY=0
-
+
More details about setting up Docker server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/
-Now make sure that docker is up:
-
- $ docker -H tcp://127.0.0.1:2375 version
-
- Client version: 0.8.0
- Go version (client): go1.2
- Git commit (client): cc3a8c8
- Server version: 1.2.0
- Git commit (server): fa7b24f
- Go version (server): go1.3.1
-
-Run build without integration tests:
+To force docker-java to use TCP (http) configure the following (see [Configuration](https://github.com/docker-java/docker-java#configuration) for details):
- $ mvn clean install -DskipITs
+ DOCKER_HOST=tcp://127.0.0.1:2375
+
+For secure tls (https) communication:
-## Docker-Java maven dependencies
+ DOCKER_HOST=tcp://127.0.0.1:2376
+ DOCKER_TLS_VERIFY=1
+ DOCKER_CERT_PATH=/Users/marcus/.docker/machine/machines/docker-1.11.2
### Latest release version
-Supports a subset of the Docker Remote API [v1.19](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.19.md), Docker Server version 1.7.x
-
-
- com.github.docker-java
- docker-java
- 2.2.3
-
-
-### Latest release candidate
-Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x
+Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/api/v1.23.md), Docker Server version 1.11.x
com.github.docker-javadocker-java
- 3.0.0-RC5
+ 3.0.6
### Latest development version
-Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x
+Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/api/v1.23.md), Docker Server version 1.11.x
You can find the latest development version including javadoc and source files on [Sonatypes OSS repository](https://oss.sonatype.org/content/groups/public/com/github/docker-java/docker-java/).
com.github.docker-javadocker-java
- 3.0.0-SNAPSHOT
+ 3.0.7-SNAPSHOT
@@ -99,7 +83,7 @@ There are a couple of configuration items, all of which have sensible defaults:
* `DOCKER_TLS_VERIFY` enable/disable TLS verification (switch between `http` and `https` protocol)
* `DOCKER_CERT_PATH` Path to the certificates needed for TLS verification
* `DOCKER_CONFIG` Path for additional docker configuration files (like `.dockercfg`)
-* `api.version` The API version, e.g. `1.21`.
+* `api.version` The API version, e.g. `1.23`.
* `registry.url` Your registry's address.
* `registry.username` Your registry username (required to push containers).
* `registry.password` Your registry password.
@@ -110,12 +94,12 @@ There are three ways to configure, in descending order of precedence:
#### Programmatic:
In your application, e.g.
- DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder()
+ DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("tcp://my-docker-host.tld:2376")
.withDockerTlsVerify(true)
.withDockerCertPath("/home/user/.docker/certs")
.withDockerConfig("/home/user/.docker")
- .withApiVersion("1.21")
+ .withApiVersion("1.23")
.withRegistryUrl("https://index.docker.io/v1/")
.withRegistryUsername("dockeruser")
.withRegistryPassword("ilovedocker")
@@ -129,7 +113,7 @@ In your application, e.g.
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/home/user/.docker/certs
DOCKER_CONFIG=/home/user/.docker
- api.version=1.21
+ api.version=1.23
registry.url=https://index.docker.io/v1/
registry.username=dockeruser
registry.password=ilovedocker
@@ -137,11 +121,11 @@ In your application, e.g.
##### System Properties:
- java -Dregistry.username=dockeruser pkg.Main
+ java -DDOCKER_HOST=tcp://localhost:2375 -Dregistry.username=dockeruser pkg.Main
##### System Environment
- export DOCKER_URL=tcp://localhost:2376
+ export DOCKER_HOST=tcp://localhost:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/home/user/.docker/certs
export DOCKER_CONFIG=/home/user/.docker
diff --git a/docs/devel.adoc b/docs/devel.adoc
index 50c6a7279..1b6295662 100644
--- a/docs/devel.adoc
+++ b/docs/devel.adoc
@@ -13,6 +13,7 @@
** Provide full information on field:
*** For models define API version with `@since {@link RemoteApiVersion#VERSION_1_X}`.
** getters/setters should refernce to field `@see #$field`.
+ * If it is `Serializable` it shall have a `serialVersionUID` field. Unless code has shipped to users, the initial value of the `serialVersionUID` field shall be `1L`.
### Coding style
* TBD, some initial styling already enforced with checkstyle.
@@ -23,3 +24,11 @@
* Integration tests for commands.
* If model object has builders, then fill it with data and compare by `equals()` with expected response
from docker daemon. If failed, then some fields mappings are wrong.
+
+### Debug
+ * When there are unreproducible Travis errors:
+ ** Try locally run test 10-20 times in IDE against the same docker daemon version and same connection type (tcp or socket).
+ ** Limit `.travis.yml` to single run (to not consume their resources with matrix run).
+ ** Remove `travis-logback.xml` replacement (build can't output everything in every run because travis has log limitation).
+ ** Set single test in `pom.xml` `for maven-failsafe-plugin`
+ ** Make PR or if you are maintainer push to branch, catch log and fix.
diff --git a/pom.xml b/pom.xml
index 3b77e6e98..216c48631 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
com.github.docker-javadocker-javajar
- 3.0.0
+ 3.0.7-SNAPSHOTdocker-javahttps://github.com/docker-java/docker-java
@@ -28,10 +28,20 @@
scm:git:git@github.com:docker-java/docker-java.gitgit@github.com:docker-java/docker-java.gitscm:git:git@github.com:docker-java/docker-java.git
- docker-java-3.0.0
+ HEAD
+
+ marcuslinke
+ Marcus Linke
+ marcus.linke@gmx.de
+
+
+ kostyasha
+ Kanstantsin Shautsou
+ kanstantsin.sha@gmail.com
+ kpelykhKonstantin Pelykh
@@ -47,35 +57,35 @@
1.71.7
- 2.11
+ 2.23.12.6.4
- 4.3.1
- 1.5
- 1.8
- 2.3
+ 4.5
+ 1.12
+ 1.10
+ 2.52.6
- 1.7.5
+ 1.7.21
- 1.51
- 2015-01-27T15-02-14
- 18.0
+ 1.54
+ 2.0.4
+ 19.0
- 1.1.0
- 6.1.1
- 4.1.0.CR3
+ 1.1.7
+ 6.9.10
+ 4.1.3.Final1.3
- 1.6
+ 1.82.3.31.10.19
- 2.2
- 2.3.1
- 2.3.1
+ 3.0.2
+ 3.5.1
+ 2.5.32.19.12.19.1
- 1.7
+ 1.8
@@ -89,6 +99,11 @@
jersey-apache-connector${jersey.version}
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.5
+ org.apache.httpcomponentshttpclient
@@ -100,11 +115,15 @@
${jersey.version}
- de.gesellix
- unix-socket-factory
- ${unix-socket-factory.version}
+ com.kohlschutter.junixsocket
+ junixsocket-common
+ ${junixsocket.version}
+
+
+ com.kohlschutter.junixsocket
+ junixsocket-native-common
+ ${junixsocket.version}
-
org.apache.commonscommons-compress
@@ -133,7 +152,7 @@
org.slf4jjcl-over-slf4j
- 1.7.12
+ 1.7.21
@@ -206,7 +225,7 @@
com.google.code.findbugsannotations
- 3.0.0
+ 3.0.1provided
@@ -231,6 +250,12 @@
${netty.version}linux-x86_64
+
+ junit
+ junit
+ 4.12
+ test
+
@@ -245,13 +270,6 @@
-
-
-
-
-
-
-
@@ -321,7 +339,7 @@
org.apache.maven.pluginsmaven-source-plugin
- 2.2.1
+ 3.0.1attach-sources
@@ -334,13 +352,16 @@
org.apache.maven.pluginsmaven-javadoc-plugin
- 2.9.1
+ 2.10.4attach-javadocsjar
+
+ -Xdoclint:none
+
@@ -350,7 +371,7 @@
org.sonatype.pluginsnexus-staging-maven-plugin
- 1.6.2
+ 1.6.7trueossrh
@@ -362,7 +383,7 @@
org.apache.maven.pluginsmaven-release-plugin
- 2.5
+ ${maven-release-plugin.version}truefalse
@@ -376,7 +397,7 @@
maven-surefire-plugin${maven-surefire-plugin.version}
- integration
+ integration,integration-auth
@@ -391,8 +412,11 @@
verify
+ true
+ true
+ 1integration
-
+ integration-auth**/*Test.java
@@ -456,7 +480,8 @@
truetruefalse
-
+
src/test/resources/checkstyle/checkstyle-config.xml
@@ -465,7 +490,7 @@
org.codehaus.mojofindbugs-maven-plugin
- 3.0.2
+ 3.0.3MaxLow
@@ -484,20 +509,35 @@
org.jacocojacoco-maven-plugin
- 0.7.6.201602180812
+ 0.7.7.201606060606prepare-agent
+
- report
+ post-unit-testtestreport
+
+
+ pre-integration-test
+ pre-integration-test
+
+ prepare-agent-integration
+
+
+
+ report-integration
+
+ report-integration
+
+
diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java
index 4c0e2ed56..832890e87 100644
--- a/src/main/java/com/github/dockerjava/api/DockerClient.java
+++ b/src/main/java/com/github/dockerjava/api/DockerClient.java
@@ -35,6 +35,7 @@
import com.github.dockerjava.api.command.ListImagesCmd;
import com.github.dockerjava.api.command.ListNetworksCmd;
import com.github.dockerjava.api.command.ListVolumesCmd;
+import com.github.dockerjava.api.command.LoadImageCmd;
import com.github.dockerjava.api.command.LogContainerCmd;
import com.github.dockerjava.api.command.PauseContainerCmd;
import com.github.dockerjava.api.command.PingCmd;
@@ -90,6 +91,18 @@ public interface DockerClient extends Closeable {
CreateImageCmd createImageCmd(@Nonnull String repository, @Nonnull InputStream imageStream);
+ /**
+ * Loads a tarball with a set of images and tags into a Docker repository.
+ *
+ * Corresponds to POST /images/load API endpoint.
+ *
+ * @param imageStream
+ * stream of the tarball file
+ * @return created command
+ * @since {@link RemoteApiVersion#VERSION_1_7}
+ */
+ LoadImageCmd loadImageCmd(@Nonnull InputStream imageStream);
+
SearchImagesCmd searchImagesCmd(@Nonnull String term);
RemoveImageCmd removeImageCmd(@Nonnull String imageId);
@@ -157,6 +170,7 @@ public interface DockerClient extends Closeable {
* @return created command
* @see #copyArchiveFromContainerCmd(String, String)
* @deprecated since docker API version 1.20, replaced by {@link #copyArchiveFromContainerCmd(String, String)}
+ * since 1.24 fails.
*/
@Deprecated
CopyFileFromContainerCmd copyFileFromContainerCmd(@Nonnull String containerId, @Nonnull String resource);
diff --git a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java
index 20b23e903..ac98db2f9 100644
--- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java
+++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java
@@ -101,6 +101,12 @@ public interface BuildImageCmd extends AsyncDockerCmd getLabels();
+
// setters
BuildImageCmd withTag(String tag);
@@ -145,6 +151,11 @@ public interface BuildImageCmd extends AsyncDockerCmd labels);
+
interface Exec extends DockerCmdAsyncExec {
}
diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java
index 65bdafcac..e2b0072fa 100644
--- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java
+++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java
@@ -6,6 +6,7 @@
import com.github.dockerjava.api.model.Capability;
import com.github.dockerjava.api.model.Device;
import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.Link;
import com.github.dockerjava.api.model.LogConfig;
import com.github.dockerjava.api.model.LxcConf;
@@ -187,6 +188,9 @@ public interface CreateContainerCmd extends SyncDockerCmd securityOpt);
diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
index ae090e434..671c0d535 100644
--- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
+++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java
@@ -3,8 +3,6 @@
import java.io.Closeable;
import java.io.IOException;
-import javax.net.ssl.SSLContext;
-
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.RemoteApiVersion;
@@ -30,6 +28,8 @@ public interface DockerCmdExecFactory extends Closeable {
CreateImageCmd.Exec createCreateImageCmdExec();
+ LoadImageCmd.Exec createLoadImageCmdExec();
+
SearchImagesCmd.Exec createSearchImagesCmdExec();
RemoveImageCmd.Exec createRemoveImageCmdExec();
@@ -117,8 +117,6 @@ public interface DockerCmdExecFactory extends Closeable {
DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec();
- DockerCmdExecFactory withSSLContext(SSLContext sslContext);
-
@Override
void close() throws IOException;
diff --git a/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java b/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java
index fe2329290..829ebf8ee 100644
--- a/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java
+++ b/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java
@@ -20,6 +20,9 @@ public interface ExecCreateCmd extends SyncDockerCmd {
@CheckForNull
Boolean hasTtyEnabled();
+ @CheckForNull
+ String getUser();
+
ExecCreateCmd withAttachStderr(Boolean attachStderr);
ExecCreateCmd withAttachStdin(Boolean attachStdin);
@@ -32,6 +35,8 @@ public interface ExecCreateCmd extends SyncDockerCmd {
ExecCreateCmd withTty(Boolean tty);
+ ExecCreateCmd withUser(String user);
+
interface Exec extends DockerCmdSyncExec {
}
diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java
index 59a267e9d..c8027b0ed 100644
--- a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java
+++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java
@@ -53,6 +53,12 @@ public class InspectContainerResponse {
@JsonProperty("HostsPath")
private String hostsPath;
+ /**
+ * @since {@link RemoteApiVersion#VERSION_1_17}
+ */
+ @JsonProperty("LogPath")
+ private String logPath;
+
@JsonProperty("Id")
private String id;
@@ -168,6 +174,11 @@ public String getHostsPath() {
return hostsPath;
}
+ @CheckForNull
+ public String getLogPath() {
+ return logPath;
+ }
+
public String getName() {
return name;
}
diff --git a/src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java b/src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java
new file mode 100644
index 000000000..184b7ef33
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java
@@ -0,0 +1,21 @@
+package com.github.dockerjava.api.command;
+
+import java.io.InputStream;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+public interface LoadImageCmd extends SyncDockerCmd {
+
+ @CheckForNull
+ InputStream getImageStream();
+
+ /**
+ * @param imageStream
+ * the InputStream of the tar file
+ */
+ LoadImageCmd withImageStream(@Nonnull InputStream imageStream);
+
+ interface Exec extends DockerCmdSyncExec {
+ }
+}
diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java
index 849f26a21..074c6db61 100644
--- a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java
+++ b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java
@@ -8,9 +8,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
@JsonInclude(Include.NON_NULL)
-public class AuthConfig {
+public class AuthConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
/**
* For backwards compatibility. Make sure you update the properties if you change this.
diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java b/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java
index e8edbc950..baa8fc0b4 100644
--- a/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java
+++ b/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java
@@ -1,11 +1,13 @@
package com.github.dockerjava.api.model;
+import java.io.Serializable;
import java.util.Map;
import java.util.TreeMap;
import com.fasterxml.jackson.annotation.JsonProperty;
-public class AuthConfigurations {
+public class AuthConfigurations implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("configs")
private Map configs = new TreeMap<>();
diff --git a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java
index cb5d9df80..cd6908185 100644
--- a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java
+++ b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java
@@ -2,7 +2,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
-public class AuthResponse {
+import java.io.Serializable;
+
+public class AuthResponse implements Serializable {
+ private static final long serialVersionUID = 1L;
+
@JsonProperty("Status")
private String status;
diff --git a/src/main/java/com/github/dockerjava/api/model/Bind.java b/src/main/java/com/github/dockerjava/api/model/Bind.java
index bf02bbad2..9a7ebf18d 100644
--- a/src/main/java/com/github/dockerjava/api/model/Bind.java
+++ b/src/main/java/com/github/dockerjava/api/model/Bind.java
@@ -3,11 +3,14 @@
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
+import java.io.Serializable;
+
/**
* Represents a host path being bind mounted as a {@link Volume} in a Docker container.
* The Bind can be in read only or read write access mode.
*/
-public class Bind {
+public class Bind implements Serializable {
+ private static final long serialVersionUID = 1L;
private String path;
@@ -15,24 +18,48 @@ public class Bind {
private AccessMode accessMode;
+ /**
+ * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_23}
+ */
+ private Boolean noCopy;
+
/**
* @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_17}
*/
private SELContext secMode;
+ /**
+ * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22}
+ */
+ private PropagationMode propagationMode;
+
public Bind(String path, Volume volume) {
this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT);
}
+ public Bind(String path, Volume volume, Boolean noCopy) {
+ this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT, noCopy);
+ }
+
public Bind(String path, Volume volume, AccessMode accessMode) {
this(path, volume, accessMode, SELContext.DEFAULT);
}
public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode) {
+ this(path, volume, accessMode, secMode, null);
+ }
+
+ public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode, Boolean noCopy) {
+ this(path, volume, accessMode, secMode, noCopy, PropagationMode.DEFAULT_MODE);
+ }
+
+ public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode, Boolean noCopy, PropagationMode propagationMode) {
this.path = path;
this.volume = volume;
this.accessMode = accessMode;
this.secMode = secMode;
+ this.noCopy = noCopy;
+ this.propagationMode = propagationMode;
}
public String getPath() {
@@ -51,6 +78,14 @@ public SELContext getSecMode() {
return secMode;
}
+ public Boolean getNoCopy() {
+ return noCopy;
+ }
+
+ public PropagationMode getPropagationMode() {
+ return propagationMode;
+ }
+
/**
* Parses a bind mount specification to a {@link Bind}.
*
@@ -71,15 +106,25 @@ public static Bind parse(String serialized) {
String[] flags = parts[2].split(",");
AccessMode accessMode = AccessMode.DEFAULT;
SELContext seMode = SELContext.DEFAULT;
+ Boolean nocopy = null;
+ PropagationMode propagationMode = PropagationMode.DEFAULT_MODE;
for (String p : flags) {
if (p.length() == 2) {
accessMode = AccessMode.valueOf(p.toLowerCase());
+ } else if ("nocopy".equals(p)) {
+ nocopy = true;
+ } else if (PropagationMode.SHARED.toString().equals(p)) {
+ propagationMode = PropagationMode.SHARED;
+ } else if (PropagationMode.SLAVE.toString().equals(p)) {
+ propagationMode = PropagationMode.SLAVE;
+ } else if (PropagationMode.PRIVATE.toString().equals(p)) {
+ propagationMode = PropagationMode.PRIVATE;
} else {
seMode = SELContext.fromString(p);
}
}
- return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode);
+ return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode, nocopy, propagationMode);
}
default: {
throw new IllegalArgumentException();
@@ -99,6 +144,8 @@ public boolean equals(Object obj) {
.append(volume, other.getVolume())
.append(accessMode, other.getAccessMode())
.append(secMode, other.getSecMode())
+ .append(noCopy, other.getNoCopy())
+ .append(propagationMode, other.getPropagationMode())
.isEquals();
} else {
return super.equals(obj);
@@ -112,6 +159,8 @@ public int hashCode() {
.append(volume)
.append(accessMode)
.append(secMode)
+ .append(noCopy)
+ .append(propagationMode)
.toHashCode();
}
@@ -124,10 +173,12 @@ public int hashCode() {
*/
@Override
public String toString() {
- return String.format("%s:%s:%s%s",
+ return String.format("%s:%s:%s%s%s%s",
path,
volume.getPath(),
accessMode.toString(),
- secMode != SELContext.none ? "," + secMode.toString() : "");
+ secMode != SELContext.none ? "," + secMode.toString() : "",
+ noCopy != null ? ",nocopy" : "",
+ propagationMode != PropagationMode.DEFAULT_MODE ? "," + propagationMode.toString() : "");
}
}
diff --git a/src/main/java/com/github/dockerjava/api/model/Binds.java b/src/main/java/com/github/dockerjava/api/model/Binds.java
index 917cfdcbd..b24c3208d 100644
--- a/src/main/java/com/github/dockerjava/api/model/Binds.java
+++ b/src/main/java/com/github/dockerjava/api/model/Binds.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -19,7 +20,8 @@
@JsonSerialize(using = Binds.Serializer.class)
@JsonDeserialize(using = Binds.Deserializer.class)
-public class Binds {
+public class Binds implements Serializable {
+ private static final long serialVersionUID = 1L;
private Bind[] binds;
diff --git a/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java b/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java
index a53a1df9a..7236be23d 100644
--- a/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java
+++ b/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java
@@ -8,7 +8,6 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class BuildResponseItem extends ResponseItem {
-
private static final long serialVersionUID = -1252904184236343612L;
private static final String BUILD_SUCCESS = "Successfully built";
diff --git a/src/main/java/com/github/dockerjava/api/model/ChangeLog.java b/src/main/java/com/github/dockerjava/api/model/ChangeLog.java
index 36804362c..04b36f5ce 100644
--- a/src/main/java/com/github/dockerjava/api/model/ChangeLog.java
+++ b/src/main/java/com/github/dockerjava/api/model/ChangeLog.java
@@ -5,13 +5,16 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
*
* @author Konstantin Pelykh (kpelykh@gmail.com)
*
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ChangeLog {
+public class ChangeLog implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Path")
private String path;
diff --git a/src/main/java/com/github/dockerjava/api/model/Container.java b/src/main/java/com/github/dockerjava/api/model/Container.java
index 47492920d..9e04362ce 100644
--- a/src/main/java/com/github/dockerjava/api/model/Container.java
+++ b/src/main/java/com/github/dockerjava/api/model/Container.java
@@ -11,6 +11,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.Map;
/**
@@ -20,7 +21,8 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class Container {
+public class Container implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Command")
private String command;
diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java
index 224da3272..191126798 100644
--- a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java
+++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java
@@ -10,6 +10,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.Map;
/**
@@ -19,7 +20,8 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class ContainerConfig {
+public class ContainerConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("AttachStderr")
private Boolean attachStderr;
diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java
index 43a5a94b1..8d0c3fe37 100644
--- a/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java
+++ b/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java
@@ -6,6 +6,8 @@
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
+import java.io.Serializable;
+
/**
* Used in {@link Container}
*
@@ -13,7 +15,9 @@
* @author Kanstantsin Shautsou
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ContainerHostConfig {
+public class ContainerHostConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
+
@JsonProperty("NetworkMode")
private String networkMode;
diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java
index 9b2160e98..bc7e12d33 100644
--- a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java
+++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java
@@ -9,6 +9,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@@ -21,7 +22,9 @@
* @author Kanstantsin Shautsou
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ContainerNetwork {
+public class ContainerNetwork implements Serializable {
+ private static final long serialVersionUID = 1L;
+
/**
* FIXME verify
*/
diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java
index 7f4b17be5..bc6165874 100644
--- a/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java
+++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java
@@ -7,6 +7,7 @@
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
+import java.io.Serializable;
import java.util.Map;
/**
@@ -16,7 +17,9 @@
* @since {@link RemoteApiVersion#VERSION_1_22}
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ContainerNetworkSettings {
+public class ContainerNetworkSettings implements Serializable {
+ private static final long serialVersionUID = 1L;
+
/**
* @since {@link RemoteApiVersion#VERSION_1_22}
*/
diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerPort.java b/src/main/java/com/github/dockerjava/api/model/ContainerPort.java
index 09f718ef6..5924e53df 100644
--- a/src/main/java/com/github/dockerjava/api/model/ContainerPort.java
+++ b/src/main/java/com/github/dockerjava/api/model/ContainerPort.java
@@ -7,13 +7,15 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
/**
* @author Kanstantsin Shautsou
* @see Container
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ContainerPort {
+public class ContainerPort implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("IP")
private String ip;
diff --git a/src/main/java/com/github/dockerjava/api/model/Device.java b/src/main/java/com/github/dockerjava/api/model/Device.java
index 9240239b1..7d73710fd 100644
--- a/src/main/java/com/github/dockerjava/api/model/Device.java
+++ b/src/main/java/com/github/dockerjava/api/model/Device.java
@@ -1,6 +1,8 @@
package com.github.dockerjava.api.model;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.commons.lang.BooleanUtils.isNotTrue;
+import static org.apache.commons.lang.StringUtils.isEmpty;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -9,8 +11,15 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.Nonnull;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
@JsonInclude(Include.NON_NULL)
-public class Device {
+public class Device implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("CgroupPermissions")
private String cGroupPermissions = "";
@@ -45,6 +54,75 @@ public String getPathOnHost() {
return pathOnHost;
}
+ /**
+ * @link https://github.com/docker/docker/blob/6b4a46f28266031ce1a1315f17fb69113a06efe1/runconfig/opts/parse_test.go#L468
+ */
+ @Nonnull
+ public static Device parse(@Nonnull String deviceStr) {
+ String src = "";
+ String dst = "";
+ String permissions = "rwm";
+ final String[] arr = deviceStr.trim().split(":");
+ // java String.split() returns wrong length, use tokenizer instead
+ switch (new StringTokenizer(deviceStr, ":").countTokens()) {
+ case 3: {
+ // Mismatches docker code logic. While there is no validations after parsing, checking heregit
+ if (validDeviceMode(arr[2])) {
+ permissions = arr[2];
+ } else {
+ throw new IllegalArgumentException("Invalid device specification: " + deviceStr);
+ }
+ }
+ case 2: {
+ if (validDeviceMode(arr[1])) {
+ permissions = arr[1];
+ } else {
+ dst = arr[1];
+ }
+ }
+ case 1: {
+ src = arr[0];
+ break;
+ }
+ default: {
+ throw new IllegalArgumentException("Invalid device specification: " + deviceStr);
+ }
+ }
+
+ if (isEmpty(dst)) {
+ dst = src;
+ }
+
+ return new Device(permissions, dst, src);
+ }
+
+ /**
+ * ValidDeviceMode checks if the mode for device is valid or not.
+ * Valid mode is a composition of r (read), w (write), and m (mknod).
+ *
+ * @link https://github.com/docker/docker/blob/6b4a46f28266031ce1a1315f17fb69113a06efe1/runconfig/opts/parse.go#L796
+ */
+ private static boolean validDeviceMode(String deviceMode) {
+ Map validModes = new HashMap<>(3);
+ validModes.put("r", true);
+ validModes.put("w", true);
+ validModes.put("m", true);
+
+ if (isEmpty(deviceMode)) {
+ return false;
+ }
+
+ for (char ch : deviceMode.toCharArray()) {
+ final String mode = String.valueOf(ch);
+ if (isNotTrue(validModes.get(mode))) {
+ return false; // wrong mode
+ }
+ validModes.put(mode, false);
+ }
+
+ return true;
+ }
+
@Override
public boolean equals(Object obj) {
if (obj instanceof Device) {
diff --git a/src/main/java/com/github/dockerjava/api/model/DriverStatus.java b/src/main/java/com/github/dockerjava/api/model/DriverStatus.java
index 3e2b5037a..7c1374aae 100644
--- a/src/main/java/com/github/dockerjava/api/model/DriverStatus.java
+++ b/src/main/java/com/github/dockerjava/api/model/DriverStatus.java
@@ -7,12 +7,15 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
- * Created by ben on 12/12/13.
+ * @author ben
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class DriverStatus {
+public class DriverStatus implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Root Dir")
private String rootDir;
diff --git a/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java b/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java
index 62018a4e0..92e869d2a 100644
--- a/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java
+++ b/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java
@@ -4,8 +4,12 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
@JsonInclude(Include.NON_NULL)
-public class ErrorDetail {
+public class ErrorDetail implements Serializable {
+ private static final long serialVersionUID = 1L;
+
@JsonProperty
private String message;
diff --git a/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java b/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java
index 172bd5c79..f6abfc3eb 100644
--- a/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java
+++ b/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java
@@ -4,8 +4,12 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
@JsonInclude(Include.NON_NULL)
-public class ErrorResponse {
+public class ErrorResponse implements Serializable {
+ private static final long serialVersionUID = 1L;
+
@JsonProperty
private ErrorDetail errorDetail;
diff --git a/src/main/java/com/github/dockerjava/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java
index 202f5a350..6e4b6f3c2 100644
--- a/src/main/java/com/github/dockerjava/api/model/Event.java
+++ b/src/main/java/com/github/dockerjava/api/model/Event.java
@@ -1,27 +1,81 @@
package com.github.dockerjava.api.model;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import javax.annotation.CheckForNull;
+
+import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE;
+
+import java.io.Serializable;
/**
* Representation of a Docker event.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class Event {
+public class Event implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @since 1.16
+ */
+ @JsonProperty("status")
private String status;
+ /**
+ * @since 1.16
+ */
+ @JsonProperty("id")
private String id;
+ /**
+ * @since 1.16
+ */
+ @JsonProperty("from")
private String from;
+ /**
+ * ??
+ */
+ @JsonProperty("node")
+ private Node node;
+
+ /*
+ * @since 1.
+ */
+ @JsonProperty("Type")
+ private EventType type;
+
+ /**
+ * @since 1.22
+ */
+ @JsonProperty("Action")
+ private String action;
+
+ /**
+ * @since 1.22
+ */
+ @JsonProperty("Actor")
+ private EventActor actor;
+
+ /**
+ * @since 1.16
+ */
+ @JsonProperty("time")
private Long time;
- @JsonIgnoreProperties
- private Node node;
+ /**
+ * @since 1.21
+ */
+ @JsonProperty("timeNano")
+ private Long timeNano;
/**
* Default constructor for the deserialization.
@@ -32,16 +86,12 @@ public Event() {
/**
* Constructor.
*
- * @param id
- * Container ID
- * @param status
- * Status string. List of statuses is available in Docker API v.1.16
- * @param from
- * Image, from which the container has been created
- * @param time
- * Event time The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT
- * @since TODO
+ * @param id Container ID
+ * @param status Status string. List of statuses is available in Docker API v.1.16
+ * @param from Image, from which the container has been created
+ * @param time Event time The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT
+ * @since 1.16
*/
public Event(String status, String id, String from, Long time) {
this.status = status;
@@ -60,6 +110,14 @@ public String getStatus() {
return status;
}
+ /**
+ * @see #status
+ */
+ public Event withStatus(String status) {
+ this.status = status;
+ return this;
+ }
+
/**
* Get ID of docker container.
*
@@ -69,6 +127,14 @@ public String getId() {
return id;
}
+ /**
+ * @see #id
+ */
+ public Event withId(String id) {
+ this.id = id;
+ return this;
+ }
+
/**
* Get source image of the container.
*
@@ -78,6 +144,14 @@ public String getFrom() {
return from;
}
+ /**
+ * @see #from
+ */
+ public Event withFrom(String from) {
+ this.from = from;
+ return this;
+ }
+
/**
* Get the event time. The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT
*
@@ -87,6 +161,30 @@ public Long getTime() {
return time;
}
+ /**
+ * @see #time
+ */
+ public Event withTime(Long time) {
+ this.time = time;
+ return this;
+ }
+
+ /**
+ * @see #timeNano
+ */
+ @CheckForNull
+ public Long getTimeNano() {
+ return timeNano;
+ }
+
+ /**
+ * @see #timeNano
+ */
+ public Event withTimenano(Long timenano) {
+ this.timeNano = timenano;
+ return this;
+ }
+
/**
* Returns the node when working against docker swarm
*/
@@ -94,8 +192,71 @@ public Node getNode() {
return node;
}
+ /**
+ * @see #node
+ */
+ public Event withNode(Node node) {
+ this.node = node;
+ return this;
+ }
+
+ @CheckForNull
+ public EventType getType() {
+ return type;
+ }
+
+ /**
+ * @see #type
+ */
+ public Event withType(EventType type) {
+ this.type = type;
+ return this;
+ }
+
+ /**
+ * @see #action
+ */
+ @CheckForNull
+ public String getAction() {
+ return action;
+ }
+
+ /**
+ * @see #action
+ */
+ public Event withAction(String action) {
+ this.action = action;
+ return this;
+ }
+
+ /**
+ * @see #actor
+ */
+ @CheckForNull
+ public EventActor getActor() {
+ return actor;
+ }
+
+ /**
+ * @see #actor
+ */
+ public Event withEventActor(EventActor actor) {
+ this.actor = actor;
+ return this;
+ }
+
@Override
public String toString() {
- return ToStringBuilder.reflectionToString(this);
+ return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return EqualsBuilder.reflectionEquals(this, o);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
}
}
diff --git a/src/main/java/com/github/dockerjava/api/model/EventActor.java b/src/main/java/com/github/dockerjava/api/model/EventActor.java
new file mode 100644
index 000000000..f7b0abbf3
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/api/model/EventActor.java
@@ -0,0 +1,77 @@
+package com.github.dockerjava.api.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import javax.annotation.CheckForNull;
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author Kanstantsin Shautsou
+ * @since 1.22
+ */
+public class EventActor implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @since 1.22
+ */
+ @JsonProperty("ID")
+ private String id;
+
+ /**
+ * @since 1.22
+ */
+ @JsonProperty("Attributes")
+ private Map attributes;
+
+ /**
+ * @see #id
+ */
+ @CheckForNull
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @see #id
+ */
+ public EventActor withId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * @see #attributes
+ */
+ @CheckForNull
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * @see #attributes
+ */
+ public EventActor withAttributes(Map attributes) {
+ this.attributes = attributes;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return EqualsBuilder.reflectionEquals(this, o);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this);
+ }
+}
diff --git a/src/main/java/com/github/dockerjava/api/model/EventType.java b/src/main/java/com/github/dockerjava/api/model/EventType.java
new file mode 100644
index 000000000..697c1e429
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/api/model/EventType.java
@@ -0,0 +1,55 @@
+package com.github.dockerjava.api.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import javax.annotation.Nonnull;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @since 1.24
+ */
+public enum EventType {
+ /**
+ * @since 1.24
+ */
+ CONTAINER("container"),
+
+ /**
+ * @since 1.24
+ */
+ DAEMON("daemon"),
+
+ /**
+ * @since 1.24
+ */
+ IMAGE("image"),
+ NETWORK("network"),
+ PLUGIN("plugin"),
+ VOLUME("volume");
+
+ private static final Map EVENT_TYPES = new HashMap<>();
+
+ static {
+ for (EventType t : values()) {
+ EVENT_TYPES.put(t.name().toLowerCase(), t);
+ }
+ }
+
+ private String value;
+
+ EventType(@Nonnull String value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+
+ @JsonCreator
+ public static EventType forValue(String s) {
+ return EVENT_TYPES.get(s);
+ }
+}
diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java
index ec95f6273..26d727ff4 100644
--- a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java
+++ b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java
@@ -4,6 +4,7 @@
import static com.github.dockerjava.api.model.InternetProtocol.UDP;
import java.io.IOException;
+import java.io.Serializable;
import java.util.Map.Entry;
import org.apache.commons.lang.builder.EqualsBuilder;
@@ -30,7 +31,8 @@
*/
@JsonDeserialize(using = ExposedPort.Deserializer.class)
@JsonSerialize(using = ExposedPort.Serializer.class)
-public class ExposedPort {
+public class ExposedPort implements Serializable {
+ private static final long serialVersionUID = 1L;
private final InternetProtocol protocol;
diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java
index 0ecb879b6..7670212e1 100644
--- a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java
+++ b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -21,7 +22,8 @@
@JsonSerialize(using = ExposedPorts.Serializer.class)
@JsonDeserialize(using = ExposedPorts.Deserializer.class)
-public class ExposedPorts {
+public class ExposedPorts implements Serializable {
+ private static final long serialVersionUID = 1L;
private ExposedPort[] exposedPorts;
diff --git a/src/main/java/com/github/dockerjava/api/model/Frame.java b/src/main/java/com/github/dockerjava/api/model/Frame.java
index 0ad16e8c6..9b1376f82 100644
--- a/src/main/java/com/github/dockerjava/api/model/Frame.java
+++ b/src/main/java/com/github/dockerjava/api/model/Frame.java
@@ -1,11 +1,14 @@
package com.github.dockerjava.api.model;
+import java.io.Serializable;
import java.util.Arrays;
/**
* Represents a logging frame.
*/
-public class Frame {
+public class Frame implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private final StreamType streamType;
private final byte[] payload;
diff --git a/src/main/java/com/github/dockerjava/api/model/HostConfig.java b/src/main/java/com/github/dockerjava/api/model/HostConfig.java
index 4d9d7f145..62bde8650 100644
--- a/src/main/java/com/github/dockerjava/api/model/HostConfig.java
+++ b/src/main/java/com/github/dockerjava/api/model/HostConfig.java
@@ -11,6 +11,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@@ -20,7 +21,8 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class HostConfig {
+public class HostConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
private static final List PREDEFINED_NETWORKS = Arrays.asList("bridge", "host", "none");
@@ -190,7 +192,7 @@ public class HostConfig {
* @since {@link RemoteApiVersion#VERSION_1_22}
*/
@JsonProperty("ShmSize")
- private String shmSize;
+ private Long shmSize;
@JsonIgnore
@@ -401,7 +403,7 @@ public String getCgroupParent() {
* @see #shmSize
*/
@CheckForNull
- public String getShmSize() {
+ public Long getShmSize() {
return shmSize;
}
@@ -764,7 +766,7 @@ public HostConfig withSecurityOpts(String[] securityOpts) {
/**
* @see #shmSize
*/
- public HostConfig withShmSize(String shmSize) {
+ public HostConfig withShmSize(Long shmSize) {
this.shmSize = shmSize;
return this;
}
diff --git a/src/main/java/com/github/dockerjava/api/model/Identifier.java b/src/main/java/com/github/dockerjava/api/model/Identifier.java
index 1051d857f..8f1c871a7 100644
--- a/src/main/java/com/github/dockerjava/api/model/Identifier.java
+++ b/src/main/java/com/github/dockerjava/api/model/Identifier.java
@@ -3,10 +3,14 @@
import com.google.common.base.Objects;
import com.google.common.base.Optional;
+import java.io.Serializable;
+
/**
- * Created by magnayn on 22/07/2014.
+ * @author magnayn
*/
-public class Identifier {
+public class Identifier implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public final Repository repository;
public final Optional tag;
diff --git a/src/main/java/com/github/dockerjava/api/model/Image.java b/src/main/java/com/github/dockerjava/api/model/Image.java
index 496db275e..78fee9f79 100644
--- a/src/main/java/com/github/dockerjava/api/model/Image.java
+++ b/src/main/java/com/github/dockerjava/api/model/Image.java
@@ -7,6 +7,8 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
*
* @author Konstantin Pelykh (kpelykh@gmail.com)
@@ -14,7 +16,8 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class Image {
+public class Image implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Created")
private Long created;
diff --git a/src/main/java/com/github/dockerjava/api/model/Info.java b/src/main/java/com/github/dockerjava/api/model/Info.java
index 7270eceb8..51abe5dac 100644
--- a/src/main/java/com/github/dockerjava/api/model/Info.java
+++ b/src/main/java/com/github/dockerjava/api/model/Info.java
@@ -9,6 +9,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.List;
import java.util.Map;
@@ -19,7 +20,8 @@
*/
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
-public class Info {
+public class Info implements Serializable {
+ private static final long serialVersionUID = 1L;
/**
* @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22}
diff --git a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java
index 956aaebe3..2c2be5cfd 100644
--- a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java
+++ b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java
@@ -7,6 +7,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.List;
import java.util.Map;
@@ -14,7 +15,9 @@
* @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20}
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public final class InfoRegistryConfig {
+public final class InfoRegistryConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
+
@JsonProperty("IndexConfigs")
private Map indexConfigs;
diff --git a/src/main/java/com/github/dockerjava/api/model/Link.java b/src/main/java/com/github/dockerjava/api/model/Link.java
index 89647306c..346aedcb0 100644
--- a/src/main/java/com/github/dockerjava/api/model/Link.java
+++ b/src/main/java/com/github/dockerjava/api/model/Link.java
@@ -3,12 +3,15 @@
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
+import java.io.Serializable;
+
/**
* Represents a network link between two Docker containers. The container with the name {@link #getName()} is made available in the target
* container with the aliased name {@link #getAlias()}. This involves creating an entry in /etc/hosts and some environment
* variables in the target container as well as creating a network bridge between both containers.
*/
-public class Link {
+public class Link implements Serializable {
+ private static final long serialVersionUID = 1L;
private final String name;
diff --git a/src/main/java/com/github/dockerjava/api/model/Links.java b/src/main/java/com/github/dockerjava/api/model/Links.java
index 2d678b3a3..1eb66ae42 100644
--- a/src/main/java/com/github/dockerjava/api/model/Links.java
+++ b/src/main/java/com/github/dockerjava/api/model/Links.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -20,7 +21,8 @@
@JsonSerialize(using = Links.Serializer.class)
@JsonDeserialize(using = Links.Deserializer.class)
-public class Links {
+public class Links implements Serializable {
+ private static final long serialVersionUID = 1L;
private final Link[] links;
diff --git a/src/main/java/com/github/dockerjava/api/model/LogConfig.java b/src/main/java/com/github/dockerjava/api/model/LogConfig.java
index f4fd0e958..e2a066101 100644
--- a/src/main/java/com/github/dockerjava/api/model/LogConfig.java
+++ b/src/main/java/com/github/dockerjava/api/model/LogConfig.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -26,7 +27,8 @@
* docker will ignore them. In most cases setting the config option to null will suffice. Consult the docker remote API for a more detailed
* and up-to-date explanation of the available types and their options.
*/
-public class LogConfig {
+public class LogConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Type")
public LoggingType type = null;
diff --git a/src/main/java/com/github/dockerjava/api/model/LxcConf.java b/src/main/java/com/github/dockerjava/api/model/LxcConf.java
index aeb854285..0a60086fb 100644
--- a/src/main/java/com/github/dockerjava/api/model/LxcConf.java
+++ b/src/main/java/com/github/dockerjava/api/model/LxcConf.java
@@ -4,8 +4,12 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
@JsonInclude(Include.NON_NULL)
-public class LxcConf {
+public class LxcConf implements Serializable {
+ private static final long serialVersionUID = 1L;
+
@JsonProperty("Key")
public String key;
diff --git a/src/main/java/com/github/dockerjava/api/model/Network.java b/src/main/java/com/github/dockerjava/api/model/Network.java
index 6f4114914..c0f9f36eb 100644
--- a/src/main/java/com/github/dockerjava/api/model/Network.java
+++ b/src/main/java/com/github/dockerjava/api/model/Network.java
@@ -5,6 +5,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang.builder.ToStringBuilder;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -12,7 +13,8 @@
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Network {
+public class Network implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Id")
private String id;
diff --git a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java
index 1d523bf4b..8fcd8fb9b 100644
--- a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java
+++ b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java
@@ -8,6 +8,7 @@
import com.github.dockerjava.core.RemoteApiVersion;
import org.apache.commons.lang.builder.ToStringBuilder;
+import java.io.Serializable;
import java.util.Map;
/**
@@ -16,7 +17,8 @@
*
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class NetworkSettings {
+public class NetworkSettings implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Bridge")
private String bridge;
diff --git a/src/main/java/com/github/dockerjava/api/model/Node.java b/src/main/java/com/github/dockerjava/api/model/Node.java
index 9e8580e0a..89b391c0a 100644
--- a/src/main/java/com/github/dockerjava/api/model/Node.java
+++ b/src/main/java/com/github/dockerjava/api/model/Node.java
@@ -4,11 +4,14 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
* A node as returned by the /events API, for instance, when Swarm is used.
*/
@JsonInclude(Include.NON_NULL)
-public class Node {
+public class Node implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Name")
private String name;
diff --git a/src/main/java/com/github/dockerjava/api/model/PortBinding.java b/src/main/java/com/github/dockerjava/api/model/PortBinding.java
index e163272d7..9a30b6cd2 100644
--- a/src/main/java/com/github/dockerjava/api/model/PortBinding.java
+++ b/src/main/java/com/github/dockerjava/api/model/PortBinding.java
@@ -6,6 +6,8 @@
import com.github.dockerjava.api.model.Ports.Binding;
+import java.io.Serializable;
+
/**
* In a {@link PortBinding}, a network socket on the Docker host, expressed as a {@link Binding}, is bound to an {@link ExposedPort} of a
* container. A {@link PortBinding} corresponds to the --publish (-p) option of the docker run (and
@@ -15,7 +17,9 @@
* existing port bindings from a container configuration in {@link NetworkSettings#getPorts()} and {@link HostConfig#getPortBindings()}. In
* that context, a Map<ExposedPort, Binding[]> is used.
*/
-public class PortBinding {
+public class PortBinding implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private final Binding binding;
private final ExposedPort exposedPort;
diff --git a/src/main/java/com/github/dockerjava/api/model/Ports.java b/src/main/java/com/github/dockerjava/api/model/Ports.java
index 904a31c4e..673852d9e 100644
--- a/src/main/java/com/github/dockerjava/api/model/Ports.java
+++ b/src/main/java/com/github/dockerjava/api/model/Ports.java
@@ -16,6 +16,7 @@
import org.apache.commons.lang.builder.EqualsBuilder;
import java.io.IOException;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -35,7 +36,8 @@
@SuppressWarnings(value = "checkstyle:equalshashcode")
@JsonDeserialize(using = Ports.Deserializer.class)
@JsonSerialize(using = Ports.Serializer.class)
-public class Ports {
+public class Ports implements Serializable {
+ private static final long serialVersionUID = 1L;
private final Map ports = new HashMap();
diff --git a/src/main/java/com/github/dockerjava/api/model/PropagationMode.java b/src/main/java/com/github/dockerjava/api/model/PropagationMode.java
new file mode 100644
index 000000000..9be7d6e43
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/api/model/PropagationMode.java
@@ -0,0 +1,50 @@
+package com.github.dockerjava.api.model;
+
+/**
+ * The propagation mode of a file system or file: shared, slave or private.
+ *
+ * @see https://github.com/docker/docker/pull/17034
+ * @since 1.22
+ */
+public enum PropagationMode {
+ /** default */
+ DEFAULT(""),
+
+ /** shared */
+ SHARED("shared"),
+
+ /** slave */
+ SLAVE("slave"),
+
+ /** private */
+ PRIVATE("private");
+
+ /**
+ * The default {@link PropagationMode}: {@link #DEFAULT}
+ */
+ public static final PropagationMode DEFAULT_MODE = DEFAULT;
+
+ private String value;
+
+ PropagationMode(String v) {
+ value = v;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ public static PropagationMode fromString(String v) {
+ switch (v) {
+ case "shared":
+ return SHARED;
+ case "slave":
+ return SLAVE;
+ case "private":
+ return PRIVATE;
+ default:
+ return DEFAULT;
+ }
+ }
+}
diff --git a/src/main/java/com/github/dockerjava/api/model/Repository.java b/src/main/java/com/github/dockerjava/api/model/Repository.java
index 1e814a1b5..f4e4b9ab8 100644
--- a/src/main/java/com/github/dockerjava/api/model/Repository.java
+++ b/src/main/java/com/github/dockerjava/api/model/Repository.java
@@ -1,5 +1,6 @@
package com.github.dockerjava.api.model;
+import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
@@ -8,7 +9,9 @@
/**
* A repository or image name.
*/
-public class Repository {
+public class Repository implements Serializable {
+ private static final long serialVersionUID = 1L;
+
public final String name;
/**
diff --git a/src/main/java/com/github/dockerjava/api/model/ResponseItem.java b/src/main/java/com/github/dockerjava/api/model/ResponseItem.java
index 12a090db8..6663b4bf0 100644
--- a/src/main/java/com/github/dockerjava/api/model/ResponseItem.java
+++ b/src/main/java/com/github/dockerjava/api/model/ResponseItem.java
@@ -15,7 +15,6 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseItem implements Serializable {
-
private static final long serialVersionUID = -5187169652557467828L;
@JsonProperty("stream")
diff --git a/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java
index ac6c4a318..1f77b8b9d 100644
--- a/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java
+++ b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java
@@ -7,6 +7,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
* Container restart policy
*
@@ -26,7 +28,8 @@
* @author Marcus Linke
*
*/
-public class RestartPolicy {
+public class RestartPolicy implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("MaximumRetryCount")
private Integer maximumRetryCount = 0;
diff --git a/src/main/java/com/github/dockerjava/api/model/SearchItem.java b/src/main/java/com/github/dockerjava/api/model/SearchItem.java
index 0a5843838..4e1663655 100644
--- a/src/main/java/com/github/dockerjava/api/model/SearchItem.java
+++ b/src/main/java/com/github/dockerjava/api/model/SearchItem.java
@@ -5,13 +5,16 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
*
* @author Konstantin Pelykh (kpelykh@gmail.com)
*
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class SearchItem {
+public class SearchItem implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("star_count")
private Integer starCount;
diff --git a/src/main/java/com/github/dockerjava/api/model/Statistics.java b/src/main/java/com/github/dockerjava/api/model/Statistics.java
index 21b9ca923..cf8c1b77e 100644
--- a/src/main/java/com/github/dockerjava/api/model/Statistics.java
+++ b/src/main/java/com/github/dockerjava/api/model/Statistics.java
@@ -1,5 +1,6 @@
package com.github.dockerjava.api.model;
+import java.io.Serializable;
import java.util.Map;
import javax.annotation.CheckForNull;
@@ -16,7 +17,8 @@
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
-public class Statistics {
+public class Statistics implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("read")
private String read;
diff --git a/src/main/java/com/github/dockerjava/api/model/Ulimit.java b/src/main/java/com/github/dockerjava/api/model/Ulimit.java
index 7427fb0cc..abcf298bd 100644
--- a/src/main/java/com/github/dockerjava/api/model/Ulimit.java
+++ b/src/main/java/com/github/dockerjava/api/model/Ulimit.java
@@ -7,10 +7,13 @@
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
* @author Vangie Du (duwan@live.com)
*/
-public class Ulimit {
+public class Ulimit implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("Name")
private String name;
diff --git a/src/main/java/com/github/dockerjava/api/model/Version.java b/src/main/java/com/github/dockerjava/api/model/Version.java
index 004c85f22..f08c411e2 100644
--- a/src/main/java/com/github/dockerjava/api/model/Version.java
+++ b/src/main/java/com/github/dockerjava/api/model/Version.java
@@ -8,6 +8,7 @@
import org.apache.commons.lang.builder.ToStringBuilder;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
/**
* Used for `/version`
@@ -16,7 +17,8 @@
* @see VersionCmd
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class Version {
+public class Version implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("ApiVersion")
private String apiVersion;
diff --git a/src/main/java/com/github/dockerjava/api/model/Volume.java b/src/main/java/com/github/dockerjava/api/model/Volume.java
index 655a8dbfc..46989f79c 100644
--- a/src/main/java/com/github/dockerjava/api/model/Volume.java
+++ b/src/main/java/com/github/dockerjava/api/model/Volume.java
@@ -3,12 +3,15 @@
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
+import java.io.Serializable;
+
/**
* Represents a bind mounted volume in a Docker container.
*
* @see Bind
*/
-public class Volume {
+public class Volume implements Serializable {
+ private static final long serialVersionUID = 1L;
private String path;
diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeBind.java b/src/main/java/com/github/dockerjava/api/model/VolumeBind.java
index cf9c077ab..f78fc587e 100644
--- a/src/main/java/com/github/dockerjava/api/model/VolumeBind.java
+++ b/src/main/java/com/github/dockerjava/api/model/VolumeBind.java
@@ -1,6 +1,10 @@
package com.github.dockerjava.api.model;
-public class VolumeBind {
+import java.io.Serializable;
+
+public class VolumeBind implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private final String hostPath;
private final String containerPath;
diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java b/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java
index d8303ec84..aeef19e9f 100644
--- a/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java
+++ b/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -22,7 +23,9 @@
// This is not going to be serialized
@JsonDeserialize(using = VolumeBinds.Deserializer.class)
@JsonSerialize(using = VolumeBinds.Serializer.class)
-public class VolumeBinds {
+public class VolumeBinds implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private final VolumeBind[] binds;
public VolumeBinds(VolumeBind... binds) {
diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeRW.java b/src/main/java/com/github/dockerjava/api/model/VolumeRW.java
index 7c4bdfb26..229cee3ed 100644
--- a/src/main/java/com/github/dockerjava/api/model/VolumeRW.java
+++ b/src/main/java/com/github/dockerjava/api/model/VolumeRW.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.Map.Entry;
import org.apache.commons.lang.builder.EqualsBuilder;
@@ -29,7 +30,8 @@
@JsonDeserialize(using = VolumeRW.Deserializer.class)
@JsonSerialize(using = VolumeRW.Serializer.class)
@Deprecated
-public class VolumeRW {
+public class VolumeRW implements Serializable {
+ private static final long serialVersionUID = 1L;
private Volume volume;
diff --git a/src/main/java/com/github/dockerjava/api/model/Volumes.java b/src/main/java/com/github/dockerjava/api/model/Volumes.java
index 46175548d..3246b0e8e 100644
--- a/src/main/java/com/github/dockerjava/api/model/Volumes.java
+++ b/src/main/java/com/github/dockerjava/api/model/Volumes.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -21,7 +22,8 @@
@JsonSerialize(using = Volumes.Serializer.class)
@JsonDeserialize(using = Volumes.Deserializer.class)
-public class Volumes {
+public class Volumes implements Serializable {
+ private static final long serialVersionUID = 1L;
private Volume[] volumes;
diff --git a/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java b/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java
index f027b6d71..fb52ff3f7 100644
--- a/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java
+++ b/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -19,7 +20,8 @@
@JsonSerialize(using = VolumesFrom.Serializer.class)
@JsonDeserialize(using = VolumesFrom.Deserializer.class)
-public class VolumesFrom {
+public class VolumesFrom implements Serializable {
+ private static final long serialVersionUID = 1L;
private String container;
diff --git a/src/main/java/com/github/dockerjava/api/model/VolumesRW.java b/src/main/java/com/github/dockerjava/api/model/VolumesRW.java
index f54f8242c..1b12bd13d 100644
--- a/src/main/java/com/github/dockerjava/api/model/VolumesRW.java
+++ b/src/main/java/com/github/dockerjava/api/model/VolumesRW.java
@@ -1,6 +1,7 @@
package com.github.dockerjava.api.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -22,7 +23,9 @@
// This is not going to be serialized
@JsonSerialize(using = VolumesRW.Serializer.class)
@JsonDeserialize(using = VolumesRW.Deserializer.class)
-public class VolumesRW {
+public class VolumesRW implements Serializable {
+ private static final long serialVersionUID = 1L;
+
private final VolumeRW[] volumesRW;
public VolumesRW(VolumeRW... binds) {
diff --git a/src/main/java/com/github/dockerjava/api/model/WaitResponse.java b/src/main/java/com/github/dockerjava/api/model/WaitResponse.java
index a2ab16f6f..0cab338b2 100644
--- a/src/main/java/com/github/dockerjava/api/model/WaitResponse.java
+++ b/src/main/java/com/github/dockerjava/api/model/WaitResponse.java
@@ -3,11 +3,14 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+
/**
* Represents a wait container command response
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public class WaitResponse {
+public class WaitResponse implements Serializable {
+ private static final long serialVersionUID = 1L;
@JsonProperty("StatusCode")
private Integer statusCode;
diff --git a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java
new file mode 100644
index 000000000..a9a15bb36
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java
@@ -0,0 +1,456 @@
+package com.github.dockerjava.core;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.commons.lang.BooleanUtils.isTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+import com.github.dockerjava.api.exception.DockerClientException;
+import com.github.dockerjava.api.model.AuthConfig;
+import com.github.dockerjava.api.model.AuthConfigurations;
+import com.github.dockerjava.core.NameParser.HostnameReposName;
+import com.github.dockerjava.core.NameParser.ReposTag;
+
+/**
+ * Respects some of the docker CLI options. See https://docs.docker.com/engine/reference/commandline/cli/#environment-variables
+ */
+public class DefaultDockerClientConfig implements Serializable, DockerClientConfig {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String DOCKER_HOST = "DOCKER_HOST";
+
+ public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY";
+
+ public static final String DOCKER_CONFIG = "DOCKER_CONFIG";
+
+ public static final String DOCKER_CERT_PATH = "DOCKER_CERT_PATH";
+
+ public static final String API_VERSION = "api.version";
+
+ public static final String REGISTRY_USERNAME = "registry.username";
+
+ public static final String REGISTRY_PASSWORD = "registry.password";
+
+ public static final String REGISTRY_EMAIL = "registry.email";
+
+ public static final String REGISTRY_URL = "registry.url";
+
+ private static final String DOCKER_JAVA_PROPERTIES = "docker-java.properties";
+
+ private static final String DOCKER_CFG = ".dockercfg";
+
+ private static final Set CONFIG_KEYS = new HashSet();
+
+ static {
+ CONFIG_KEYS.add(DOCKER_HOST);
+ CONFIG_KEYS.add(DOCKER_TLS_VERIFY);
+ CONFIG_KEYS.add(DOCKER_CONFIG);
+ CONFIG_KEYS.add(DOCKER_CERT_PATH);
+ CONFIG_KEYS.add(API_VERSION);
+ CONFIG_KEYS.add(REGISTRY_USERNAME);
+ CONFIG_KEYS.add(REGISTRY_PASSWORD);
+ CONFIG_KEYS.add(REGISTRY_EMAIL);
+ CONFIG_KEYS.add(REGISTRY_URL);
+ }
+
+ private final URI dockerHost;
+
+ private final String registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig;
+
+ private final SSLConfig sslConfig;
+
+ private final RemoteApiVersion apiVersion;
+
+ DefaultDockerClientConfig(URI dockerHost, String dockerConfig, String apiVersion, String registryUrl,
+ String registryUsername, String registryPassword, String registryEmail, SSLConfig sslConfig) {
+ this.dockerHost = checkDockerHostScheme(dockerHost);
+ this.dockerConfig = dockerConfig;
+ this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion);
+ this.sslConfig = sslConfig;
+ this.registryUsername = registryUsername;
+ this.registryPassword = registryPassword;
+ this.registryEmail = registryEmail;
+ this.registryUrl = registryUrl;
+ }
+
+ private URI checkDockerHostScheme(URI dockerHost) {
+ if ("tcp".equals(dockerHost.getScheme()) || "unix".equals(dockerHost.getScheme())) {
+ return dockerHost;
+ } else {
+ throw new DockerClientException("Unsupported protocol scheme found: '" + dockerHost
+ + "'. Only 'tcp://' or 'unix://' supported.");
+ }
+ }
+
+ private static Properties loadIncludedDockerProperties(Properties systemProperties) {
+ try (InputStream is = DefaultDockerClientConfig.class.getResourceAsStream("/" + DOCKER_JAVA_PROPERTIES)) {
+ Properties p = new Properties();
+ p.load(is);
+ replaceProperties(p, systemProperties);
+ return p;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void replaceProperties(Properties properties, Properties replacements) {
+ for (Object objectKey : properties.keySet()) {
+ String key = objectKey.toString();
+ properties.setProperty(key, replaceProperties(properties.getProperty(key), replacements));
+ }
+ }
+
+ private static String replaceProperties(String s, Properties replacements) {
+ for (Map.Entry
- *
- * Connector instances created via this connector provider use {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED chunked
- * encoding} as a default setting. This can be overridden by the
- * {@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING}. By default the
- * {@link org.glassfish.jersey.client.ClientProperties#CHUNKED_ENCODING_SIZE} property is only supported when using the default
- * {@code org.apache.http.conn.HttpClientConnectionManager} instance. If custom connection manager is used, then chunked encoding size can
- * be set by providing a custom {@code org.apache.http.HttpClientConnection} (via custom
- * {@code org.apache.http.impl.conn.ManagedHttpClientConnectionFactory}) and overriding it's {@code createOutputStream} method.
- *
- *
- * Use of authorization by the AHC-based connectors is dependent on the chunk encoding setting. If the entity buffering is enabled, the
- * entity is buffered and authorization can be performed automatically in response to a 401 by sending the request again. When entity
- * buffering is disabled (chunked encoding is used) then the property
- * {@link org.glassfish.jersey.apache.connector.ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION} must be set to {@code true}.
- *
- *
- * If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an entity is not read from the response then
- * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called after processing the response to release connection-based
- * resources.
- *
- *
- * If a response entity is obtained that is an instance of {@link java.io.Closeable} then the instance MUST be closed after processing the
- * entity to release connection-based resources.
- *
- *
- * The following methods are currently supported: HEAD, GET, POST, PUT, DELETE, OPTIONS, PATCH and TRACE.
- *
- *
- * @author Pavel Bucek (pavel.bucek at oracle.com)
- * @author Arul Dhesiaseelan (aruld at acm.org)
- * @author jorgeluisw at mac.com
- * @author Marek Potociar (marek.potociar at oracle.com)
- * @author Paul Sandoz (paul.sandoz at oracle.com)
- * @since 2.5
- */
-public class ApacheConnectorProvider implements ConnectorProvider {
-
- @Override
- public Connector getConnector(Client client, Configuration runtimeConfig) {
- return new ApacheConnector(runtimeConfig);
- }
-
- /**
- * Retrieve the underlying Apache {@link HttpClient} instance from {@link org.glassfish.jersey.client.JerseyClient} or
- * {@link org.glassfish.jersey.client.JerseyWebTarget} configured to use {@code ApacheConnectorProvider}.
- *
- * @param component
- * {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use {@code ApacheConnectorProvider}.
- * @return underlying Apache {@code HttpClient} instance.
- *
- * @throws java.lang.IllegalArgumentException
- * in case the {@code component} is neither {@code JerseyClient} nor {@code JerseyWebTarget} instance or in case the
- * component is not configured to use a {@code ApacheConnectorProvider}.
- * @since 2.8
- */
- public static HttpClient getHttpClient(Configurable> component) {
- if (!(component instanceof Initializable)) {
- throw new IllegalArgumentException(LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component
- .getClass().getName()));
- }
-
- final Initializable> initializable = (Initializable>) component;
- Connector connector = initializable.getConfiguration().getConnector();
- if (connector == null) {
- initializable.preInitialize();
- connector = initializable.getConfiguration().getConnector();
- }
-
- if (connector instanceof ApacheConnector) {
- return ((ApacheConnector) connector).getHttpClient();
- }
-
- throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
- }
-}
diff --git a/src/main/java/com/github/dockerjava/jaxrs/connector/README.txt b/src/main/java/com/github/dockerjava/jaxrs/connector/README.txt
deleted file mode 100644
index c3c1415f1..000000000
--- a/src/main/java/com/github/dockerjava/jaxrs/connector/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-This package exists as a workaround to https://java.net/jira/browse/JERSEY-2852.
-It introduces ApacheConnectorClientResponse which extends ClientResponse and closes
-the underlying CloseableHttpResponse when close() is called.
\ No newline at end of file
diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java b/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java
index afe0dce92..4ec74ddcc 100644
--- a/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java
+++ b/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java
@@ -53,9 +53,12 @@ public int available() throws IOException {
}
public void close() throws IOException {
+ if (closed) {
+ return;
+ }
closed = true;
- response.close();
delegate.close();
+ response.close();
}
public void mark(int readlimit) {
diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java
index 8f704c7af..25825d169 100644
--- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java
+++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java
@@ -1,589 +1,9 @@
package com.github.dockerjava.netty;
-import com.github.dockerjava.api.command.AttachContainerCmd;
-import com.github.dockerjava.api.command.AuthCmd;
-import com.github.dockerjava.api.command.BuildImageCmd;
-import com.github.dockerjava.api.command.CommitCmd;
-import com.github.dockerjava.api.command.ConnectToNetworkCmd;
-import com.github.dockerjava.api.command.ContainerDiffCmd;
-import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd;
-import com.github.dockerjava.api.command.CopyArchiveToContainerCmd;
-import com.github.dockerjava.api.command.CopyFileFromContainerCmd;
-import com.github.dockerjava.api.command.CreateContainerCmd;
-import com.github.dockerjava.api.command.CreateImageCmd;
-import com.github.dockerjava.api.command.CreateNetworkCmd;
-import com.github.dockerjava.api.command.CreateVolumeCmd;
-import com.github.dockerjava.api.command.DisconnectFromNetworkCmd;
-import com.github.dockerjava.api.command.DockerCmdExecFactory;
-import com.github.dockerjava.api.command.EventsCmd;
-import com.github.dockerjava.api.command.ExecCreateCmd;
-import com.github.dockerjava.api.command.ExecStartCmd;
-import com.github.dockerjava.api.command.InfoCmd;
-import com.github.dockerjava.api.command.InspectContainerCmd;
-import com.github.dockerjava.api.command.InspectExecCmd;
-import com.github.dockerjava.api.command.InspectImageCmd;
-import com.github.dockerjava.api.command.InspectNetworkCmd;
-import com.github.dockerjava.api.command.InspectVolumeCmd;
-import com.github.dockerjava.api.command.KillContainerCmd;
-import com.github.dockerjava.api.command.ListContainersCmd;
-import com.github.dockerjava.api.command.ListImagesCmd;
-import com.github.dockerjava.api.command.ListNetworksCmd;
-import com.github.dockerjava.api.command.ListVolumesCmd;
-import com.github.dockerjava.api.command.LogContainerCmd;
-import com.github.dockerjava.api.command.PauseContainerCmd;
-import com.github.dockerjava.api.command.PingCmd;
-import com.github.dockerjava.api.command.PullImageCmd;
-import com.github.dockerjava.api.command.PushImageCmd;
-import com.github.dockerjava.api.command.RemoveContainerCmd;
-import com.github.dockerjava.api.command.RemoveImageCmd;
-import com.github.dockerjava.api.command.RemoveNetworkCmd;
-import com.github.dockerjava.api.command.RemoveVolumeCmd;
-import com.github.dockerjava.api.command.RestartContainerCmd;
-import com.github.dockerjava.api.command.SaveImageCmd;
-import com.github.dockerjava.api.command.SearchImagesCmd;
-import com.github.dockerjava.api.command.StartContainerCmd;
-import com.github.dockerjava.api.command.StatsCmd;
-import com.github.dockerjava.api.command.StopContainerCmd;
-import com.github.dockerjava.api.command.TagImageCmd;
-import com.github.dockerjava.api.command.TopContainerCmd;
-import com.github.dockerjava.api.command.UnpauseContainerCmd;
-import com.github.dockerjava.api.command.UpdateContainerCmd;
-import com.github.dockerjava.api.command.VersionCmd;
-import com.github.dockerjava.api.command.WaitContainerCmd;
-import com.github.dockerjava.api.command.RenameContainerCmd;
-import com.github.dockerjava.core.DockerClientConfig;
-import com.github.dockerjava.core.DockerClientImpl;
-import com.github.dockerjava.core.LocalDirectorySSLConfig;
-import com.github.dockerjava.netty.exec.AttachContainerCmdExec;
-import com.github.dockerjava.netty.exec.AuthCmdExec;
-import com.github.dockerjava.netty.exec.BuildImageCmdExec;
-import com.github.dockerjava.netty.exec.CommitCmdExec;
-import com.github.dockerjava.netty.exec.ConnectToNetworkCmdExec;
-import com.github.dockerjava.netty.exec.ContainerDiffCmdExec;
-import com.github.dockerjava.netty.exec.CopyArchiveFromContainerCmdExec;
-import com.github.dockerjava.netty.exec.CopyArchiveToContainerCmdExec;
-import com.github.dockerjava.netty.exec.CopyFileFromContainerCmdExec;
-import com.github.dockerjava.netty.exec.CreateContainerCmdExec;
-import com.github.dockerjava.netty.exec.CreateImageCmdExec;
-import com.github.dockerjava.netty.exec.CreateNetworkCmdExec;
-import com.github.dockerjava.netty.exec.CreateVolumeCmdExec;
-import com.github.dockerjava.netty.exec.DisconnectFromNetworkCmdExec;
-import com.github.dockerjava.netty.exec.EventsCmdExec;
-import com.github.dockerjava.netty.exec.ExecCreateCmdExec;
-import com.github.dockerjava.netty.exec.ExecStartCmdExec;
-import com.github.dockerjava.netty.exec.InfoCmdExec;
-import com.github.dockerjava.netty.exec.InspectContainerCmdExec;
-import com.github.dockerjava.netty.exec.InspectExecCmdExec;
-import com.github.dockerjava.netty.exec.InspectImageCmdExec;
-import com.github.dockerjava.netty.exec.InspectNetworkCmdExec;
-import com.github.dockerjava.netty.exec.InspectVolumeCmdExec;
-import com.github.dockerjava.netty.exec.KillContainerCmdExec;
-import com.github.dockerjava.netty.exec.ListContainersCmdExec;
-import com.github.dockerjava.netty.exec.ListImagesCmdExec;
-import com.github.dockerjava.netty.exec.ListNetworksCmdExec;
-import com.github.dockerjava.netty.exec.ListVolumesCmdExec;
-import com.github.dockerjava.netty.exec.LogContainerCmdExec;
-import com.github.dockerjava.netty.exec.PauseContainerCmdExec;
-import com.github.dockerjava.netty.exec.PingCmdExec;
-import com.github.dockerjava.netty.exec.PullImageCmdExec;
-import com.github.dockerjava.netty.exec.PushImageCmdExec;
-import com.github.dockerjava.netty.exec.RemoveContainerCmdExec;
-import com.github.dockerjava.netty.exec.RemoveImageCmdExec;
-import com.github.dockerjava.netty.exec.RemoveNetworkCmdExec;
-import com.github.dockerjava.netty.exec.RemoveVolumeCmdExec;
-import com.github.dockerjava.netty.exec.RestartContainerCmdExec;
-import com.github.dockerjava.netty.exec.SaveImageCmdExec;
-import com.github.dockerjava.netty.exec.SearchImagesCmdExec;
-import com.github.dockerjava.netty.exec.StartContainerCmdExec;
-import com.github.dockerjava.netty.exec.StatsCmdExec;
-import com.github.dockerjava.netty.exec.StopContainerCmdExec;
-import com.github.dockerjava.netty.exec.TagImageCmdExec;
-import com.github.dockerjava.netty.exec.TopContainerCmdExec;
-import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec;
-import com.github.dockerjava.netty.exec.UpdateContainerCmdExec;
-import com.github.dockerjava.netty.exec.VersionCmdExec;
-import com.github.dockerjava.netty.exec.WaitContainerCmdExec;
-import com.github.dockerjava.netty.exec.RenameContainerCmdExec;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.epoll.EpollDomainSocketChannel;
-import io.netty.channel.epoll.EpollEventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.DuplexChannel;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.channel.unix.DomainSocketAddress;
-import io.netty.channel.unix.UnixChannel;
-import io.netty.handler.codec.http.HttpClientCodec;
-import io.netty.handler.logging.LoggingHandler;
-import io.netty.handler.ssl.SslHandler;
-import io.netty.util.concurrent.DefaultThreadFactory;
-
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLParameters;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.security.Security;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
/**
- * Experimental implementation of {@link DockerCmdExecFactory} that supports http connection hijacking that is needed to pass STDIN to the
- * container.
- *
- * To use it just pass an instance via {@link DockerClientImpl#withDockerCmdExecFactory(DockerCmdExecFactory)}
- *
- * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#attach-to-a-container
- * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#exec-start
- *
- *
- * @author Marcus Linke
+ * @author Kanstantsin Shautsou
+ * @deprecated old clashing name
*/
-public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory {
-
- private static String threadPrefix = "dockerjava-netty";
-
- /*
- * useful links:
- *
- * http://stackoverflow.com/questions/33296749/netty-connect-to-unix-domain-socket-failed
- * http://netty.io/wiki/native-transports.html
- * https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java
- * https://github.com/slandelle/netty-request-chunking/blob/master/src/test/java/slandelle/ChunkingTest.java
- */
-
- private DockerClientConfig dockerClientConfig;
-
- private Bootstrap bootstrap;
-
- private EventLoopGroup eventLoopGroup;
-
- private NettyInitializer nettyInitializer;
-
- private SSLContext sslContext = null;
-
- private ChannelProvider channelProvider = new ChannelProvider() {
- @Override
- public DuplexChannel getChannel() {
- DuplexChannel channel = connect();
- channel.pipeline().addLast(new LoggingHandler(getClass()));
- return channel;
- }
- };
-
- @Override
- public void init(DockerClientConfig dockerClientConfig) {
- checkNotNull(dockerClientConfig, "config was not specified");
- this.dockerClientConfig = dockerClientConfig;
-
- bootstrap = new Bootstrap();
-
- String scheme = dockerClientConfig.getDockerHost().getScheme();
-
- if ("unix".equals(scheme)) {
- nettyInitializer = new UnixDomainSocketInitializer();
- } else if ("tcp".equals(scheme)) {
- nettyInitializer = new InetSocketInitializer();
- }
-
- eventLoopGroup = nettyInitializer.init(bootstrap, dockerClientConfig);
- }
-
- private DuplexChannel connect() {
- try {
- return connect(bootstrap);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- private DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException {
- return nettyInitializer.connect(bootstrap);
- }
-
- private interface NettyInitializer {
- EventLoopGroup init(final Bootstrap bootstrap, DockerClientConfig dockerClientConfig);
-
- DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException;
- }
-
- private class UnixDomainSocketInitializer implements NettyInitializer {
- @Override
- public EventLoopGroup init(Bootstrap bootstrap, DockerClientConfig dockerClientConfig) {
- EventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(0, new DefaultThreadFactory(threadPrefix));
- bootstrap.group(epollEventLoopGroup).channel(EpollDomainSocketChannel.class)
- .handler(new ChannelInitializer() {
- @Override
- protected void initChannel(final UnixChannel channel) throws Exception {
- channel.pipeline().addLast(new HttpClientCodec());
- }
- });
- return epollEventLoopGroup;
- }
-
- @Override
- public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException {
- return (DuplexChannel) bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel();
- }
- }
-
- private class InetSocketInitializer implements NettyInitializer {
- @Override
- public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerClientConfig) {
- EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(0, new DefaultThreadFactory(threadPrefix));
-
- InetAddress addr = InetAddress.getLoopbackAddress();
-
- final SocketAddress proxyAddress = new InetSocketAddress(addr, 8008);
-
- Security.addProvider(new BouncyCastleProvider());
-
- bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class)
- .handler(new ChannelInitializer() {
- @Override
- protected void initChannel(final SocketChannel channel) throws Exception {
- // channel.pipeline().addLast(new
- // HttpProxyHandler(proxyAddress));
- channel.pipeline().addLast(new HttpClientCodec());
- }
- });
-
- return nioEventLoopGroup;
- }
-
- @Override
- public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException {
- String host = dockerClientConfig.getDockerHost().getHost();
- int port = dockerClientConfig.getDockerHost().getPort();
-
- if (port == -1) {
- throw new RuntimeException("no port configured for " + host);
- }
-
- DuplexChannel channel = (DuplexChannel) bootstrap.connect(host, port).sync().channel();
-
- if (dockerClientConfig.getDockerTlsVerify()) {
- final SslHandler ssl = initSsl(dockerClientConfig);
-
- if (ssl != null) {
- channel.pipeline().addFirst(ssl);
- }
- }
-
- return channel;
- }
-
- private SslHandler initSsl(DockerClientConfig dockerClientConfig) {
- SslHandler ssl = null;
-
- try {
- String host = dockerClientConfig.getDockerHost().getHost();
- int port = dockerClientConfig.getDockerHost().getPort();
-
- if (sslContext == null) {
- sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext();
- }
-
- SSLEngine engine = sslContext.createSSLEngine(host, port);
- engine.setUseClientMode(true);
- engine.setSSLParameters(enableHostNameVerification(engine.getSSLParameters()));
-
- // in the future we may use HostnameVerifier like here:
- // https://github.com/AsyncHttpClient/async-http-client/blob/1.8.x/src/main/java/com/ning/http/client/providers/netty/NettyConnectListener.java#L76
-
- ssl = new SslHandler(engine);
-
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- return ssl;
- }
- }
-
- protected DockerClientConfig getDockerClientConfig() {
- checkNotNull(dockerClientConfig,
- "Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!");
- return dockerClientConfig;
- }
-
- public SSLParameters enableHostNameVerification(SSLParameters sslParameters) {
- sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
- return sslParameters;
- }
-
- @Override
- public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec() {
- return new CopyArchiveFromContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec() {
- return new CopyArchiveToContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public AuthCmd.Exec createAuthCmdExec() {
- return new AuthCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public InfoCmd.Exec createInfoCmdExec() {
- return new InfoCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public PingCmd.Exec createPingCmdExec() {
- return new PingCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public VersionCmd.Exec createVersionCmdExec() {
- return new VersionCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public PullImageCmd.Exec createPullImageCmdExec() {
- return new PullImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public PushImageCmd.Exec createPushImageCmdExec() {
- return new PushImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public SaveImageCmd.Exec createSaveImageCmdExec() {
- return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CreateImageCmd.Exec createCreateImageCmdExec() {
- return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public SearchImagesCmd.Exec createSearchImagesCmdExec() {
- return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public RemoveImageCmd.Exec createRemoveImageCmdExec() {
- return new RemoveImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ListImagesCmd.Exec createListImagesCmdExec() {
- return new ListImagesCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public InspectImageCmd.Exec createInspectImageCmdExec() {
- return new InspectImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ListContainersCmd.Exec createListContainersCmdExec() {
- return new ListContainersCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CreateContainerCmd.Exec createCreateContainerCmdExec() {
- return new CreateContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public StartContainerCmd.Exec createStartContainerCmdExec() {
- return new StartContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public InspectContainerCmd.Exec createInspectContainerCmdExec() {
- return new InspectContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ExecCreateCmd.Exec createExecCmdExec() {
- return new ExecCreateCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public RemoveContainerCmd.Exec createRemoveContainerCmdExec() {
- return new RemoveContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public WaitContainerCmd.Exec createWaitContainerCmdExec() {
- return new WaitContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public AttachContainerCmd.Exec createAttachContainerCmdExec() {
- return new AttachContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ExecStartCmd.Exec createExecStartCmdExec() {
- return new ExecStartCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public InspectExecCmd.Exec createInspectExecCmdExec() {
- return new InspectExecCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public LogContainerCmd.Exec createLogContainerCmdExec() {
- return new LogContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() {
- return new CopyFileFromContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public StopContainerCmd.Exec createStopContainerCmdExec() {
- return new StopContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ContainerDiffCmd.Exec createContainerDiffCmdExec() {
- return new ContainerDiffCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public KillContainerCmd.Exec createKillContainerCmdExec() {
- return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public UpdateContainerCmd.Exec createUpdateContainerCmdExec() {
- return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public RenameContainerCmd.Exec createRenameContainerCmdExec() {
- return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public RestartContainerCmd.Exec createRestartContainerCmdExec() {
- return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CommitCmd.Exec createCommitCmdExec() {
- return new CommitCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public BuildImageCmd.Exec createBuildImageCmdExec() {
- return new BuildImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public TopContainerCmd.Exec createTopContainerCmdExec() {
- return new TopContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public TagImageCmd.Exec createTagImageCmdExec() {
- return new TagImageCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public PauseContainerCmd.Exec createPauseContainerCmdExec() {
- return new PauseContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() {
- return new UnpauseContainerCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public EventsCmd.Exec createEventsCmdExec() {
- return new EventsCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public StatsCmd.Exec createStatsCmdExec() {
- return new StatsCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CreateVolumeCmd.Exec createCreateVolumeCmdExec() {
- return new CreateVolumeCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public InspectVolumeCmd.Exec createInspectVolumeCmdExec() {
- return new InspectVolumeCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec() {
- return new RemoveVolumeCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ListVolumesCmd.Exec createListVolumesCmdExec() {
- return new ListVolumesCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ListNetworksCmd.Exec createListNetworksCmdExec() {
- return new ListNetworksCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public InspectNetworkCmd.Exec createInspectNetworkCmdExec() {
- return new InspectNetworkCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public CreateNetworkCmd.Exec createCreateNetworkCmdExec() {
- return new CreateNetworkCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec() {
- return new RemoveNetworkCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec() {
- return new ConnectToNetworkCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() {
- return new DisconnectFromNetworkCmdExec(getBaseResource(), getDockerClientConfig());
- }
-
- @Override
- public void close() throws IOException {
- checkNotNull(eventLoopGroup, "Factory not initialized. You probably forgot to call init()!");
-
- eventLoopGroup.shutdownGracefully();
- }
-
- @Override
- public DockerCmdExecFactory withSSLContext(SSLContext sslContext) {
- this.sslContext = sslContext;
- return this;
- }
-
- private WebTarget getBaseResource() {
- return new WebTarget(channelProvider);
- }
+@Deprecated
+public class DockerCmdExecFactoryImpl extends NettyDockerCmdExecFactory {
}
diff --git a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java
index 9669d6818..26b950e4e 100644
--- a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java
+++ b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java
@@ -27,6 +27,7 @@
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.CountDownLatch;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
@@ -69,6 +70,63 @@ public void onNext(T object) {
}
}
+ public class SkipResultCallback extends ResultCallbackTemplate, Void> {
+ @Override
+ public void onNext(Void object) {
+ }
+ }
+
+ /**
+ * Implementation of {@link ResultCallback} with the single result event expected.
+ */
+ public static class AsyncResultCallback
+ extends ResultCallbackTemplate, A_RES_T> {
+
+ private A_RES_T result = null;
+
+ private final CountDownLatch resultReady = new CountDownLatch(1);
+
+ @Override
+ public void onNext(A_RES_T object) {
+ onResult(object);
+ }
+
+ private void onResult(A_RES_T object) {
+ if (resultReady.getCount() == 0) {
+ throw new IllegalStateException("Result has already been set");
+ }
+
+ try {
+ result = object;
+ } finally {
+ resultReady.countDown();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ super.close();
+ } finally {
+ resultReady.countDown();
+ }
+ }
+
+ /**
+ * Blocks until {@link ResultCallback#onNext(Object)} was called for the first time
+ */
+ @SuppressWarnings("unchecked")
+ public A_RES_T awaitResult() {
+ try {
+ resultReady.await();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ getFirstError();
+ return result;
+ }
+ }
+
private ChannelProvider channelProvider;
private String resource;
@@ -197,7 +255,7 @@ public InputStream post(final Object entity) {
Channel channel = getChannel();
- ResponseCallback callback = new ResponseCallback();
+ AsyncResultCallback callback = new AsyncResultCallback<>();
HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, callback);
HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback);
@@ -401,6 +459,31 @@ public void post(TypeReference typeReference, ResultCallback resultCal
channel.pipeline().addLast(new JsonObjectDecoder());
channel.pipeline().addLast(jsonResponseHandler);
+ postChunkedStreamRequest(requestProvider, channel, body);
+ }
+
+ public void postStream(InputStream body) {
+ SkipResultCallback resultCallback = new SkipResultCallback();
+
+ HttpRequestProvider requestProvider = httpPostRequestProvider(null);
+
+ Channel channel = getChannel();
+
+ HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, resultCallback);
+
+ channel.pipeline().addLast(new ChunkedWriteHandler());
+ channel.pipeline().addLast(responseHandler);
+
+ postChunkedStreamRequest(requestProvider, channel, body);
+
+ try {
+ resultCallback.awaitCompletion();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void postChunkedStreamRequest(HttpRequestProvider requestProvider, Channel channel, InputStream body) {
HttpRequest request = requestProvider.getHttpRequest(resource);
// don't accept FullHttpRequest here
@@ -423,7 +506,7 @@ public InputStream get() {
Channel channel = getChannel();
- ResponseCallback resultCallback = new ResponseCallback();
+ AsyncResultCallback resultCallback = new AsyncResultCallback<>();
HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, resultCallback);
diff --git a/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java
new file mode 100644
index 000000000..c91d4af21
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java
@@ -0,0 +1,624 @@
+package com.github.dockerjava.netty;
+
+import com.github.dockerjava.api.command.AttachContainerCmd;
+import com.github.dockerjava.api.command.AuthCmd;
+import com.github.dockerjava.api.command.BuildImageCmd;
+import com.github.dockerjava.api.command.CommitCmd;
+import com.github.dockerjava.api.command.ConnectToNetworkCmd;
+import com.github.dockerjava.api.command.ContainerDiffCmd;
+import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd;
+import com.github.dockerjava.api.command.CopyArchiveToContainerCmd;
+import com.github.dockerjava.api.command.CopyFileFromContainerCmd;
+import com.github.dockerjava.api.command.CreateContainerCmd;
+import com.github.dockerjava.api.command.CreateImageCmd;
+import com.github.dockerjava.api.command.CreateNetworkCmd;
+import com.github.dockerjava.api.command.CreateVolumeCmd;
+import com.github.dockerjava.api.command.DisconnectFromNetworkCmd;
+import com.github.dockerjava.api.command.DockerCmdExecFactory;
+import com.github.dockerjava.api.command.EventsCmd;
+import com.github.dockerjava.api.command.ExecCreateCmd;
+import com.github.dockerjava.api.command.ExecStartCmd;
+import com.github.dockerjava.api.command.InfoCmd;
+import com.github.dockerjava.api.command.InspectContainerCmd;
+import com.github.dockerjava.api.command.InspectExecCmd;
+import com.github.dockerjava.api.command.InspectImageCmd;
+import com.github.dockerjava.api.command.InspectNetworkCmd;
+import com.github.dockerjava.api.command.InspectVolumeCmd;
+import com.github.dockerjava.api.command.KillContainerCmd;
+import com.github.dockerjava.api.command.ListContainersCmd;
+import com.github.dockerjava.api.command.ListImagesCmd;
+import com.github.dockerjava.api.command.ListNetworksCmd;
+import com.github.dockerjava.api.command.ListVolumesCmd;
+import com.github.dockerjava.api.command.LoadImageCmd;
+import com.github.dockerjava.api.command.LogContainerCmd;
+import com.github.dockerjava.api.command.PauseContainerCmd;
+import com.github.dockerjava.api.command.PingCmd;
+import com.github.dockerjava.api.command.PullImageCmd;
+import com.github.dockerjava.api.command.PushImageCmd;
+import com.github.dockerjava.api.command.RemoveContainerCmd;
+import com.github.dockerjava.api.command.RemoveImageCmd;
+import com.github.dockerjava.api.command.RemoveNetworkCmd;
+import com.github.dockerjava.api.command.RemoveVolumeCmd;
+import com.github.dockerjava.api.command.RestartContainerCmd;
+import com.github.dockerjava.api.command.SaveImageCmd;
+import com.github.dockerjava.api.command.SearchImagesCmd;
+import com.github.dockerjava.api.command.StartContainerCmd;
+import com.github.dockerjava.api.command.StatsCmd;
+import com.github.dockerjava.api.command.StopContainerCmd;
+import com.github.dockerjava.api.command.TagImageCmd;
+import com.github.dockerjava.api.command.TopContainerCmd;
+import com.github.dockerjava.api.command.UnpauseContainerCmd;
+import com.github.dockerjava.api.command.UpdateContainerCmd;
+import com.github.dockerjava.api.command.VersionCmd;
+import com.github.dockerjava.api.command.WaitContainerCmd;
+import com.github.dockerjava.api.command.RenameContainerCmd;
+import com.github.dockerjava.core.DockerClientConfig;
+import com.github.dockerjava.core.DockerClientImpl;
+import com.github.dockerjava.core.SSLConfig;
+import com.github.dockerjava.netty.exec.AttachContainerCmdExec;
+import com.github.dockerjava.netty.exec.AuthCmdExec;
+import com.github.dockerjava.netty.exec.BuildImageCmdExec;
+import com.github.dockerjava.netty.exec.CommitCmdExec;
+import com.github.dockerjava.netty.exec.ConnectToNetworkCmdExec;
+import com.github.dockerjava.netty.exec.ContainerDiffCmdExec;
+import com.github.dockerjava.netty.exec.CopyArchiveFromContainerCmdExec;
+import com.github.dockerjava.netty.exec.CopyArchiveToContainerCmdExec;
+import com.github.dockerjava.netty.exec.CopyFileFromContainerCmdExec;
+import com.github.dockerjava.netty.exec.CreateContainerCmdExec;
+import com.github.dockerjava.netty.exec.CreateImageCmdExec;
+import com.github.dockerjava.netty.exec.CreateNetworkCmdExec;
+import com.github.dockerjava.netty.exec.CreateVolumeCmdExec;
+import com.github.dockerjava.netty.exec.DisconnectFromNetworkCmdExec;
+import com.github.dockerjava.netty.exec.EventsCmdExec;
+import com.github.dockerjava.netty.exec.ExecCreateCmdExec;
+import com.github.dockerjava.netty.exec.ExecStartCmdExec;
+import com.github.dockerjava.netty.exec.InfoCmdExec;
+import com.github.dockerjava.netty.exec.InspectContainerCmdExec;
+import com.github.dockerjava.netty.exec.InspectExecCmdExec;
+import com.github.dockerjava.netty.exec.InspectImageCmdExec;
+import com.github.dockerjava.netty.exec.InspectNetworkCmdExec;
+import com.github.dockerjava.netty.exec.InspectVolumeCmdExec;
+import com.github.dockerjava.netty.exec.KillContainerCmdExec;
+import com.github.dockerjava.netty.exec.ListContainersCmdExec;
+import com.github.dockerjava.netty.exec.ListImagesCmdExec;
+import com.github.dockerjava.netty.exec.ListNetworksCmdExec;
+import com.github.dockerjava.netty.exec.ListVolumesCmdExec;
+import com.github.dockerjava.netty.exec.LoadImageCmdExec;
+import com.github.dockerjava.netty.exec.LogContainerCmdExec;
+import com.github.dockerjava.netty.exec.PauseContainerCmdExec;
+import com.github.dockerjava.netty.exec.PingCmdExec;
+import com.github.dockerjava.netty.exec.PullImageCmdExec;
+import com.github.dockerjava.netty.exec.PushImageCmdExec;
+import com.github.dockerjava.netty.exec.RemoveContainerCmdExec;
+import com.github.dockerjava.netty.exec.RemoveImageCmdExec;
+import com.github.dockerjava.netty.exec.RemoveNetworkCmdExec;
+import com.github.dockerjava.netty.exec.RemoveVolumeCmdExec;
+import com.github.dockerjava.netty.exec.RestartContainerCmdExec;
+import com.github.dockerjava.netty.exec.SaveImageCmdExec;
+import com.github.dockerjava.netty.exec.SearchImagesCmdExec;
+import com.github.dockerjava.netty.exec.StartContainerCmdExec;
+import com.github.dockerjava.netty.exec.StatsCmdExec;
+import com.github.dockerjava.netty.exec.StopContainerCmdExec;
+import com.github.dockerjava.netty.exec.TagImageCmdExec;
+import com.github.dockerjava.netty.exec.TopContainerCmdExec;
+import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec;
+import com.github.dockerjava.netty.exec.UpdateContainerCmdExec;
+import com.github.dockerjava.netty.exec.VersionCmdExec;
+import com.github.dockerjava.netty.exec.WaitContainerCmdExec;
+import com.github.dockerjava.netty.exec.RenameContainerCmdExec;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelConfig;
+import io.netty.channel.ChannelFactory;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.EpollDomainSocketChannel;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.DuplexChannel;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.channel.unix.DomainSocketAddress;
+import io.netty.channel.unix.UnixChannel;
+import io.netty.handler.codec.http.HttpClientCodec;
+import io.netty.handler.logging.LoggingHandler;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.util.concurrent.DefaultThreadFactory;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.security.Security;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Experimental implementation of {@link DockerCmdExecFactory} that supports http connection hijacking that is needed to pass STDIN to the
+ * container.
+ *
+ * To use it just pass an instance via {@link DockerClientImpl#withDockerCmdExecFactory(DockerCmdExecFactory)}
+ *
+ * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#attach-to-a-container
+ * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#exec-start
+ *
+ *
+ * @author Marcus Linke
+ */
+public class NettyDockerCmdExecFactory implements DockerCmdExecFactory {
+
+ private static String threadPrefix = "dockerjava-netty";
+
+ /*
+ * useful links:
+ *
+ * http://stackoverflow.com/questions/33296749/netty-connect-to-unix-domain-socket-failed
+ * http://netty.io/wiki/native-transports.html
+ * https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java
+ * https://github.com/slandelle/netty-request-chunking/blob/master/src/test/java/slandelle/ChunkingTest.java
+ */
+
+ private DockerClientConfig dockerClientConfig;
+
+ private Bootstrap bootstrap;
+
+ private EventLoopGroup eventLoopGroup;
+
+ private NettyInitializer nettyInitializer;
+
+ private ChannelProvider channelProvider = new ChannelProvider() {
+ @Override
+ public DuplexChannel getChannel() {
+ DuplexChannel channel = connect();
+ channel.pipeline().addLast(new LoggingHandler(getClass()));
+ return channel;
+ }
+ };
+
+ private Integer connectTimeout = null;
+
+ @Override
+ public void init(DockerClientConfig dockerClientConfig) {
+ checkNotNull(dockerClientConfig, "config was not specified");
+ this.dockerClientConfig = dockerClientConfig;
+
+ bootstrap = new Bootstrap();
+
+ String scheme = dockerClientConfig.getDockerHost().getScheme();
+
+ if ("unix".equals(scheme)) {
+ nettyInitializer = new UnixDomainSocketInitializer();
+ } else if ("tcp".equals(scheme)) {
+ nettyInitializer = new InetSocketInitializer();
+ }
+
+ eventLoopGroup = nettyInitializer.init(bootstrap, dockerClientConfig);
+ }
+
+ private DuplexChannel connect() {
+ try {
+ return connect(bootstrap);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException {
+ return nettyInitializer.connect(bootstrap);
+ }
+
+ private interface NettyInitializer {
+ EventLoopGroup init(final Bootstrap bootstrap, DockerClientConfig dockerClientConfig);
+
+ DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException;
+ }
+
+ private class UnixDomainSocketInitializer implements NettyInitializer {
+ @Override
+ public EventLoopGroup init(Bootstrap bootstrap, DockerClientConfig dockerClientConfig) {
+ EventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(0, new DefaultThreadFactory(threadPrefix));
+
+ ChannelFactory factory = new ChannelFactory() {
+ @Override
+ public EpollDomainSocketChannel newChannel() {
+ return configure(new EpollDomainSocketChannel());
+ }
+ };
+
+ bootstrap.group(epollEventLoopGroup).channelFactory(factory)
+ .handler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(final UnixChannel channel) throws Exception {
+ channel.pipeline().addLast(new HttpClientCodec());
+ }
+ });
+ return epollEventLoopGroup;
+ }
+
+ @Override
+ public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException {
+ return (DuplexChannel) bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel();
+ }
+ }
+
+ private class InetSocketInitializer implements NettyInitializer {
+ @Override
+ public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerClientConfig) {
+ EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(0, new DefaultThreadFactory(threadPrefix));
+
+ InetAddress addr = InetAddress.getLoopbackAddress();
+
+ final SocketAddress proxyAddress = new InetSocketAddress(addr, 8008);
+
+ Security.addProvider(new BouncyCastleProvider());
+
+ ChannelFactory factory = new ChannelFactory() {
+ @Override
+ public NioSocketChannel newChannel() {
+ return configure(new NioSocketChannel());
+ }
+ };
+
+ bootstrap.group(nioEventLoopGroup).channelFactory(factory)
+ .handler(new ChannelInitializer() {
+ @Override
+ protected void initChannel(final SocketChannel channel) throws Exception {
+ // channel.pipeline().addLast(new
+ // HttpProxyHandler(proxyAddress));
+ channel.pipeline().addLast(new HttpClientCodec());
+ }
+ });
+
+ return nioEventLoopGroup;
+ }
+
+ @Override
+ public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException {
+ String host = dockerClientConfig.getDockerHost().getHost();
+ int port = dockerClientConfig.getDockerHost().getPort();
+
+ if (port == -1) {
+ throw new RuntimeException("no port configured for " + host);
+ }
+
+ DuplexChannel channel = (DuplexChannel) bootstrap.connect(host, port).sync().channel();
+
+ final SslHandler ssl = initSsl(dockerClientConfig);
+
+ if (ssl != null) {
+ channel.pipeline().addFirst(ssl);
+ }
+
+ return channel;
+ }
+
+ private SslHandler initSsl(DockerClientConfig dockerClientConfig) {
+ SslHandler ssl = null;
+
+ try {
+ String host = dockerClientConfig.getDockerHost().getHost();
+ int port = dockerClientConfig.getDockerHost().getPort();
+
+ final SSLConfig sslConfig = dockerClientConfig.getSSLConfig();
+
+ if (sslConfig != null && sslConfig.getSSLContext() != null) {
+
+ SSLEngine engine = sslConfig.getSSLContext().createSSLEngine(host, port);
+ engine.setUseClientMode(true);
+ engine.setSSLParameters(enableHostNameVerification(engine.getSSLParameters()));
+
+ // in the future we may use HostnameVerifier like here:
+ // https://github.com/AsyncHttpClient/async-http-client/blob/1.8.x/src/main/java/com/ning/http/client/providers/netty/NettyConnectListener.java#L76
+
+ ssl = new SslHandler(engine);
+ }
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return ssl;
+ }
+ }
+
+ protected DockerClientConfig getDockerClientConfig() {
+ checkNotNull(dockerClientConfig,
+ "Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!");
+ return dockerClientConfig;
+ }
+
+ public SSLParameters enableHostNameVerification(SSLParameters sslParameters) {
+ sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+ return sslParameters;
+ }
+
+ @Override
+ public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec() {
+ return new CopyArchiveFromContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec() {
+ return new CopyArchiveToContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public AuthCmd.Exec createAuthCmdExec() {
+ return new AuthCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public InfoCmd.Exec createInfoCmdExec() {
+ return new InfoCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public PingCmd.Exec createPingCmdExec() {
+ return new PingCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public VersionCmd.Exec createVersionCmdExec() {
+ return new VersionCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public PullImageCmd.Exec createPullImageCmdExec() {
+ return new PullImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public PushImageCmd.Exec createPushImageCmdExec() {
+ return new PushImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public SaveImageCmd.Exec createSaveImageCmdExec() {
+ return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CreateImageCmd.Exec createCreateImageCmdExec() {
+ return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public LoadImageCmd.Exec createLoadImageCmdExec() {
+ return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public SearchImagesCmd.Exec createSearchImagesCmdExec() {
+ return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public RemoveImageCmd.Exec createRemoveImageCmdExec() {
+ return new RemoveImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ListImagesCmd.Exec createListImagesCmdExec() {
+ return new ListImagesCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public InspectImageCmd.Exec createInspectImageCmdExec() {
+ return new InspectImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ListContainersCmd.Exec createListContainersCmdExec() {
+ return new ListContainersCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CreateContainerCmd.Exec createCreateContainerCmdExec() {
+ return new CreateContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public StartContainerCmd.Exec createStartContainerCmdExec() {
+ return new StartContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public InspectContainerCmd.Exec createInspectContainerCmdExec() {
+ return new InspectContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ExecCreateCmd.Exec createExecCmdExec() {
+ return new ExecCreateCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public RemoveContainerCmd.Exec createRemoveContainerCmdExec() {
+ return new RemoveContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public WaitContainerCmd.Exec createWaitContainerCmdExec() {
+ return new WaitContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public AttachContainerCmd.Exec createAttachContainerCmdExec() {
+ return new AttachContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ExecStartCmd.Exec createExecStartCmdExec() {
+ return new ExecStartCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public InspectExecCmd.Exec createInspectExecCmdExec() {
+ return new InspectExecCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public LogContainerCmd.Exec createLogContainerCmdExec() {
+ return new LogContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() {
+ return new CopyFileFromContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public StopContainerCmd.Exec createStopContainerCmdExec() {
+ return new StopContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ContainerDiffCmd.Exec createContainerDiffCmdExec() {
+ return new ContainerDiffCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public KillContainerCmd.Exec createKillContainerCmdExec() {
+ return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() {
+ return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public RenameContainerCmd.Exec createRenameContainerCmdExec() {
+ return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public RestartContainerCmd.Exec createRestartContainerCmdExec() {
+ return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CommitCmd.Exec createCommitCmdExec() {
+ return new CommitCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public BuildImageCmd.Exec createBuildImageCmdExec() {
+ return new BuildImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public TopContainerCmd.Exec createTopContainerCmdExec() {
+ return new TopContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public TagImageCmd.Exec createTagImageCmdExec() {
+ return new TagImageCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public PauseContainerCmd.Exec createPauseContainerCmdExec() {
+ return new PauseContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() {
+ return new UnpauseContainerCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public EventsCmd.Exec createEventsCmdExec() {
+ return new EventsCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public StatsCmd.Exec createStatsCmdExec() {
+ return new StatsCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CreateVolumeCmd.Exec createCreateVolumeCmdExec() {
+ return new CreateVolumeCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public InspectVolumeCmd.Exec createInspectVolumeCmdExec() {
+ return new InspectVolumeCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec() {
+ return new RemoveVolumeCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ListVolumesCmd.Exec createListVolumesCmdExec() {
+ return new ListVolumesCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ListNetworksCmd.Exec createListNetworksCmdExec() {
+ return new ListNetworksCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public InspectNetworkCmd.Exec createInspectNetworkCmdExec() {
+ return new InspectNetworkCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public CreateNetworkCmd.Exec createCreateNetworkCmdExec() {
+ return new CreateNetworkCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec() {
+ return new RemoveNetworkCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec() {
+ return new ConnectToNetworkCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() {
+ return new DisconnectFromNetworkCmdExec(getBaseResource(), getDockerClientConfig());
+ }
+
+ @Override
+ public void close() throws IOException {
+ checkNotNull(eventLoopGroup, "Factory not initialized. You probably forgot to call init()!");
+
+ eventLoopGroup.shutdownGracefully();
+ }
+
+ /**
+ * Configure connection timeout in milliseconds
+ */
+ public NettyDockerCmdExecFactory withConnectTimeout(Integer connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ return this;
+ }
+
+ private T configure(T channel) {
+ ChannelConfig channelConfig = channel.config();
+
+ if (connectTimeout != null) {
+ channelConfig.setConnectTimeoutMillis(connectTimeout);
+ }
+
+ return channel;
+ }
+
+ private WebTarget getBaseResource() {
+ return new WebTarget(channelProvider);
+ }
+}
diff --git a/src/main/java/com/github/dockerjava/netty/WebTarget.java b/src/main/java/com/github/dockerjava/netty/WebTarget.java
index 090fea67c..ef1510f5c 100644
--- a/src/main/java/com/github/dockerjava/netty/WebTarget.java
+++ b/src/main/java/com/github/dockerjava/netty/WebTarget.java
@@ -2,12 +2,14 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
/**
* This class is basically a replacement of javax.ws.rs.client.WebTarget to allow simpler migration of JAX-RS code to a netty based
* implementation.
@@ -16,32 +18,40 @@
*/
public class WebTarget {
- private ChannelProvider channelProvider;
+ private final ChannelProvider channelProvider;
- private List path = new ArrayList();
+ private final ImmutableList path;
- private Map queryParams = new HashMap();
+ private final ImmutableMap queryParams;
private static final String PATH_SEPARATOR = "/";
public WebTarget(ChannelProvider channelProvider) {
+ this(channelProvider, ImmutableList.of(), ImmutableMap.of());
+ }
+
+ private WebTarget(ChannelProvider channelProvider,
+ ImmutableList path,
+ ImmutableMap queryParams) {
this.channelProvider = channelProvider;
+ this.path = path;
+ this.queryParams = queryParams;
}
public WebTarget path(String... components) {
+ ImmutableList.Builder newPath = ImmutableList.builder().addAll(this.path);
for (String component : components) {
-
- path.addAll(Arrays.asList(StringUtils.split(component, PATH_SEPARATOR)));
+ newPath.addAll(Arrays.asList(StringUtils.split(component, PATH_SEPARATOR)));
}
- return this;
+ return new WebTarget(channelProvider, newPath.build(), queryParams);
}
public InvocationBuilder request() {
String resource = PATH_SEPARATOR + StringUtils.join(path, PATH_SEPARATOR);
- List params = new ArrayList();
+ List params = new ArrayList<>();
for (Map.Entry entry : queryParams.entrySet()) {
params.add(entry.getKey() + "=" + entry.getValue());
}
@@ -54,20 +64,47 @@ public InvocationBuilder request() {
}
public WebTarget resolveTemplate(String name, Object value) {
- List newPath = new ArrayList();
+ ImmutableList.Builder newPath = ImmutableList.builder();
for (String component : path) {
component = component.replaceAll("\\{" + name + "\\}", value.toString());
newPath.add(component);
}
- path = newPath;
- return this;
+ return new WebTarget(channelProvider, newPath.build(), queryParams);
}
public WebTarget queryParam(String name, Object value) {
+ ImmutableMap.Builder builder = ImmutableMap.builder().putAll(queryParams);
if (value != null) {
- queryParams.put(name, value.toString());
+ builder.put(name, value.toString());
}
- return this;
+ return new WebTarget(channelProvider, path, builder.build());
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ WebTarget webTarget = (WebTarget) o;
+
+ if (channelProvider != null ? !channelProvider.equals(webTarget.channelProvider) : webTarget.channelProvider != null) {
+ return false;
+ }
+ if (path != null ? !path.equals(webTarget.path) : webTarget.path != null) {
+ return false;
+ }
+ return queryParams != null ? queryParams.equals(webTarget.queryParams) : webTarget.queryParams == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = channelProvider != null ? channelProvider.hashCode() : 0;
+ result = 31 * result + (path != null ? path.hashCode() : 0);
+ result = 31 * result + (queryParams != null ? queryParams.hashCode() : 0);
+ return result;
+ }
}
diff --git a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java
index f4ff04576..43152570e 100644
--- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java
+++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java
@@ -15,6 +15,7 @@
import com.github.dockerjava.netty.WebTarget;
import java.io.IOException;
+import java.util.Map;
public class BuildImageCmdExec extends AbstrAsyncDockerCmdExec implements
BuildImageCmd.Exec {
@@ -85,18 +86,14 @@ protected Void execute0(BuildImageCmd command, ResultCallback
webTarget = webTarget.queryParam("cpusetcpus", command.getCpusetcpus());
}
- if (command.getBuildArgs() != null && !command.getBuildArgs().isEmpty()) {
- try {
- webTarget = webTarget.queryParam("buildargs", MAPPER.writeValueAsString(command.getBuildArgs()));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
+ webTarget = writeMap(webTarget, "buildargs", command.getBuildArgs());
if (command.getShmsize() != null) {
webTarget = webTarget.queryParam("shmsize", command.getShmsize());
}
+ webTarget = writeMap(webTarget, "labels", command.getLabels());
+
LOGGER.trace("POST: {}", webTarget);
InvocationBuilder builder = resourceWithOptionalAuthConfig(command, webTarget.request())
@@ -109,4 +106,16 @@ protected Void execute0(BuildImageCmd command, ResultCallback
return null;
}
+
+ private WebTarget writeMap(WebTarget webTarget, String name, Map value) {
+ if (value != null && !value.isEmpty()) {
+ try {
+ return webTarget.queryParam(name, MAPPER.writeValueAsString(value));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ return webTarget;
+ }
+ }
}
diff --git a/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java
new file mode 100644
index 000000000..30ee716a5
--- /dev/null
+++ b/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java
@@ -0,0 +1,28 @@
+package com.github.dockerjava.netty.exec;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.dockerjava.api.command.LoadImageCmd;
+import com.github.dockerjava.core.DockerClientConfig;
+import com.github.dockerjava.netty.WebTarget;
+
+public class LoadImageCmdExec extends AbstrSyncDockerCmdExec implements
+ LoadImageCmd.Exec {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LoadImageCmdExec.class);
+
+ public LoadImageCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) {
+ super(baseResource, dockerClientConfig);
+ }
+
+ @Override
+ protected Void execute(LoadImageCmd command) {
+ WebTarget webResource = getBaseResource().path("/images/load");
+
+ LOGGER.trace("POST: {}", webResource);
+ webResource.request().postStream(command.getImageStream());
+
+ return null;
+ }
+}
diff --git a/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java
index 12f2d8cbc..039006f2d 100644
--- a/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java
+++ b/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java
@@ -23,7 +23,9 @@ protected Void execute(StartContainerCmd command) {
command.getContainerId());
LOGGER.trace("POST: {}", webResource);
- webResource.request().accept(MediaType.APPLICATION_JSON).post(command);
+ webResource.request()
+ .accept(MediaType.APPLICATION_JSON)
+ .post(command);
return null;
}
diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java
index 706228d04..596334640 100644
--- a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java
+++ b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java
@@ -6,9 +6,6 @@
import java.io.IOException;
import java.io.InputStream;
-import java.util.concurrent.LinkedTransferQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
import com.github.dockerjava.api.async.ResultCallback;
@@ -19,45 +16,87 @@
*/
public class HttpResponseStreamHandler extends SimpleChannelInboundHandler {
- private HttpResponseInputStream stream = new HttpResponseInputStream();
+ private ResultCallback resultCallback;
+
+ private final HttpResponseInputStream stream = new HttpResponseInputStream();
public HttpResponseStreamHandler(ResultCallback resultCallback) {
- resultCallback.onNext(stream);
+ this.resultCallback = resultCallback;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
+ invokeCallbackOnFirstRead();
+
stream.write(msg.copy());
}
+ private void invokeCallbackOnFirstRead() {
+ if (resultCallback != null) {
+ resultCallback.onNext(stream);
+ resultCallback = null;
+ }
+ }
+
@Override
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
- stream.close();
- super.channelReadComplete(ctx);
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ stream.writeComplete();
+
+ super.channelInactive(ctx);
}
public static class HttpResponseInputStream extends InputStream {
- private AtomicBoolean closed = new AtomicBoolean(false);
+ private boolean writeCompleted = false;
- private LinkedTransferQueue queue = new LinkedTransferQueue();
+ private boolean closed = false;
private ByteBuf current = null;
- public void write(ByteBuf byteBuf) {
- queue.put(byteBuf);
+ private final Object lock = new Object();
+
+ public void write(ByteBuf byteBuf) throws InterruptedException {
+ synchronized (lock) {
+ if (closed) {
+ return;
+ }
+ while (current != null) {
+ lock.wait();
+
+ if (closed) {
+ return;
+ }
+ }
+ current = byteBuf;
+
+ lock.notifyAll();
+ }
+ }
+
+ public void writeComplete() {
+ synchronized (lock) {
+ writeCompleted = true;
+
+ lock.notifyAll();
+ }
}
@Override
public void close() throws IOException {
- closed.set(true);
- super.close();
+ synchronized (lock) {
+ closed = true;
+ releaseCurrent();
+
+ lock.notifyAll();
+ }
}
@Override
public int available() throws IOException {
- poll();
- return readableBytes();
+ synchronized (lock) {
+ poll(0);
+ return readableBytes();
+ }
}
private int readableBytes() {
@@ -66,34 +105,72 @@ private int readableBytes() {
} else {
return 0;
}
-
}
@Override
public int read() throws IOException {
+ byte[] b = new byte[1];
+ int n = read(b, 0, 1);
+ return n != -1 ? b[0] : -1;
+ }
- poll();
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ synchronized (lock) {
+ off = poll(off);
- if (readableBytes() == 0) {
- if (closed.get()) {
+ if (current == null) {
return -1;
+ } else {
+ int availableBytes = Math.min(len, current.readableBytes() - off);
+ current.readBytes(b, off, availableBytes);
+ return availableBytes;
}
}
+ }
- if (current != null && current.readableBytes() > 0) {
- return current.readByte() & 0xff;
- } else {
- return read();
+ private int poll(int off) throws IOException {
+ synchronized (lock) {
+ while (readableBytes() <= off) {
+ try {
+ if (closed) {
+ throw new IOException("Stream closed");
+ }
+
+ off -= releaseCurrent();
+ if (writeCompleted) {
+ return off;
+ }
+ while (current == null) {
+ lock.wait();
+
+ if (closed) {
+ throw new IOException("Stream closed");
+ }
+ if (writeCompleted && current == null) {
+ return off;
+ }
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return off;
}
}
- private void poll() {
- if (readableBytes() == 0) {
- try {
- current = queue.poll(50, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
+ private int releaseCurrent() {
+ synchronized (lock) {
+ if (current != null) {
+ int n = current.readableBytes();
+ current.release();
+ current = null;
+
+ lock.notifyAll();
+
+ return n;
}
+ return 0;
}
}
}
diff --git a/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java b/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
new file mode 100644
index 000000000..17c339e3e
--- /dev/null
+++ b/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java
@@ -0,0 +1,337 @@
+// Modified version (see https://github.com/docker-java/docker-java/pull/697)
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.http.impl.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.http.ConnectionClosedException;
+import org.apache.http.Header;
+import org.apache.http.HttpException;
+import org.apache.http.MalformedChunkCodingException;
+import org.apache.http.TruncatedChunkException;
+import org.apache.http.config.MessageConstraints;
+import org.apache.http.io.BufferInfo;
+import org.apache.http.io.SessionInputBuffer;
+import org.apache.http.util.Args;
+import org.apache.http.util.CharArrayBuffer;
+
+/**
+ * Implements chunked transfer coding. The content is received in small chunks.
+ * Entities transferred using this input stream can be of unlimited length.
+ * After the stream is read to the end, it provides access to the trailers,
+ * if any.
+ *
+ * Note that this class NEVER closes the underlying stream, even when close
+ * gets called. Instead, it will read until the "end" of its chunking on
+ * close, which allows for the seamless execution of subsequent HTTP 1.1
+ * requests, while not requiring the client to remember to read the entire
+ * contents of the response.
+ *
+ *
+ * @since 4.0
+ *
+ */
+public class ChunkedInputStream extends InputStream {
+
+ private static final int CHUNK_LEN = 1;
+ private static final int CHUNK_DATA = 2;
+ private static final int CHUNK_CRLF = 3;
+ private static final int CHUNK_INVALID = Integer.MAX_VALUE;
+
+ private static final int BUFFER_SIZE = 2048;
+
+ /** The session input buffer */
+ private final SessionInputBuffer in;
+ private final CharArrayBuffer buffer;
+ private final MessageConstraints constraints;
+
+ private int state;
+
+ /** The chunk size */
+ private long chunkSize;
+
+ /** The current position within the current chunk */
+ private long pos;
+
+ /** True if we've reached the end of stream */
+ private boolean eof = false;
+
+ /** True if this stream is closed */
+ private boolean closed = false;
+
+ private Header[] footers = new Header[] {};
+
+ /**
+ * Wraps session input stream and reads chunk coded input.
+ *
+ * @param in The session input buffer
+ * @param constraints Message constraints. If {@code null}
+ * {@link MessageConstraints#DEFAULT} will be used.
+ *
+ * @since 4.4
+ */
+ public ChunkedInputStream(final SessionInputBuffer in, final MessageConstraints constraints) {
+ super();
+ this.in = Args.notNull(in, "Session input buffer");
+ this.pos = 0L;
+ this.buffer = new CharArrayBuffer(16);
+ this.constraints = constraints != null ? constraints : MessageConstraints.DEFAULT;
+ this.state = CHUNK_LEN;
+ }
+
+ /**
+ * Wraps session input stream and reads chunk coded input.
+ *
+ * @param in The session input buffer
+ */
+ public ChunkedInputStream(final SessionInputBuffer in) {
+ this(in, null);
+ }
+
+ @Override
+ public int available() throws IOException {
+ if (this.in instanceof BufferInfo) {
+ final int len = ((BufferInfo) this.in).length();
+ return (int) Math.min(len, this.chunkSize - this.pos);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ *
Returns all the data in a chunked stream in coalesced form. A chunk
+ * is followed by a CRLF. The method returns -1 as soon as a chunksize of 0
+ * is detected.
+ *
+ *
Trailer headers are read automatically at the end of the stream and
+ * can be obtained with the getResponseFooters() method.
+ *
+ * @return -1 of the end of the stream has been reached or the next data
+ * byte
+ * @throws IOException in case of an I/O error
+ */
+ @Override
+ public int read() throws IOException {
+ if (this.closed) {
+ throw new IOException("Attempted read from closed stream.");
+ }
+ if (this.eof) {
+ return -1;
+ }
+ if (state != CHUNK_DATA) {
+ nextChunk();
+ if (this.eof) {
+ return -1;
+ }
+ }
+ final int b = in.read();
+ if (b != -1) {
+ pos++;
+ if (pos >= chunkSize) {
+ state = CHUNK_CRLF;
+ }
+ }
+ return b;
+ }
+
+ /**
+ * Read some bytes from the stream.
+ * @param b The byte array that will hold the contents from the stream.
+ * @param off The offset into the byte array at which bytes will start to be
+ * placed.
+ * @param len the maximum number of bytes that can be returned.
+ * @return The number of bytes returned or -1 if the end of stream has been
+ * reached.
+ * @throws IOException in case of an I/O error
+ */
+ @Override
+ public int read(final byte[] b, final int off, final int len) throws IOException {
+
+ if (closed) {
+ throw new IOException("Attempted read from closed stream.");
+ }
+
+ if (eof) {
+ return -1;
+ }
+ if (state != CHUNK_DATA) {
+ nextChunk();
+ if (eof) {
+ return -1;
+ }
+ }
+ final int bytesRead = in.read(b, off, (int) Math.min(len, chunkSize - pos));
+ if (bytesRead != -1) {
+ pos += bytesRead;
+ if (pos >= chunkSize) {
+ state = CHUNK_CRLF;
+ }
+ return bytesRead;
+ } else {
+ eof = true;
+ throw new TruncatedChunkException("Truncated chunk "
+ + "( expected size: " + chunkSize
+ + "; actual size: " + pos + ")");
+ }
+ }
+
+ /**
+ * Read some bytes from the stream.
+ * @param b The byte array that will hold the contents from the stream.
+ * @return The number of bytes returned or -1 if the end of stream has been
+ * reached.
+ * @throws IOException in case of an I/O error
+ */
+ @Override
+ public int read(final byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ /**
+ * Read the next chunk.
+ * @throws IOException in case of an I/O error
+ */
+ private void nextChunk() throws IOException {
+ if (state == CHUNK_INVALID) {
+ throw new MalformedChunkCodingException("Corrupt data stream");
+ }
+ try {
+ chunkSize = getChunkSize();
+ if (chunkSize < 0L) {
+ throw new MalformedChunkCodingException("Negative chunk size");
+ }
+ state = CHUNK_DATA;
+ pos = 0L;
+ if (chunkSize == 0L) {
+ eof = true;
+ parseTrailerHeaders();
+ }
+ } catch (MalformedChunkCodingException ex) {
+ state = CHUNK_INVALID;
+ throw ex;
+ }
+ }
+
+ /**
+ * Expects the stream to start with a chunksize in hex with optional
+ * comments after a semicolon. The line must end with a CRLF: "a3; some
+ * comment\r\n" Positions the stream at the start of the next line.
+ */
+ private long getChunkSize() throws IOException {
+ final int st = this.state;
+ switch (st) {
+ case CHUNK_CRLF:
+ this.buffer.clear();
+ final int bytesRead1 = this.in.readLine(this.buffer);
+ if (bytesRead1 == -1) {
+ throw new MalformedChunkCodingException(
+ "CRLF expected at end of chunk");
+ }
+ if (!this.buffer.isEmpty()) {
+ throw new MalformedChunkCodingException(
+ "Unexpected content at the end of chunk");
+ }
+ state = CHUNK_LEN;
+ //$FALL-THROUGH$
+ case CHUNK_LEN:
+ this.buffer.clear();
+ final int bytesRead2 = this.in.readLine(this.buffer);
+ if (bytesRead2 == -1) {
+ throw new ConnectionClosedException("Premature end of chunk coded message body: " +
+ "closing chunk expected");
+ }
+ int separator = this.buffer.indexOf(';');
+ if (separator < 0) {
+ separator = this.buffer.length();
+ }
+ final String s = this.buffer.substringTrimmed(0, separator);
+ try {
+ return Long.parseLong(s, 16);
+ } catch (final NumberFormatException e) {
+ throw new MalformedChunkCodingException("Bad chunk header: " + s);
+ }
+ default:
+ throw new IllegalStateException("Inconsistent codec state");
+ }
+ }
+
+ /**
+ * Reads and stores the Trailer headers.
+ * @throws IOException in case of an I/O error
+ */
+ private void parseTrailerHeaders() throws IOException {
+ try {
+ this.footers = AbstractMessageParser.parseHeaders(in,
+ constraints.getMaxHeaderCount(),
+ constraints.getMaxLineLength(),
+ null);
+ } catch (final HttpException ex) {
+ final IOException ioe = new MalformedChunkCodingException("Invalid footer: "
+ + ex.getMessage());
+ ioe.initCause(ex);
+ throw ioe;
+ }
+ }
+
+ /**
+ * Upon close, this reads the remainder of the chunked message,
+ * leaving the underlying socket at a position to start reading the
+ * next response without scanning.
+ * @throws IOException in case of an I/O error
+ */
+ @Override
+ public void close() throws IOException {
+ if (!closed) {
+ try {
+ if (!eof && state != CHUNK_INVALID) {
+ // read and discard the remainder of the message
+ final byte[] buff = new byte[BUFFER_SIZE];
+ try {
+ while (read(buff) >= 0) {
+ continue;
+ }
+ } catch (ConnectionClosedException e) {
+ // just ignore
+ } catch (TruncatedChunkException e) {
+ // just ignore
+ }
+ }
+ } finally {
+ eof = true;
+ closed = true;
+ }
+ }
+ }
+
+ public Header[] getFooters() {
+ return this.footers.clone();
+ }
+
+}
diff --git a/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java b/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java
new file mode 100644
index 000000000..869d987f2
--- /dev/null
+++ b/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java
@@ -0,0 +1,415 @@
+// Modified version (see https://github.com/docker-java/docker-java/pull/697)
+/**
+ * junixsocket
+ *
+ * Copyright (c) 2009,2014 Christian Kohlschütter
+ *
+ * The author licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.newsclub.net.unix;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.SocketImpl;
+import java.net.SocketOptions;
+
+/**
+ * The Java-part of the {@link AFUNIXSocket} implementation.
+ *
+ * @author Christian Kohlschütter
+ */
+class AFUNIXSocketImpl extends SocketImpl {
+ private static final int SHUT_RD = 0;
+ private static final int SHUT_WR = 1;
+ private static final int SHUT_RD_WR = 2;
+
+ private String socketFile;
+ private boolean closed = false;
+ private boolean bound = false;
+ private boolean connected = false;
+
+ private boolean closedInputStream = false;
+ private boolean closedOutputStream = false;
+
+ private final AFUNIXInputStream in = new AFUNIXInputStream();
+ private final AFUNIXOutputStream out = new AFUNIXOutputStream();
+
+ AFUNIXSocketImpl() {
+ super();
+ this.fd = new FileDescriptor();
+ }
+
+ FileDescriptor getFD() {
+ return fd;
+ }
+
+ @Override
+ protected void accept(SocketImpl socket) throws IOException {
+ final AFUNIXSocketImpl si = (AFUNIXSocketImpl) socket;
+ NativeUnixSocket.accept(socketFile, fd, si.fd);
+ si.socketFile = socketFile;
+ si.connected = true;
+ }
+
+ @Override
+ protected int available() throws IOException {
+ return NativeUnixSocket.available(fd);
+ }
+
+ protected void bind(SocketAddress addr) throws IOException {
+ bind(0, addr);
+ }
+
+ protected void bind(int backlog, SocketAddress addr) throws IOException {
+ if (!(addr instanceof AFUNIXSocketAddress)) {
+ throw new SocketException("Cannot bind to this type of address: " + addr.getClass());
+ }
+ final AFUNIXSocketAddress socketAddress = (AFUNIXSocketAddress) addr;
+ socketFile = socketAddress.getSocketFile();
+ NativeUnixSocket.bind(socketFile, fd, backlog);
+ bound = true;
+ this.localport = socketAddress.getPort();
+ }
+
+ @Override
+ @SuppressWarnings("hiding")
+ protected void bind(InetAddress host, int port) throws IOException {
+ throw new SocketException("Cannot bind to this type of address: " + InetAddress.class);
+ }
+
+ private void checkClose() throws IOException {
+ //if (closedInputStream && closedOutputStream) {
+ // close();
+ //}
+ }
+
+ @Override
+ protected synchronized void close() throws IOException {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ if (fd.valid()) {
+ NativeUnixSocket.shutdown(fd, SHUT_RD_WR);
+ NativeUnixSocket.close(fd);
+ }
+ if (bound) {
+ NativeUnixSocket.unlink(socketFile);
+ }
+ connected = false;
+ }
+
+ @Override
+ @SuppressWarnings("hiding")
+ protected void connect(String host, int port) throws IOException {
+ throw new SocketException("Cannot bind to this type of address: " + InetAddress.class);
+ }
+
+ @Override
+ @SuppressWarnings("hiding")
+ protected void connect(InetAddress address, int port) throws IOException {
+ throw new SocketException("Cannot bind to this type of address: " + InetAddress.class);
+ }
+
+ @Override
+ protected void connect(SocketAddress addr, int timeout) throws IOException {
+ if (!(addr instanceof AFUNIXSocketAddress)) {
+ throw new SocketException("Cannot bind to this type of address: " + addr.getClass());
+ }
+ final AFUNIXSocketAddress socketAddress = (AFUNIXSocketAddress) addr;
+ socketFile = socketAddress.getSocketFile();
+ NativeUnixSocket.connect(socketFile, fd);
+ this.address = socketAddress.getAddress();
+ this.port = socketAddress.getPort();
+ this.localport = 0;
+ this.connected = true;
+ }
+
+ @Override
+ protected void create(boolean stream) throws IOException {
+ }
+
+ @Override
+ protected InputStream getInputStream() throws IOException {
+ if (!connected && !bound) {
+ throw new IOException("Not connected/not bound");
+ }
+ return in;
+ }
+
+ @Override
+ protected OutputStream getOutputStream() throws IOException {
+ if (!connected && !bound) {
+ throw new IOException("Not connected/not bound");
+ }
+ return out;
+ }
+
+ @Override
+ protected void listen(int backlog) throws IOException {
+ NativeUnixSocket.listen(fd, backlog);
+ }
+
+ @Override
+ protected void sendUrgentData(int data) throws IOException {
+ NativeUnixSocket.write(fd, new byte[] {(byte) (data & 0xFF)}, 0, 1);
+ }
+
+ private final class AFUNIXInputStream extends InputStream {
+ private boolean streamClosed = false;
+
+ @Override
+ public int read(byte[] buf, int off, int len) throws IOException {
+ if (streamClosed) {
+ throw new IOException("This InputStream has already been closed.");
+ }
+ if (len == 0) {
+ return 0;
+ }
+ if (closed) {
+ return -1;
+ }
+ int maxRead = buf.length - off;
+ if (len > maxRead) {
+ len = maxRead;
+ }
+ try {
+ return NativeUnixSocket.read(fd, buf, off, len);
+ } catch (final IOException e) {
+ throw (IOException) new IOException(e.getMessage() + " at "
+ + AFUNIXSocketImpl.this.toString()).initCause(e);
+ }
+ }
+
+ @Override
+ public int read() throws IOException {
+ final byte[] buf1 = new byte[1];
+ final int numRead = read(buf1, 0, 1);
+ if (numRead <= 0) {
+ return -1;
+ } else {
+ return buf1[0] & 0xFF;
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (streamClosed) {
+ return;
+ }
+ streamClosed = true;
+ if (fd.valid()) {
+ NativeUnixSocket.shutdown(fd, SHUT_RD);
+ }
+
+ closedInputStream = true;
+ checkClose();
+ }
+
+ @Override
+ public int available() throws IOException {
+ final int av = NativeUnixSocket.available(fd);
+ return av;
+ }
+ }
+
+ private final class AFUNIXOutputStream extends OutputStream {
+ private boolean streamClosed = false;
+
+ @Override
+ public void write(int oneByte) throws IOException {
+ final byte[] buf1 = new byte[] {(byte) oneByte};
+ write(buf1, 0, 1);
+ }
+
+ @Override
+ public void write(byte[] buf, int off, int len) throws IOException {
+ if (streamClosed) {
+ throw new AFUNIXSocketException("This OutputStream has already been closed.");
+ }
+ if (len > buf.length - off) {
+ throw new IndexOutOfBoundsException();
+ }
+ try {
+ while (len > 0 && !Thread.interrupted()) {
+ final int written = NativeUnixSocket.write(fd, buf, off, len);
+ if (written == -1) {
+ throw new IOException("Unspecific error while writing");
+ }
+ len -= written;
+ off += written;
+ }
+ } catch (final IOException e) {
+ throw (IOException) new IOException(e.getMessage() + " at "
+ + AFUNIXSocketImpl.this.toString()).initCause(e);
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (streamClosed) {
+ return;
+ }
+ streamClosed = true;
+ if (fd.valid()) {
+ NativeUnixSocket.shutdown(fd, SHUT_WR);
+ }
+ closedOutputStream = true;
+ checkClose();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "[fd=" + fd + "; file=" + this.socketFile + "; connected="
+ + connected + "; bound=" + bound + "]";
+ }
+
+ private static int expectInteger(Object value) throws SocketException {
+ try {
+ return (Integer) value;
+ } catch (final ClassCastException e) {
+ throw new AFUNIXSocketException("Unsupported value: " + value, e);
+ } catch (final NullPointerException e) {
+ throw new AFUNIXSocketException("Value must not be null", e);
+ }
+ }
+
+ private static int expectBoolean(Object value) throws SocketException {
+ try {
+ return ((Boolean) value).booleanValue() ? 1 : 0;
+ } catch (final ClassCastException e) {
+ throw new AFUNIXSocketException("Unsupported value: " + value, e);
+ } catch (final NullPointerException e) {
+ throw new AFUNIXSocketException("Value must not be null", e);
+ }
+ }
+
+ @Override
+ public Object getOption(int optID) throws SocketException {
+ try {
+ switch (optID) {
+ case SocketOptions.SO_KEEPALIVE:
+ case SocketOptions.TCP_NODELAY:
+ return NativeUnixSocket.getSocketOptionInt(fd, optID) != 0 ? true : false;
+ case SocketOptions.SO_LINGER:
+ case SocketOptions.SO_TIMEOUT:
+ case SocketOptions.SO_RCVBUF:
+ case SocketOptions.SO_SNDBUF:
+ return NativeUnixSocket.getSocketOptionInt(fd, optID);
+ default:
+ throw new AFUNIXSocketException("Unsupported option: " + optID);
+ }
+ } catch (final AFUNIXSocketException e) {
+ throw e;
+ } catch (final Exception e) {
+ throw new AFUNIXSocketException("Error while getting option", e);
+ }
+ }
+
+ @Override
+ public void setOption(int optID, Object value) throws SocketException {
+ try {
+ switch (optID) {
+ case SocketOptions.SO_LINGER:
+
+ if (value instanceof Boolean) {
+ final boolean b = (Boolean) value;
+ if (b) {
+ throw new SocketException("Only accepting Boolean.FALSE here");
+ }
+ NativeUnixSocket.setSocketOptionInt(fd, optID, -1);
+ return;
+ }
+ NativeUnixSocket.setSocketOptionInt(fd, optID, expectInteger(value));
+ return;
+ case SocketOptions.SO_RCVBUF:
+ case SocketOptions.SO_SNDBUF:
+ case SocketOptions.SO_TIMEOUT:
+ NativeUnixSocket.setSocketOptionInt(fd, optID, expectInteger(value));
+ return;
+ case SocketOptions.SO_KEEPALIVE:
+ case SocketOptions.TCP_NODELAY:
+ NativeUnixSocket.setSocketOptionInt(fd, optID, expectBoolean(value));
+ return;
+ default:
+ throw new AFUNIXSocketException("Unsupported option: " + optID);
+ }
+ } catch (final AFUNIXSocketException e) {
+ throw e;
+ } catch (final Exception e) {
+ throw new AFUNIXSocketException("Error while setting option", e);
+ }
+ }
+
+ @Override
+ protected void shutdownInput() throws IOException {
+ if (!closed && fd.valid()) {
+ NativeUnixSocket.shutdown(fd, SHUT_RD);
+ }
+ }
+
+ @Override
+ protected void shutdownOutput() throws IOException {
+ if (!closed && fd.valid()) {
+ NativeUnixSocket.shutdown(fd, SHUT_WR);
+ }
+ }
+
+ /**
+ * Changes the behavior to be somewhat lenient with respect to the specification.
+ *
+ * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and
+ * {@link Socket#setTcpNoDelay(boolean)}.
+ */
+ static class Lenient extends AFUNIXSocketImpl {
+ Lenient() {
+ super();
+ }
+
+ @Override
+ public void setOption(int optID, Object value) throws SocketException {
+ try {
+ super.setOption(optID, value);
+ } catch (SocketException e) {
+ switch (optID) {
+ case SocketOptions.TCP_NODELAY:
+ return;
+ default:
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public Object getOption(int optID) throws SocketException {
+ try {
+ return super.getOption(optID);
+ } catch (SocketException e) {
+ switch (optID) {
+ case SocketOptions.TCP_NODELAY:
+ case SocketOptions.SO_KEEPALIVE:
+ return false;
+ default:
+ throw e;
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java b/src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java
new file mode 100644
index 000000000..770b136c9
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java
@@ -0,0 +1,63 @@
+package com.github.dockerjava.api;
+
+import com.github.dockerjava.api.model.Binds;
+import com.github.dockerjava.api.model.BuildResponseItem;
+import com.github.dockerjava.api.model.PullResponseItem;
+import com.github.dockerjava.api.model.PushResponseItem;
+import com.github.dockerjava.api.model.ResponseItem;
+import com.google.common.reflect.ClassPath.ClassInfo;
+import org.apache.commons.lang.reflect.FieldUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.google.common.reflect.ClassPath.from;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.object.IsCompatibleType.typeCompatibleWith;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author Kanstantsin Shautsou
+ */
+public class ModelsSerializableTest {
+ private static final Logger LOG = LoggerFactory.getLogger(ModelsSerializableTest.class);
+
+ private List excludeClasses = Arrays.asList(
+ Binds.class.getName(),
+ BuildResponseItem.class.getName(),
+ PullResponseItem.class.getName(),
+ PushResponseItem.class.getName(),
+ ResponseItem.class.getName()
+ );
+
+ @Test
+ public void allModelsSerializable() throws IOException, NoSuchFieldException, IllegalAccessException {
+ final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ for (ClassInfo classInfo : from(contextClassLoader).getTopLevelClasses("com.github.dockerjava.api.model")) {
+ if (classInfo.getName().endsWith("Test")) {
+ continue;
+ }
+
+ final Class> aClass = classInfo.load();
+ if (aClass.getProtectionDomain().getCodeSource().getLocation().getPath().endsWith("test-classes/")
+ || aClass.isEnum()) {
+ continue;
+ }
+
+ LOG.debug("aClass: {}", aClass);
+ assertThat(aClass, typeCompatibleWith(Serializable.class));
+
+ final Object serialVersionUID = FieldUtils.readDeclaredStaticField(aClass, "serialVersionUID", true);
+ if (!excludeClasses.contains(aClass.getName())) {
+ assertThat(serialVersionUID, instanceOf(Long.class));
+ assertThat("Follow devel docs", (Long) serialVersionUID, is(1L));
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java
index f64cf4ead..cd4562b4a 100644
--- a/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java
+++ b/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java
@@ -22,6 +22,7 @@
import static com.github.dockerjava.test.serdes.JSONTestHelper.testRoundTrip;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsNot.not;
@@ -51,6 +52,7 @@ public void roundTrip_full() throws IOException {
assertEquals(response.getVolumesRW()[1].getVolume().getPath(), "/bar/foo/myvol2");
assertFalse(response.getVolumesRW()[1].getAccessMode().toBoolean());
assertTrue(response.getVolumesRW()[0].getAccessMode().toBoolean());
+ assertThat(response.getLogPath(), is("/mnt/sda1/var/lib/docker/containers/469e5edd8d5b33e3c905a7ffc97360ec6ee211d6782815fbcd144568045819e1/469e5edd8d5b33e3c905a7ffc97360ec6ee211d6782815fbcd144568045819e1-json.log"));
}
@Test
diff --git a/src/test/java/com/github/dockerjava/api/model/BindTest.java b/src/test/java/com/github/dockerjava/api/model/BindTest.java
index 3204ee716..2e6fd8353 100644
--- a/src/test/java/com/github/dockerjava/api/model/BindTest.java
+++ b/src/test/java/com/github/dockerjava/api/model/BindTest.java
@@ -3,6 +3,7 @@
import static com.github.dockerjava.api.model.AccessMode.ro;
import static com.github.dockerjava.api.model.AccessMode.rw;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import org.testng.annotations.Test;
@@ -16,6 +17,8 @@ public void parseUsingDefaultAccessMode() {
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT));
assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
}
@Test
@@ -25,6 +28,52 @@ public void parseReadWrite() {
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(rw));
assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
+ }
+
+ @Test
+ public void parseReadWriteNoCopy() {
+ Bind bind = Bind.parse("/host:/container:rw,nocopy");
+ assertThat(bind.getPath(), is("/host"));
+ assertThat(bind.getVolume().getPath(), is("/container"));
+ assertThat(bind.getAccessMode(), is(rw));
+ assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), is(true));
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
+ }
+
+ @Test
+ public void parseReadWriteShared() {
+ Bind bind = Bind.parse("/host:/container:rw,shared");
+ assertThat(bind.getPath(), is("/host"));
+ assertThat(bind.getVolume().getPath(), is("/container"));
+ assertThat(bind.getAccessMode(), is(rw));
+ assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.SHARED));
+ }
+
+ @Test
+ public void parseReadWriteSlave() {
+ Bind bind = Bind.parse("/host:/container:rw,slave");
+ assertThat(bind.getPath(), is("/host"));
+ assertThat(bind.getVolume().getPath(), is("/container"));
+ assertThat(bind.getAccessMode(), is(rw));
+ assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.SLAVE));
+ }
+
+ @Test
+ public void parseReadWritePrivate() {
+ Bind bind = Bind.parse("/host:/container:rw,private");
+ assertThat(bind.getPath(), is("/host"));
+ assertThat(bind.getVolume().getPath(), is("/container"));
+ assertThat(bind.getAccessMode(), is(rw));
+ assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.PRIVATE));
}
@Test
@@ -34,6 +83,8 @@ public void parseReadOnly() {
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(ro));
assertThat(bind.getSecMode(), is(SELContext.none));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
}
@Test
@@ -43,12 +94,16 @@ public void parseSELOnly() {
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT));
assertThat(bind.getSecMode(), is(SELContext.single));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
bind = Bind.parse("/host:/container:z");
assertThat(bind.getPath(), is("/host"));
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT));
assertThat(bind.getSecMode(), is(SELContext.shared));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
}
@Test
@@ -58,6 +113,8 @@ public void parseReadWriteSEL() {
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(rw));
assertThat(bind.getSecMode(), is(SELContext.single));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
}
@Test
@@ -67,6 +124,8 @@ public void parseReadOnlySEL() {
assertThat(bind.getVolume().getPath(), is("/container"));
assertThat(bind.getAccessMode(), is(ro));
assertThat(bind.getSecMode(), is(SELContext.shared));
+ assertThat(bind.getNoCopy(), nullValue());
+ assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE));
}
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing Bind.*")
@@ -94,6 +153,26 @@ public void toStringReadWrite() {
assertThat(Bind.parse("/host:/container:rw").toString(), is("/host:/container:rw"));
}
+ @Test
+ public void toStringReadWriteNoCopy() {
+ assertThat(Bind.parse("/host:/container:rw,nocopy").toString(), is("/host:/container:rw,nocopy"));
+ }
+
+ @Test
+ public void toStringReadWriteShared() {
+ assertThat(Bind.parse("/host:/container:rw,shared").toString(), is("/host:/container:rw,shared"));
+ }
+
+ @Test
+ public void toStringReadWriteSlave() {
+ assertThat(Bind.parse("/host:/container:rw,slave").toString(), is("/host:/container:rw,slave"));
+ }
+
+ @Test
+ public void toStringReadWritePrivate() {
+ assertThat(Bind.parse("/host:/container:rw,private").toString(), is("/host:/container:rw,private"));
+ }
+
@Test
public void toStringDefaultAccessMode() {
assertThat(Bind.parse("/host:/container").toString(), is("/host:/container:rw"));
diff --git a/src/test/java/com/github/dockerjava/api/model/DeviceTest.java b/src/test/java/com/github/dockerjava/api/model/DeviceTest.java
new file mode 100644
index 000000000..5c48c4886
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/api/model/DeviceTest.java
@@ -0,0 +1,95 @@
+package com.github.dockerjava.api.model;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import static junit.framework.Assert.fail;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * @author Kanstantsin Shautsou
+ */
+public class DeviceTest {
+
+ public static List validPaths = Arrays.asList(
+ "/home",
+ "/home:/home",
+ "/home:/something/else",
+ "/with space",
+ "/home:/with space",
+ "relative:/absolute-path",
+ "hostPath:/containerPath:r",
+ "/hostPath:/containerPath:rw",
+ "/hostPath:/containerPath:mrw"
+ );
+
+ public static HashMap badPaths = new LinkedHashMap() {{
+ put("", "bad format for path: ");
+ // TODO implement ValidatePath
+// put("./", "./ is not an absolute path");
+// put("../", "../ is not an absolute path");
+// put("/:../", "../ is not an absolute path");
+// put("/:path", "path is not an absolute path");
+// put(":", "bad format for path: :");
+// put("/tmp:", " is not an absolute path");
+// put(":test", "bad format for path: :test");
+// put(":/test", "bad format for path: :/test");
+// put("tmp:", " is not an absolute path");
+// put(":test:", "bad format for path: :test:");
+// put("::", "bad format for path: ::");
+// put(":::", "bad format for path: :::");
+// put("/tmp:::", "bad format for path: /tmp:::");
+// put(":/tmp::", "bad format for path: :/tmp::");
+// put("path:ro", "ro is not an absolute path");
+// put("path:rr", "rr is not an absolute path");
+ put("a:/b:ro", "bad mode specified: ro");
+ put("a:/b:rr", "bad mode specified: rr");
+ }};
+
+ @Test
+ public void testParse() throws Exception {
+ assertThat(Device.parse("/dev/sda:/dev/xvdc:r"),
+ equalTo(new Device("r", "/dev/xvdc", "/dev/sda")));
+
+ assertThat(Device.parse("/dev/snd:rw"),
+ equalTo(new Device("rw", "/dev/snd", "/dev/snd")));
+
+ assertThat(Device.parse("/dev/snd:/something"),
+ equalTo(new Device("rwm", "/something", "/dev/snd")));
+
+ assertThat(Device.parse("/dev/snd:/something:rw"),
+ equalTo(new Device("rw", "/something", "/dev/snd")));
+
+ }
+
+ @Test
+ public void testParseBadPaths() {
+ for (Map.Entry entry : badPaths.entrySet()) {
+ final String deviceStr = entry.getKey();
+ try {
+ Device.parse(deviceStr);
+ fail("Should fail because: " + entry.getValue() + " '" + deviceStr + "'");
+ } catch (IllegalArgumentException ex) {
+ assertThat(ex.getMessage(), containsString("Invalid device specification:"));
+ }
+ }
+ }
+
+ @Test
+ public void testParseValidPaths() {
+ for (String path : validPaths) {
+ Device.parse(path);
+ }
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/api/model/EventsTest.java b/src/test/java/com/github/dockerjava/api/model/EventsTest.java
new file mode 100644
index 000000000..ce62c7d5f
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/api/model/EventsTest.java
@@ -0,0 +1,64 @@
+package com.github.dockerjava.api.model;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.dockerjava.core.RemoteApiVersion;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+import static com.github.dockerjava.api.model.EventType.CONTAINER;
+import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * @author Kanstantsin Shautsou
+ */
+public class EventsTest {
+
+ @Test
+ public void serderDocs1() throws IOException {
+ final ObjectMapper mapper = new ObjectMapper();
+ final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(Event.class);
+
+ final Event event = testRoundTrip(RemoteApiVersion.VERSION_1_24,
+ "/events/docs1.json",
+ type
+ );
+
+ assertThat(event, notNullValue());
+ assertThat(event.getType(), is(CONTAINER));
+ assertThat(event.getAction(), is("create"));
+ assertThat(event.getId(), is("ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743"));
+ assertThat(event.getFrom(), is("alpine"));
+ assertThat(event.getTime(), is(1461943101L));
+ assertThat(event.getNode(), nullValue());
+ assertThat(event.getTimeNano(), is(1461943101381709551L));
+
+ final HashMap attributes = new HashMap<>();
+ attributes.put("com.example.some-label", "some-label-value");
+ attributes.put("image", "alpine");
+ attributes.put("name", "my-container");
+
+ final EventActor actor = new EventActor()
+ .withId("ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743")
+ .withAttributes(attributes);
+
+ final Event event1 = new Event()
+ .withType(CONTAINER)
+ .withStatus("create")
+ .withId("ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743")
+ .withFrom("alpine")
+ .withTime(1461943101L)
+ .withTimenano(1461943101381709551L)
+ .withAction("create")
+ .withEventActor(actor);
+
+ assertThat(event1, equalTo(event));
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java
index 4c8750ecc..e6cc00ac0 100644
--- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java
+++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java
@@ -29,7 +29,7 @@
import com.github.dockerjava.api.model.Network;
import com.github.dockerjava.api.model.Volume;
import com.github.dockerjava.core.DockerClientBuilder;
-import com.github.dockerjava.core.DockerClientConfig;
+import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.TestDockerCmdExecFactory;
import com.github.dockerjava.core.command.BuildImageResultCallback;
import com.github.dockerjava.core.command.LogContainerResultCallback;
@@ -68,12 +68,12 @@ public void beforeTest() throws Exception {
LOG.info("======================= END OF BEFORETEST =======================\n\n");
}
- private DockerClientConfig config() {
+ private DefaultDockerClientConfig config() {
return config(null);
}
- protected DockerClientConfig config(String password) {
- DockerClientConfig.DockerClientConfigBuilder builder = DockerClientConfig.createDefaultConfigBuilder()
+ protected DefaultDockerClientConfig config(String password) {
+ DefaultDockerClientConfig.Builder builder = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withRegistryUrl("https://index.docker.io/v1/");
if (password != null) {
builder = builder.withRegistryPassword(password);
@@ -225,17 +225,33 @@ protected String containerLog(String containerId) throws Exception {
public static class LogContainerTestCallback extends LogContainerResultCallback {
protected final StringBuffer log = new StringBuffer();
+ List collectedFrames = new ArrayList();
+
+ boolean collectFrames = false;
+
+ public LogContainerTestCallback() {
+ this(false);
+ }
+
+ public LogContainerTestCallback(boolean collectFrames) {
+ this.collectFrames = collectFrames;
+ }
+
@Override
public void onNext(Frame frame) {
+ if(collectFrames) collectedFrames.add(frame);
log.append(new String(frame.getPayload()));
- System.err.println("LogContainerTestCallback: " + log.toString());
- // super.onNext(frame);
}
@Override
public String toString() {
return log.toString();
}
+
+
+ public List getCollectedFrames() {
+ return collectedFrames;
+ }
}
protected String buildImage(File baseDir) throws Exception {
diff --git a/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java
new file mode 100644
index 000000000..54e70c511
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java
@@ -0,0 +1,204 @@
+package com.github.dockerjava.core;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.core.Is.is;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang.SerializationUtils;
+import org.testng.annotations.Test;
+
+import com.github.dockerjava.api.exception.DockerClientException;
+import com.github.dockerjava.api.model.AuthConfig;
+
+public class DefaultDockerClientConfigTest {
+
+ public static final DefaultDockerClientConfig EXAMPLE_CONFIG = newExampleConfig();
+
+ private static DefaultDockerClientConfig newExampleConfig() {
+
+ String dockerCertPath = dockerCertPath();
+
+ return new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+ new LocalDirectorySSLConfig(dockerCertPath));
+ }
+
+ private static String homeDir() {
+ return "target/test-classes/someHomeDir";
+ }
+
+ private static String dockerCertPath() {
+ return homeDir() + "/.docker";
+ }
+
+ @Test
+ public void equals() throws Exception {
+ assertEquals(EXAMPLE_CONFIG, newExampleConfig());
+ }
+
+ @Test
+ public void environmentDockerHost() throws Exception {
+
+ // given docker host in env
+ Map env = new HashMap();
+ env.put(DefaultDockerClientConfig.DOCKER_HOST, "tcp://baz:8768");
+ // and it looks to be SSL disabled
+ env.remove("DOCKER_CERT_PATH");
+
+ // given default cert path
+ Properties systemProperties = new Properties();
+ systemProperties.setProperty("user.name", "someUserName");
+ systemProperties.setProperty("user.home", homeDir());
+
+ // when you build a config
+ DefaultDockerClientConfig config = buildConfig(env, systemProperties);
+
+ assertEquals(config.getDockerHost(), URI.create("tcp://baz:8768"));
+ }
+
+ @Test
+ public void environment() throws Exception {
+
+ // given a default config in env properties
+ Map env = new HashMap();
+ env.put(DefaultDockerClientConfig.DOCKER_HOST, "tcp://foo");
+ env.put(DefaultDockerClientConfig.API_VERSION, "apiVersion");
+ env.put(DefaultDockerClientConfig.REGISTRY_USERNAME, "registryUsername");
+ env.put(DefaultDockerClientConfig.REGISTRY_PASSWORD, "registryPassword");
+ env.put(DefaultDockerClientConfig.REGISTRY_EMAIL, "registryEmail");
+ env.put(DefaultDockerClientConfig.REGISTRY_URL, "registryUrl");
+ env.put(DefaultDockerClientConfig.DOCKER_CONFIG, "dockerConfig");
+ env.put(DefaultDockerClientConfig.DOCKER_CERT_PATH, dockerCertPath());
+ env.put(DefaultDockerClientConfig.DOCKER_TLS_VERIFY, "1");
+
+ // when you build a config
+ DefaultDockerClientConfig config = buildConfig(env, new Properties());
+
+ // then we get the example object
+ assertEquals(config, EXAMPLE_CONFIG);
+ }
+
+ private DefaultDockerClientConfig buildConfig(Map env, Properties systemProperties) {
+ return DefaultDockerClientConfig.createDefaultConfigBuilder(env, systemProperties).build();
+ }
+
+ @Test
+ public void defaults() throws Exception {
+
+ // given default cert path
+ Properties systemProperties = new Properties();
+ systemProperties.setProperty("user.name", "someUserName");
+ systemProperties.setProperty("user.home", homeDir());
+
+ // when you build config
+ DefaultDockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties);
+
+ // then the cert path is as expected
+ assertEquals(config.getDockerHost(), URI.create("unix:///var/run/docker.sock"));
+ assertEquals(config.getRegistryUsername(), "someUserName");
+ assertEquals(config.getRegistryUrl(), AuthConfig.DEFAULT_SERVER_ADDRESS);
+ assertEquals(config.getApiVersion(), RemoteApiVersion.unknown());
+ assertEquals(config.getDockerConfig(), homeDir() + "/.docker");
+ assertNull(config.getSSLConfig());
+ }
+
+ @Test
+ public void systemProperties() throws Exception {
+
+ // given system properties based on the example
+ Properties systemProperties = new Properties();
+ systemProperties.put(DefaultDockerClientConfig.DOCKER_HOST, "tcp://foo");
+ systemProperties.put(DefaultDockerClientConfig.API_VERSION, "apiVersion");
+ systemProperties.put(DefaultDockerClientConfig.REGISTRY_USERNAME, "registryUsername");
+ systemProperties.put(DefaultDockerClientConfig.REGISTRY_PASSWORD, "registryPassword");
+ systemProperties.put(DefaultDockerClientConfig.REGISTRY_EMAIL, "registryEmail");
+ systemProperties.put(DefaultDockerClientConfig.REGISTRY_URL, "registryUrl");
+ systemProperties.put(DefaultDockerClientConfig.DOCKER_CONFIG, "dockerConfig");
+ systemProperties.put(DefaultDockerClientConfig.DOCKER_CERT_PATH, dockerCertPath());
+ systemProperties.put(DefaultDockerClientConfig.DOCKER_TLS_VERIFY, "1");
+
+ // when you build new config
+ DefaultDockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties);
+
+ // then it is the same as the example
+ assertEquals(config, EXAMPLE_CONFIG);
+
+ }
+
+ @Test
+ public void serializableTest() {
+ final byte[] serialized = SerializationUtils.serialize(EXAMPLE_CONFIG);
+ final DefaultDockerClientConfig deserialized = (DefaultDockerClientConfig) SerializationUtils.deserialize(serialized);
+
+ assertThat("Deserialized object mush match source object", deserialized, equalTo(EXAMPLE_CONFIG));
+ }
+
+ @Test()
+ public void testSslContextEmpty() throws Exception {
+ new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+ null);
+ }
+
+
+
+ @Test()
+ public void testTlsVerifyAndCertPath() throws Exception {
+ new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+ new LocalDirectorySSLConfig(dockerCertPath()));
+ }
+
+ @Test(expectedExceptions = DockerClientException.class)
+ public void testWrongHostScheme() throws Exception {
+ new DefaultDockerClientConfig(URI.create("http://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+ null);
+ }
+
+ @Test()
+ public void testTcpHostScheme() throws Exception {
+ new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+ null);
+ }
+
+ @Test()
+ public void testUnixHostScheme() throws Exception {
+ new DefaultDockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
+ null);
+ }
+
+ @Test
+ public void withDockerTlsVerify() throws Exception {
+ DefaultDockerClientConfig.Builder builder = new DefaultDockerClientConfig.Builder();
+ Field field = builder.getClass().getDeclaredField("dockerTlsVerify");
+ field.setAccessible(true);
+
+ builder.withDockerTlsVerify("");
+ assertThat((Boolean) field.get(builder), is(false));
+
+ builder.withDockerTlsVerify("false");
+ assertThat((Boolean) field.get(builder), is(false));
+
+ builder.withDockerTlsVerify("FALSE");
+ assertThat((Boolean) field.get(builder), is(false));
+
+ builder.withDockerTlsVerify("true");
+ assertThat((Boolean) field.get(builder), is(true));
+
+ builder.withDockerTlsVerify("TRUE");
+ assertThat((Boolean) field.get(builder), is(true));
+
+ builder.withDockerTlsVerify("0");
+ assertThat((Boolean) field.get(builder), is(false));
+
+ builder.withDockerTlsVerify("1");
+ assertThat((Boolean) field.get(builder), is(true));
+ }
+
+}
diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java
deleted file mode 100644
index ee679a0af..000000000
--- a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package com.github.dockerjava.core;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.core.Is.is;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-
-import java.lang.reflect.Field;
-import java.net.URI;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.commons.lang.SerializationUtils;
-import org.testng.annotations.Test;
-
-import com.github.dockerjava.api.exception.DockerClientException;
-import com.github.dockerjava.api.model.AuthConfig;
-
-public class DockerClientConfigTest {
-
- public static final DockerClientConfig EXAMPLE_CONFIG = newExampleConfig();
-
- private static DockerClientConfig newExampleConfig() {
-
- String dockerCertPath = dockerCertPath();
-
- return new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- dockerCertPath, true);
- }
-
- private static String homeDir() {
- return "target/test-classes/someHomeDir";
- }
-
- private static String dockerCertPath() {
- return homeDir() + "/.docker";
- }
-
- @Test
- public void equals() throws Exception {
- assertEquals(EXAMPLE_CONFIG, newExampleConfig());
- }
-
- @Test
- public void environmentDockerHost() throws Exception {
-
- // given docker host in env
- Map env = new HashMap();
- env.put(DockerClientConfig.DOCKER_HOST, "tcp://baz:8768");
- // and it looks to be SSL disabled
- env.remove("DOCKER_CERT_PATH");
-
- // given default cert path
- Properties systemProperties = new Properties();
- systemProperties.setProperty("user.name", "someUserName");
- systemProperties.setProperty("user.home", homeDir());
-
- // when you build a config
- DockerClientConfig config = buildConfig(env, systemProperties);
-
- assertEquals(config.getDockerHost(), URI.create("tcp://baz:8768"));
- }
-
- @Test
- public void environment() throws Exception {
-
- // given a default config in env properties
- Map env = new HashMap();
- env.put(DockerClientConfig.DOCKER_HOST, "tcp://foo");
- env.put(DockerClientConfig.API_VERSION, "apiVersion");
- env.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername");
- env.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword");
- env.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail");
- env.put(DockerClientConfig.REGISTRY_URL, "registryUrl");
- env.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig");
- env.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath());
- env.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1");
-
- // when you build a config
- DockerClientConfig config = buildConfig(env, new Properties());
-
- // then we get the example object
- assertEquals(config, EXAMPLE_CONFIG);
- }
-
- private DockerClientConfig buildConfig(Map env, Properties systemProperties) {
- return DockerClientConfig.createDefaultConfigBuilder(env, systemProperties).build();
- }
-
- @Test
- public void defaults() throws Exception {
-
- // given default cert path
- Properties systemProperties = new Properties();
- systemProperties.setProperty("user.name", "someUserName");
- systemProperties.setProperty("user.home", homeDir());
-
- // when you build config
- DockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties);
-
- // then the cert path is as expected
- assertEquals(config.getDockerHost(), URI.create("unix:///var/run/docker.sock"));
- assertEquals(config.getRegistryUsername(), "someUserName");
- assertEquals(config.getRegistryUrl(), AuthConfig.DEFAULT_SERVER_ADDRESS);
- assertEquals(config.getApiVersion(), RemoteApiVersion.unknown());
- assertEquals(config.getDockerConfig(), homeDir() + "/.docker");
- assertNull(config.getDockerCertPath());
- }
-
- @Test
- public void systemProperties() throws Exception {
-
- // given system properties based on the example
- Properties systemProperties = new Properties();
- systemProperties.put(DockerClientConfig.DOCKER_HOST, "tcp://foo");
- systemProperties.put(DockerClientConfig.API_VERSION, "apiVersion");
- systemProperties.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername");
- systemProperties.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword");
- systemProperties.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail");
- systemProperties.put(DockerClientConfig.REGISTRY_URL, "registryUrl");
- systemProperties.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig");
- systemProperties.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath());
- systemProperties.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1");
-
- // when you build new config
- DockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties);
-
- // then it is the same as the example
- assertEquals(config, EXAMPLE_CONFIG);
-
- }
-
- @Test
- public void serializableTest() {
- final byte[] serialized = SerializationUtils.serialize(EXAMPLE_CONFIG);
- final DockerClientConfig deserialized = (DockerClientConfig) SerializationUtils.deserialize(serialized);
-
- assertThat("Deserialized object mush match source object", deserialized, equalTo(EXAMPLE_CONFIG));
- }
-
- @Test(expectedExceptions = DockerClientException.class)
- public void testTlsVerifyAndCertPathNull() throws Exception {
- new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- null, true);
- }
-
- @Test(expectedExceptions = DockerClientException.class)
- public void testTlsVerifyAndCertPathEmpty() throws Exception {
- new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- "", true);
- }
-
- @Test()
- public void testTlsVerifyAndCertPath() throws Exception {
- new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- dockerCertPath(), true);
- }
-
- @Test(expectedExceptions = DockerClientException.class)
- public void testWrongHostScheme() throws Exception {
- new DockerClientConfig(URI.create("http://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- null, false);
- }
-
- @Test()
- public void testTcpHostScheme() throws Exception {
- new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- null, false);
- }
-
- @Test()
- public void testUnixHostScheme() throws Exception {
- new DockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail",
- null, false);
- }
-
- @Test
- public void withDockerTlsVerify() throws Exception {
- DockerClientConfig.DockerClientConfigBuilder builder = new DockerClientConfig.DockerClientConfigBuilder();
- Field field = builder.getClass().getDeclaredField("dockerTlsVerify");
- field.setAccessible(true);
-
- builder.withDockerTlsVerify("");
- assertThat(field.getBoolean(builder), is(false));
-
- builder.withDockerTlsVerify("false");
- assertThat(field.getBoolean(builder), is(false));
-
- builder.withDockerTlsVerify("FALSE");
- assertThat(field.getBoolean(builder), is(false));
-
- builder.withDockerTlsVerify("true");
- assertThat(field.getBoolean(builder), is(true));
-
- builder.withDockerTlsVerify("TRUE");
- assertThat(field.getBoolean(builder), is(true));
-
- builder.withDockerTlsVerify("0");
- assertThat(field.getBoolean(builder), is(false));
-
- builder.withDockerTlsVerify("1");
- assertThat(field.getBoolean(builder), is(true));
- }
-
-}
diff --git a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java
index 7ea8bace5..1df4636ba 100644
--- a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java
@@ -12,7 +12,7 @@ public class DockerClientImplTest {
@Test
public void configuredInstanceAuthConfig() throws Exception {
// given a config with null serverAddress
- DockerClientConfig dockerClientConfig = new DockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null, false);
+ DefaultDockerClientConfig dockerClientConfig = new DefaultDockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null);
DockerClientImpl dockerClient = DockerClientImpl.getInstance(dockerClientConfig);
// when we get the auth config
diff --git a/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java b/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java
index 0fd870194..62b342595 100644
--- a/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java
+++ b/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java
@@ -5,13 +5,14 @@
import java.io.IOException;
-import com.github.dockerjava.core.exception.GoLangFileMatchException;
-import junit.framework.Assert;
-
import org.apache.commons.io.FilenameUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import com.github.dockerjava.core.exception.GoLangFileMatchException;
+
+import junit.framework.Assert;
+
public class GoLangFileMatchTest {
@Test(dataProvider = "getTestData")
@@ -31,7 +32,7 @@ public void testMatch(MatchTestCase testCase) throws IOException {
if (testCase.expectException) {
Assert.fail("Expected GoFileMatchException");
}
- Assert.assertEquals(testCase.matches, matched);
+ Assert.assertEquals(testCase.toString(), testCase.matches, matched);
} catch (GoLangFileMatchException e) {
if (!testCase.expectException) {
throw e;
@@ -41,12 +42,13 @@ public void testMatch(MatchTestCase testCase) throws IOException {
@DataProvider
public Object[][] getTestData() {
- return new Object[][] {new Object[] {new MatchTestCase("abc", "abc", true, false)},
+ return new Object[][] {new Object[] {new MatchTestCase("", "abc", false, false)},
+ new Object[] {new MatchTestCase("abc", "abc", true, false)},
new Object[] {new MatchTestCase("*", "abc", true, false)},
new Object[] {new MatchTestCase("*c", "abc", true, false)},
new Object[] {new MatchTestCase("a*", "a", true, false)},
new Object[] {new MatchTestCase("a*", "abc", true, false)},
- new Object[] {new MatchTestCase("a*", "ab/c", false, false)},
+ new Object[] {new MatchTestCase("a*", "ab/c", true, false)},
new Object[] {new MatchTestCase("a*/b", "abc/b", true, false)},
new Object[] {new MatchTestCase("a*/b", "a/c/b", false, false)},
new Object[] {new MatchTestCase("a*b*c*d*e*/f", "axbxcxdxe/f", true, false)},
@@ -92,9 +94,13 @@ public Object[][] getTestData() {
new Object[] {new MatchTestCase("[", "a", false, true)},
new Object[] {new MatchTestCase("[^", "a", false, true)},
new Object[] {new MatchTestCase("[^bc", "a", false, true)},
- new Object[] {new MatchTestCase("a[", "a", false, false)},
+ new Object[] {new MatchTestCase("a[", "a", false, true)},
new Object[] {new MatchTestCase("a[", "ab", false, true)},
- new Object[] {new MatchTestCase("*x", "xxx", true, false)}};
+ new Object[] {new MatchTestCase("*x", "xxx", true, false)},
+ new Object[] {new MatchTestCase("a", "a/b/c", true, false)},
+ new Object[] {new MatchTestCase("*/b", "a/b/c", true, false)},
+ new Object[] {new MatchTestCase("**/b/*/d", "a/b/c/d", true, false)},
+ new Object[] {new MatchTestCase("**/c", "a/b/c", true, false)}};
}
private final class MatchTestCase {
diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
index aee8a60a8..46d6d4dcc 100644
--- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
+++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java
@@ -34,6 +34,7 @@
import com.github.dockerjava.api.command.ListImagesCmd;
import com.github.dockerjava.api.command.ListNetworksCmd;
import com.github.dockerjava.api.command.ListVolumesCmd;
+import com.github.dockerjava.api.command.LoadImageCmd;
import com.github.dockerjava.api.command.LogContainerCmd;
import com.github.dockerjava.api.command.PauseContainerCmd;
import com.github.dockerjava.api.command.PingCmd;
@@ -58,7 +59,6 @@
import com.github.dockerjava.api.command.WaitContainerCmd;
import com.github.dockerjava.api.model.BuildResponseItem;
-import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
@@ -132,6 +132,17 @@ public CreateImageResponse exec(CreateImageCmd command) {
};
}
+ @Override
+ public LoadImageCmd.Exec createLoadImageCmdExec() {
+ return new LoadImageCmd.Exec() {
+ @Override
+ public Void exec(LoadImageCmd command) {
+ delegate.createLoadImageCmdExec().exec(command);
+ return null;
+ }
+ };
+ }
+
@Override
public RemoveImageCmd.Exec createRemoveImageCmdExec() {
return new RemoveImageCmd.Exec() {
@@ -431,9 +442,4 @@ public List getVolumeNames() {
public List getNetworkIds() {
return new ArrayList<>(networkIds);
}
-
- @Override
- public DockerCmdExecFactory withSSLContext(SSLContext sslContext) {
- return delegate.withSSLContext(sslContext);
- }
}
diff --git a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java
index 21507e44e..ef69984f3 100644
--- a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java
@@ -1,5 +1,6 @@
package com.github.dockerjava.core.command;
+import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.isEmptyString;
@@ -11,7 +12,9 @@
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
+import org.apache.commons.codec.binary.StringUtils;
import org.testng.ITestResult;
+import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
@@ -97,14 +100,17 @@ public void onNext(Frame frame) {
};
};
- dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true)
- .exec(callback).awaitCompletion(15, TimeUnit.SECONDS);
+ dockerClient.attachContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .exec(callback)
+ .awaitCompletion(15, TimeUnit.SECONDS);
callback.close();
System.out.println("log: " + callback.toString());
// HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0);
-
assertThat(callback.toString(), containsString("stdout\r\nstderr"));
}
@@ -145,6 +151,11 @@ public void onNext(Frame item) {
super.onNext(item);
}
+ @Override
+ public RuntimeException getFirstError() {
+ return super.getFirstError();
+ }
+
@Override
public String toString() {
return log.toString();
diff --git a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java
index c01c8b8cd..887c99130 100644
--- a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java
@@ -45,14 +45,9 @@ public void testAuth() throws Exception {
}
// Disabled because of 500/InternalServerException
- @Test(enabled = false)
+ @Test(enabled = false, expectedExceptions = UnauthorizedException.class, expectedExceptionsMessageRegExp = "Wrong login/password, please try again")
public void testAuthInvalid() throws Exception {
- try {
- DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec();
- fail("Expected a UnauthorizedException caused by a bad password.");
- } catch (UnauthorizedException e) {
- assertEquals(e.getMessage(), "Wrong login/password, please try again\n");
- }
+ DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java
index 950b80a24..cb4c1b2a8 100644
--- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java
@@ -1,11 +1,11 @@
package com.github.dockerjava.core.command;
+import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import java.io.File;
@@ -13,11 +13,13 @@
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Collection;
+import java.util.Collections;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.testng.ITestResult;
+import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
@@ -26,7 +28,6 @@
import com.github.dockerjava.api.command.BuildImageCmd;
import com.github.dockerjava.api.command.CreateContainerResponse;
-import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.command.InspectImageResponse;
import com.github.dockerjava.api.exception.DockerClientException;
import com.github.dockerjava.api.model.AuthConfig;
@@ -35,6 +36,7 @@
import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Ports.Binding;
import com.github.dockerjava.client.AbstractDockerClientTest;
+import com.github.dockerjava.core.RemoteApiVersion;
import com.github.dockerjava.core.util.CompressArchiveUtil;
@Test(groups = "integration")
@@ -61,10 +63,9 @@ public void afterMethod(ITestResult result) {
}
@Test
- public void testNginxDockerfileBuilder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nginx").getFile());
+ public void author() throws Exception {
- String imageId = buildImage(baseDir);
+ String imageId = buildImage(fileFromBuildTestResource("AUTHOR"));
InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
assertThat(inspectImageResponse, not(nullValue()));
@@ -73,27 +74,9 @@ public void testNginxDockerfileBuilder() throws Exception {
assertThat(inspectImageResponse.getAuthor(), equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\""));
}
- @Test(groups = "ignoreInCircleCi")
- public void testNonstandard1() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader()
- .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile());
-
- buildImage(baseDir);
- }
-
- @Test(groups = "ignoreInCircleCi")
- public void testNonstandard2() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nonstandard").getFile());
- File dockerFile = new File(Thread.currentThread().getContextClassLoader()
- .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile());
-
- dockerClient.buildImageCmd().withBaseDirectory(baseDir).withDockerfile(dockerFile).withNoCache(true)
- .exec(new BuildImageResultCallback()).awaitImageId();
- }
-
@Test
- public void testDockerBuilderFromTar() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFile").getFile());
+ public void buildImageFromTar() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/file");
Collection files = FileUtils.listFiles(baseDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
File tarFile = CompressArchiveUtil.archiveTARFiles(baseDir, files, UUID.randomUUID().toString());
String response = dockerfileBuild(new FileInputStream(tarFile));
@@ -101,54 +84,45 @@ public void testDockerBuilderFromTar() throws Exception {
}
@Test
- public void testDockerBuildWithOnBuild() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddOnBuild/onbuild")
- .getFile());
+ public void onBuild() throws Exception {
+ File baseDir = fileFromBuildTestResource("ONBUILD/parent");
+
dockerClient.buildImageCmd(baseDir).withNoCache(true).withTag("docker-java-onbuild")
.exec(new BuildImageResultCallback()).awaitImageId();
- baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddOnBuild/test").getFile());
+ baseDir = fileFromBuildTestResource("ONBUILD/child");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("Successfully executed testrun.sh"));
}
@Test
- public void testDockerBuilderAddUrl() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddUrl").getFile());
+ public void addUrl() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/url");
String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Docker"));
+ assertThat(response, containsString("Example Domain"));
}
@Test
- public void testDockerBuilderAddFileInSubfolder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFileInSubfolder")
- .getFile());
+ public void addFileInSubfolder() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/fileInSubfolder");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("Successfully executed testrun.sh"));
}
@Test
- public void testDockerBuilderAddFilesViaWildcard() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFilesViaWildcard")
- .getFile());
+ public void addFilesViaWildcard() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/filesViaWildcard");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("Successfully executed testinclude1.sh"));
assertThat(response, not(containsString("Successfully executed testinclude2.sh")));
}
@Test
- public void testDockerBuilderAddFolder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFolder").getFile());
+ public void addFolder() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/folder");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("Successfully executed testAddFolder.sh"));
}
- @Test
- public void testDockerBuilderEnv() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testEnv").getFile());
- String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Successfully executed testrun.sh"));
- }
-
private String dockerfileBuild(InputStream tarInputStream) throws Exception {
return execBuild(dockerClient.buildImageCmd().withTarInputStream(tarInputStream));
@@ -175,80 +149,42 @@ private String execBuild(BuildImageCmd buildImageCmd) throws Exception {
}
@Test(expectedExceptions = {DockerClientException.class})
- public void testDockerfileIgnored() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileIgnored")
- .getFile());
+ public void dockerignoreDockerfileIgnored() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/DockerfileIgnored");
dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
}
@Test
- public void testDockerfileNotIgnored() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileNotIgnored")
- .getFile());
+ public void dockerignoreDockerfileNotIgnored() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/DockerfileNotIgnored");
dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
}
@Test(expectedExceptions = {DockerClientException.class})
- public void testInvalidDockerIgnorePattern() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader()
- .getResource("testInvalidDockerignorePattern").getFile());
+ public void dockerignoreInvalidDockerIgnorePattern() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/InvalidDockerignorePattern");
dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
}
- @Test(groups = "ignoreInCircleCi")
- public void testDockerIgnore() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerignore")
- .getFile());
+ @Test()
+ public void dockerignoreValidDockerIgnorePattern() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/ValidDockerignorePattern");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("/tmp/a/a /tmp/a/c /tmp/a/d"));
}
@Test
- public void testNetCatDockerfileBuilder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("netcat").getFile());
-
- String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback())
- .awaitImageId();
-
- assertNotNull(imageId, "Not successful in build");
-
- InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
- assertThat(inspectImageResponse, not(nullValue()));
- assertThat(inspectImageResponse.getId(), not(nullValue()));
- LOG.info("Image Inspect: {}", inspectImageResponse.toString());
-
- CreateContainerResponse container = dockerClient.createContainerCmd(inspectImageResponse.getId()).exec();
- assertThat(container.getId(), not(isEmptyString()));
- dockerClient.startContainerCmd(container.getId()).exec();
-
- InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
-
- assertThat(inspectContainerResponse.getId(), notNullValue());
- assertThat(inspectContainerResponse.getNetworkSettings().getPorts(), notNullValue());
-
- // No use as such if not running on the server
- // for (Ports.Port p : inspectContainerResponse.getNetworkSettings().getPorts().getAllPorts()) {
- // int port = Integer.valueOf(p.getHostPort());
- // LOG.info("Checking port {} is open", port);
- // assertThat(available(port), is(false));
- // }
- dockerClient.stopContainerCmd(container.getId()).withTimeout(0).exec();
-
- }
-
- @Test
- public void testAddAndCopySubstitution() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testENVSubstitution")
- .getFile());
+ public void env() throws Exception {
+ File baseDir = fileFromBuildTestResource("ENV");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("testENVSubstitution successfully completed"));
}
@Test
- public void testBuildFromPrivateRegistry() throws Exception {
+ public void fromPrivateRegistry() throws Exception {
File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("privateRegistry").getFile());
String imageId = buildImage(baseDir);
@@ -289,8 +225,7 @@ public void testBuildFromPrivateRegistry() throws Exception {
dockerClient.removeImageCmd("localhost:5000/testuser/busybox").withForce(true).exec();
- baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildFromPrivateRegistry")
- .getFile());
+ baseDir = fileFromBuildTestResource("FROM/privateRegistry");
AuthConfigurations authConfigurations = new AuthConfigurations();
authConfigurations.addConfig(authConfig);
@@ -305,8 +240,8 @@ public void testBuildFromPrivateRegistry() throws Exception {
}
@Test
- public void testBuildArgs() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildArgs").getFile());
+ public void buildArgs() throws Exception {
+ File baseDir = fileFromBuildTestResource("buildArgs");
String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildArg("testArg", "abc")
.exec(new BuildImageResultCallback())
@@ -319,9 +254,29 @@ public void testBuildArgs() throws Exception {
assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc"));
}
- public void testDockerfileNotInBaseDirectory() throws Exception {
- File baseDirectory = getResource("testDockerfileNotInBaseDirectory");
- File dockerfile = getResource("testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile");
+ @Test
+ public void labels() throws Exception {
+ if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) {
+ throw new SkipException("API version should be >= 1.23");
+ }
+
+ File baseDir = fileFromBuildTestResource("labels");
+
+ String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true)
+ .withLabels(Collections.singletonMap("test", "abc"))
+ .exec(new BuildImageResultCallback())
+ .awaitImageId();
+
+ InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
+ assertThat(inspectImageResponse, not(nullValue()));
+ LOG.info("Image Inspect: {}", inspectImageResponse.toString());
+
+ assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc"));
+ }
+
+ public void dockerfileNotInBaseDirectory() throws Exception {
+ File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory");
+ File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile");
BuildImageCmd command = dockerClient.buildImageCmd()
.withBaseDirectory(baseDirectory)
.withDockerfile(dockerfile);
@@ -331,7 +286,8 @@ public void testDockerfileNotInBaseDirectory() throws Exception {
assertThat(response, containsString("Successfully executed testrun.sh"));
}
- private File getResource(String path) {
- return new File(Thread.currentThread().getContextClassLoader().getResource(path).getFile());
+ private File fileFromBuildTestResource(String resource) {
+ return new File(Thread.currentThread().getContextClassLoader()
+ .getResource("buildTests/" + resource).getFile());
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java
index b8758d332..64e1d7ddf 100644
--- a/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java
@@ -68,13 +68,9 @@ public void commit() throws DockerException {
assertThat(inspectImageResponse.getParent(), equalTo(busyboxImg.getId()));
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void commitNonExistingContainer() throws DockerException {
- try {
- dockerClient.commitCmd("non-existent").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
- }
+ dockerClient.commitCmd("non-existent").exec();
+ }
}
diff --git a/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java
index 84bb59a81..207d2a0d5 100644
--- a/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java
@@ -3,6 +3,7 @@
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.CreateNetworkResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.exception.DockerException;
import com.github.dockerjava.api.model.ContainerNetwork;
import com.github.dockerjava.api.model.Network;
import com.github.dockerjava.client.AbstractDockerClientTest;
@@ -16,6 +17,10 @@
import java.lang.reflect.Method;
import java.util.Collections;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
@Test(groups = "integration")
public class ConnectToNetworkCmdImplTest extends AbstractDockerClientTest {
@@ -60,38 +65,49 @@ public void connectToNetwork() throws InterruptedException {
@Test
public void connectToNetworkWithContainerNetwork() throws InterruptedException {
+ final String NETWORK_SUBNET = "10.100.102.0/24";
+ final String NETWORK_NAME = "jerseyTestNetwork";
+ final String CONTAINER_IP = "10.100.102.100";
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("sleep", "9999")
+ .exec();
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
dockerClient.startContainerCmd(container.getId()).exec();
+ try {
+ dockerClient.removeNetworkCmd(NETWORK_NAME).exec();
+ } catch (DockerException ignore) {
+ }
+
CreateNetworkResponse network = dockerClient.createNetworkCmd()
- .withName("testNetwork")
+ .withName(NETWORK_NAME)
.withIpam(new Network.Ipam()
- .withConfig(new Network.Ipam.Config()
- .withSubnet("10.100.100.0/24")))
+ .withConfig(new Network.Ipam.Config()
+ .withSubnet(NETWORK_SUBNET)))
.exec();
dockerClient.connectToNetworkCmd()
.withNetworkId(network.getId())
.withContainerId(container.getId())
.withContainerNetwork(new ContainerNetwork()
- .withAliases("testing")
- .withIpamConfig(new ContainerNetwork.Ipam()
- .withIpv4Address("10.100.100.100")))
+ .withAliases("aliasName")
+ .withIpamConfig(new ContainerNetwork.Ipam()
+ .withIpv4Address(CONTAINER_IP)))
.exec();
Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec();
Network.ContainerNetworkConfig containerNetworkConfig = updatedNetwork.getContainers().get(container.getId());
assertNotNull(containerNetworkConfig);
- assertEquals(containerNetworkConfig.getIpv4Address(), "10.100.100.100/24");
+ assertThat(containerNetworkConfig.getIpv4Address(), is(CONTAINER_IP + "/24"));
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
- ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork");
+ ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get(NETWORK_NAME);
assertNotNull(testNetwork);
- assertEquals(testNetwork.getAliases(), Collections.singletonList("testing"));
- assertEquals(testNetwork.getGateway(), "10.100.100.1");
- assertEquals(testNetwork.getIpAddress(), "10.100.100.100");
+ assertThat(testNetwork.getAliases(), hasItem("aliasName"));
+ assertEquals(testNetwork.getGateway(), "10.100.102.1");
+ assertEquals(testNetwork.getIpAddress(), CONTAINER_IP);
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java
index 62c7b2ec0..e51db21f4 100644
--- a/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java
@@ -67,13 +67,9 @@ public void testContainerDiff() throws DockerException {
assertThat(testChangeLog, hasField("kind", equalTo(1)));
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void testContainerDiffWithNonExistingContainer() throws DockerException {
- try {
- dockerClient.containerDiffCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
- }
+ dockerClient.containerDiffCmd("non-existing").exec();
+ }
}
diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java
index 9b30dd891..59c459382 100644
--- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java
@@ -70,13 +70,10 @@ public void copyFromContainer() throws Exception {
assertTrue(responseAsString.length() > 0);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void copyFromNonExistingContainer() throws Exception {
- try {
- dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException ignored) {
- }
+
+ dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec();
}
@Test
diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java
index a1006277c..658c1f090 100644
--- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java
@@ -83,14 +83,10 @@ private void assertFileCopied(CreateContainerResponse container) throws IOExcept
}
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void copyToNonExistingContainer() throws Exception {
- try {
- dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile")
- .exec();
- fail("expected NotFoundException");
- } catch (NotFoundException ignored) {
- }
+
+ dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile").exec();
}
@Test
diff --git a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java
index 3e4e88612..ec66287eb 100644
--- a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java
@@ -1,5 +1,6 @@
package com.github.dockerjava.core.command;
+import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
@@ -7,7 +8,10 @@
import java.io.InputStream;
import java.lang.reflect.Method;
+import com.github.dockerjava.core.RemoteApiVersion;
+import com.github.dockerjava.utils.TestUtils;
import org.testng.ITestResult;
+import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
@@ -43,6 +47,10 @@ public void afterMethod(ITestResult result) {
@Test
public void copyFromContainer() throws Exception {
+ if (getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) {
+ throw new SkipException("Doesn't work since 1.24");
+ }
+
// TODO extract this into a shared method
CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
.withName("docker-java-itest-copyFromContainer").withCmd("touch", "/copyFromContainer").exec();
@@ -62,12 +70,9 @@ public void copyFromContainer() throws Exception {
assertTrue(responseAsString.length() > 0);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void copyFromNonExistingContainer() throws Exception {
- try {
- dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException ignored) {
- }
+
+ dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java
index a93e100c6..1f62527e9 100644
--- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java
@@ -10,6 +10,7 @@
import com.github.dockerjava.api.model.Device;
import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.Frame;
+import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.Link;
import com.github.dockerjava.api.model.LogConfig;
import com.github.dockerjava.api.model.Network;
@@ -21,6 +22,7 @@
import com.github.dockerjava.api.model.Ports.Binding;
import com.github.dockerjava.client.AbstractDockerClientTest;
+import org.apache.commons.io.FileUtils;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
@@ -45,6 +47,7 @@
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItemInArray;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyString;
@@ -191,9 +194,12 @@ public void createContainerWithVolumesFrom() throws DockerException {
@Test
public void createContainerWithEnv() throws Exception {
+ final String testVariable = "VARIABLE=success";
- CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withEnv("VARIABLE=success")
- .withCmd("env").exec();
+ CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE)
+ .withEnv(testVariable)
+ .withCmd("env")
+ .exec();
LOG.info("Created container {}", container.toString());
@@ -201,11 +207,11 @@ public void createContainerWithEnv() throws Exception {
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
- assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), containsInAnyOrder("VARIABLE=success"));
+ assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), hasItem(testVariable));
dockerClient.startContainerCmd(container.getId()).exec();
- assertThat(containerLog(container.getId()), containsString("VARIABLE=success"));
+ assertThat(containerLog(container.getId()), containsString(testVariable));
}
@Test
@@ -227,7 +233,7 @@ public void createContainerWithHostname() throws Exception {
assertThat(containerLog(container.getId()), containsString("HOSTNAME=docker-java"));
}
- @Test
+ @Test(expectedExceptions = ConflictException.class)
public void createContainerWithName() throws DockerException {
CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container")
@@ -241,12 +247,8 @@ public void createContainerWithName() throws DockerException {
assertThat(inspectContainerResponse.getName(), equalTo("/container"));
- try {
- dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container").withCmd("env").exec();
- fail("Expected ConflictException");
- } catch (ConflictException e) {
- }
+ dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container").withCmd("env").exec();
}
@Test
@@ -373,7 +375,7 @@ public void createContainerWithAlias() throws DockerException {
.exec();
ContainerNetwork aliasNet = inspectContainerResponse.getNetworkSettings().getNetworks().get("aliasNet");
- assertEquals(aliasNet.getAliases(), Collections.singletonList("server"));
+ assertThat(aliasNet.getAliases(), hasItem("server"));
}
@Test
@@ -735,4 +737,20 @@ public void createContainerWithCgroupParent() throws DockerException {
assertThat(inspectContainer.getHostConfig().getCgroupParent(), is("/parent"));
}
+
+ @SuppressWarnings("Duplicates")
+ @Test
+ public void createContainerWithShmSize() throws DockerException {
+ HostConfig hostConfig = new HostConfig().withShmSize(96 * FileUtils.ONE_MB);
+ CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE)
+ .withHostConfig(hostConfig).withCmd("true").exec();
+
+ LOG.info("Created container {}", container.toString());
+
+ assertThat(container.getId(), not(isEmptyString()));
+
+ InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
+
+ assertEquals(inspectContainerResponse.getHostConfig().getShmSize(), hostConfig.getShmSize());
+ }
}
diff --git a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java
index 939f95087..d05327a06 100644
--- a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java
@@ -17,11 +17,14 @@
import com.github.dockerjava.api.model.Event;
import com.github.dockerjava.client.AbstractDockerClientTest;
+/*
+ * NOTE: These tests may fail if there is a difference between local and daemon time
+ * (this is especially a problem when using boot2docker as time may not in sync
+ * with the virtualbox host system)
+ */
@Test(groups = "integration")
public class EventsCmdImplTest extends AbstractDockerClientTest {
- private static int KNOWN_NUM_EVENTS = 4;
-
private static String getEpochTime() {
return String.valueOf(System.currentTimeMillis() / 1000);
}
@@ -46,9 +49,6 @@ public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
- /*
- * This specific test may fail with boot2docker as time may not in sync with host system
- */
@Test
public void testEventStreamTimeBound() throws Exception {
// Don't include other tests events
@@ -58,82 +58,84 @@ public void testEventStreamTimeBound() throws Exception {
int expectedEvents = generateEvents();
String endTime = getEpochTime();
- CountDownLatch countDownLatch = new CountDownLatch(expectedEvents);
- EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch);
-
- dockerClient.eventsCmd().withSince(startTime).withUntil(endTime).exec(eventCallback);
+ EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
+ dockerClient.eventsCmd()
+ .withSince(startTime)
+ .withUntil(endTime)
+ .exec(eventCallback);
- eventCallback.close();
+ List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
+ // we may receive more events as expected
+ assertTrue(events.size() >= expectedEvents, "Received events: " + events);
}
@Test
- public void testEventStreaming1() throws Exception {
- // Don't include other tests events
- TimeUnit.SECONDS.sleep(1);
-
- CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS);
- EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch);
-
- dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback);
-
- generateEvents();
-
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
-
- eventCallback.close();
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
- }
-
- @Test
- public void testEventStreaming2() throws Exception {
+ public void testEventStreaming() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
+
+ String startTime = getEpochTime();
+ int expectedEvents = generateEvents();
- CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS);
- EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch);
+ EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
- dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback);
+ dockerClient.eventsCmd()
+ .withSince(startTime)
+ .exec(eventCallback);
generateEvents();
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
-
- eventCallback.close();
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
+ List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
+
+ // we may receive more events as expected
+ assertTrue(events.size() >= expectedEvents, "Received events: " + events);
}
+
public void testEventStreamingWithFilter() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
+
+ String startTime = getEpochTime();
+ int expectedEvents = 1;
- CountDownLatch countDownLatch = new CountDownLatch(1);
- EventsTestCallback eventCallback = dockerClient.eventsCmd().withEventFilter("start")
- .exec(new EventsTestCallback(countDownLatch));
+ EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
+
+ dockerClient.eventsCmd()
+ .withSince(startTime)
+ .withEventFilter("start")
+ .exec(eventCallback);
generateEvents();
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
-
- eventCallback.close();
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
+ List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
+
+ // we should get exactly one "start" event here
+ assertEquals(events.size(), expectedEvents, "Received events: " + events);
}
/**
- * This method generates {#link KNOWN_NUM_EVENTS} events
+ * This method generates some events and returns the number of events being generated
*/
private int generateEvents() throws Exception {
- String testImage = "busybox";
+ String testImage = "busybox:latest";
dockerClient.pullImageCmd(testImage).exec(new PullImageResultCallback()).awaitSuccess();
-
CreateContainerResponse container = dockerClient.createContainerCmd(testImage).withCmd("sleep", "9999").exec();
dockerClient.startContainerCmd(container.getId()).exec();
- dockerClient.stopContainerCmd(container.getId()).exec();
- return KNOWN_NUM_EVENTS;
+ dockerClient.stopContainerCmd(container.getId()).withTimeout(1).exec();
+
+ // generates 5 events with remote api 1.24:
+
+ // Event[status=pull,id=busybox:latest,from=,node=,type=IMAGE,action=pull,actor=com.github.dockerjava.api.model.EventActor@417db6d7[id=busybox:latest,attributes={name=busybox}],time=1473455186,timeNano=1473455186436681587]
+ // Event[status=create,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=create,actor=com.github.dockerjava.api.model.EventActor@40bcec[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186470713257]
+ // Event[status=,id=,from=,node=,type=NETWORK,action=connect,actor=com.github.dockerjava.api.model.EventActor@318a1b01[id=10870ceb13abb7cf841ea68868472da881b33c8ed08d2cde7dbb39d7c24d1d27,attributes={container=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c, name=bridge, type=bridge}],time=1473455186,timeNano=1473455186544318466]
+ // Event[status=start,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=start,actor=com.github.dockerjava.api.model.EventActor@606f43a3[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186786163819]
+ // Event[status=kill,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=kill,actor=com.github.dockerjava.api.model.EventActor@72a9ffcf[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport, signal=15}],time=1473455186,timeNano=1473455186792963392]
+
+ return 5;
}
private class EventsTestCallback extends EventsResultCallback {
@@ -142,18 +144,24 @@ private class EventsTestCallback extends EventsResultCallback {
private final List events = new ArrayList();
- public EventsTestCallback(CountDownLatch countDownLatch) {
- this.countDownLatch = countDownLatch;
+ public EventsTestCallback(int expextedEvents) {
+ this.countDownLatch = new CountDownLatch(expextedEvents);
}
public void onNext(Event event) {
LOG.info("Received event #{}: {}", countDownLatch.getCount(), event);
- countDownLatch.countDown();
events.add(event);
+ countDownLatch.countDown();
}
-
- public List getEvents() {
- return new ArrayList(events);
+
+ public List awaitExpectedEvents(long timeout, TimeUnit unit ) {
+ try {
+ countDownLatch.await(timeout, unit);
+ close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return new ArrayList(events);
}
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/ExecCreateCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ExecCreateCmdImplTest.java
index 139c81f56..d8e3326d5 100644
--- a/src/test/java/com/github/dockerjava/core/command/ExecCreateCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/ExecCreateCmdImplTest.java
@@ -44,7 +44,7 @@ public void afterMethod(ITestResult result) {
public void execCreateTest() {
String containerName = "generated_" + new SecureRandom().nextInt();
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("top")
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withUser("root").withCmd("top")
.withName(containerName).exec();
LOG.info("Created container {}", container.toString());
diff --git a/src/test/java/com/github/dockerjava/core/command/ExecStartCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ExecStartCmdImplTest.java
index c4f0b9189..8ae9e5a91 100644
--- a/src/test/java/com/github/dockerjava/core/command/ExecStartCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/ExecStartCmdImplTest.java
@@ -1,13 +1,15 @@
package com.github.dockerjava.core.command;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.isEmptyString;
-import static org.hamcrest.Matchers.not;
-
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.command.ExecCreateCmdResponse;
+import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.client.AbstractDockerClientTest;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.security.SecureRandom;
-
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isEmptyString;
+import static org.hamcrest.Matchers.not;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
@@ -15,10 +17,6 @@
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
-import com.github.dockerjava.api.command.CreateContainerResponse;
-import com.github.dockerjava.api.command.ExecCreateCmdResponse;
-import com.github.dockerjava.client.AbstractDockerClientTest;
-
@Test(groups = "integration")
public class ExecStartCmdImplTest extends AbstractDockerClientTest {
@BeforeTest
@@ -53,7 +51,7 @@ public void execStart() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
- .withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec();
+ .withAttachStdout(true).withCmd("touch", "/execStartTest.log").withUser("root").exec();
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(
new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
@@ -92,4 +90,23 @@ public void execStartAttached() throws Exception {
assertNotNull(responseAsString);
assertTrue(responseAsString.length() > 0);
}
+
+ @Test(groups = "ignoreInCircleCi", expectedExceptions = NotFoundException.class)
+ public void execStartWithNonExistentUser() throws Exception {
+ String containerName = "generated_" + new SecureRandom().nextInt();
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
+ .withName(containerName).exec();
+ LOG.info("Created container {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.startContainerCmd(container.getId()).exec();
+
+ ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
+ .withAttachStdout(true).withCmd("touch", "/execStartTest.log").withUser("NonExistentUser").exec();
+ dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true)
+ .exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
+
+ dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec();
+ }
}
diff --git a/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java
index 3ba85928e..c8589271e 100644
--- a/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java
@@ -67,14 +67,10 @@ public void killContainer() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void killNonExistingContainer() throws DockerException {
- try {
- dockerClient.killContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.killContainerCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java
new file mode 100644
index 000000000..7cecf7334
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java
@@ -0,0 +1,76 @@
+package com.github.dockerjava.core.command;
+
+import com.github.dockerjava.api.model.Image;
+import com.github.dockerjava.client.AbstractDockerClientTest;
+
+import com.github.dockerjava.utils.TestResources;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+@Test(groups = "integration")
+public class LoadImageCmdImplTest extends AbstractDockerClientTest {
+
+ private String expectedImageId;
+
+ @BeforeTest
+ public void beforeTest() throws Exception {
+ super.beforeTest();
+ }
+
+ @AfterTest
+ public void afterTest() {
+ super.afterTest();
+ }
+
+ @BeforeMethod
+ public void beforeMethod(Method method) {
+ super.beforeMethod(method);
+ expectedImageId = "sha256:56031f66eb0cef2e2e5cb2d1dabafaa0ebcd0a18a507d313b5bdb8c0472c5eba";
+ if (findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec()) != null) {
+ dockerClient.removeImageCmd(expectedImageId).exec();
+ }
+ }
+
+ @AfterMethod
+ public void afterMethod(ITestResult result) {
+ dockerClient.removeImageCmd(expectedImageId).exec();
+ super.afterMethod(result);
+ }
+
+ @Test
+ public void loadImageFromTar() throws Exception {
+ try (InputStream uploadStream = Files.newInputStream(TestResources.getApiImagesLoadTestTarball())) {
+ dockerClient.loadImageCmd(uploadStream).exec();
+ }
+
+ final Image image = findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec());
+
+ assertThat("Can't find expected image after loading from a tar archive!", image, notNullValue());
+ assertThat("Image after loading from a tar archive has wrong tags!",
+ asList(image.getRepoTags()), equalTo(singletonList("docker-java/load:1.0")));
+ }
+
+ private Image findImageWithId(final String id, final List images) {
+ for (Image image : images) {
+ if (id.equals(image.getId())) {
+ return image;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java
index 817179eb2..869bcbb1a 100644
--- a/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java
@@ -8,6 +8,7 @@
import java.io.IOException;
import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
@@ -17,6 +18,7 @@
import org.testng.annotations.Test;
import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.api.model.StreamType;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.client.AbstractDockerClientTest;
@@ -44,31 +46,65 @@ public void afterMethod(ITestResult result) {
}
@Test
- public void asyncLogContainer() throws Exception {
+ public void asyncLogContainerWithTtyEnabled() throws Exception {
- String snippet = "hello world";
-
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet)
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done")
+ .withTty(true)
.exec();
LOG.info("Created container: {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
- dockerClient.startContainerCmd(container.getId()).exec();
+ dockerClient.startContainerCmd(container.getId())
+ .exec();
- int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback())
- .awaitStatusCode();
+ LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true);
- assertThat(exitCode, equalTo(0));
+ // this essentially test the since=0 case
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .withTailAll()
+ .exec(loggingCallback);
- LogContainerTestCallback loggingCallback = new LogContainerTestCallback();
+ loggingCallback.awaitCompletion(3, TimeUnit.SECONDS);
+
+ assertTrue(loggingCallback.toString().contains("hello"));
+
+ assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.RAW);
+ }
+
+ @Test
+ public void asyncLogContainerWithTtyDisabled() throws Exception {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done")
+ .withTty(false)
+ .exec();
+
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.startContainerCmd(container.getId())
+ .exec();
+
+ LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true);
// this essentially test the since=0 case
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .withTailAll()
+ .exec(loggingCallback);
- loggingCallback.awaitCompletion();
+ loggingCallback.awaitCompletion(3, TimeUnit.SECONDS);
- assertTrue(loggingCallback.toString().contains(snippet));
+ assertTrue(loggingCallback.toString().contains("hello"));
+
+ assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.STDOUT);
}
@Test
@@ -105,7 +141,8 @@ public void asyncMultipleLogContainer() throws Exception {
String snippet = "hello world";
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet)
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/echo", snippet)
.exec();
LOG.info("Created container: {}", container.toString());
@@ -113,26 +150,36 @@ public void asyncMultipleLogContainer() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
- int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback())
+ int exitCode = dockerClient.waitContainerCmd(container.getId())
+ .exec(new WaitContainerResultCallback())
.awaitStatusCode();
assertThat(exitCode, equalTo(0));
LogContainerTestCallback loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .exec(loggingCallback);
loggingCallback.close();
loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .exec(loggingCallback);
loggingCallback.close();
loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .exec(loggingCallback);
loggingCallback.awaitCompletion();
@@ -143,7 +190,8 @@ public void asyncMultipleLogContainer() throws Exception {
public void asyncLogContainerWithSince() throws Exception {
String snippet = "hello world";
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet)
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/echo", snippet)
.exec();
LOG.info("Created container: {}", container.toString());
@@ -153,19 +201,22 @@ public void asyncLogContainerWithSince() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
- int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback())
+ int exitCode = dockerClient.waitContainerCmd(container.getId())
+ .exec(new WaitContainerResultCallback())
.awaitStatusCode();
assertThat(exitCode, equalTo(0));
LogContainerTestCallback loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withSince(timestamp)
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withSince(timestamp)
.exec(loggingCallback);
loggingCallback.awaitCompletion();
assertThat(loggingCallback.toString(), containsString(snippet));
}
-
}
diff --git a/src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java
new file mode 100644
index 000000000..f100c4f89
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java
@@ -0,0 +1,103 @@
+package com.github.dockerjava.core.command;
+
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.exception.InternalServerErrorException;
+import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.client.AbstractDockerClientTest;
+import com.github.dockerjava.utils.ContainerUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isEmptyString;
+import static org.hamcrest.Matchers.not;
+
+@Test(groups = {"integration", "ignoreInCircleCi"})
+public class PauseCmdImplTest extends AbstractDockerClientTest {
+
+ public static final Logger LOG = LoggerFactory.getLogger(PauseCmdImplTest.class);
+
+ @BeforeTest
+ public void beforeTest() throws Exception {
+ super.beforeTest();
+ }
+
+ @AfterTest
+ public void afterTest() {
+ super.afterTest();
+ }
+
+ @BeforeMethod
+ public void beforeMethod(Method method) {
+ super.beforeMethod(method);
+ }
+
+ @AfterMethod
+ public void afterMethod(ITestResult result) {
+ super.afterMethod(result);
+ }
+
+ @Test
+ public void pauseRunningContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+ }
+
+ @Test(expectedExceptions = NotFoundException.class)
+ public void pauseNonExistingContainer() {
+
+ dockerClient.pauseContainerCmd("non-existing").exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void pauseStoppedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.stopContainer(dockerClient, container);
+
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void pausePausedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void pauseCreatedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java
index e89a071b8..0fb32c311 100644
--- a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java
@@ -19,7 +19,7 @@
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.client.AbstractDockerClientTest;
-@Test(groups = "integration")
+@Test(groups = {"integration-auth", "integration"})
public class PushImageCmdImplTest extends AbstractDockerClientTest {
public static final Logger LOG = LoggerFactory.getLogger(PushImageCmdImplTest.class);
diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java
index 87ace71df..26c8e0e19 100644
--- a/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java
@@ -68,13 +68,10 @@ public void removeContainer() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeNonExistingContainer() throws DockerException {
- try {
- dockerClient.removeContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.removeContainerCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java
index 90be81c7f..4427da997 100644
--- a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java
@@ -74,14 +74,10 @@ public void removeImage() throws DockerException, InterruptedException {
assertThat(containers, matcher);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeNonExistingImage() throws DockerException, InterruptedException {
- try {
- dockerClient.removeImageCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.removeImageCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java
index e1e4e45fe..228e48c4d 100644
--- a/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java
@@ -64,13 +64,10 @@ public void removeNetwork() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeNonExistingContainer() throws DockerException {
- try {
- dockerClient.removeNetworkCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.removeNetworkCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java
index 249bf8493..9ed690b65 100644
--- a/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java
@@ -41,7 +41,7 @@ public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeVolume() throws DockerException {
String volumeName = "volume1";
@@ -55,11 +55,6 @@ public void removeVolume() throws DockerException {
dockerClient.removeVolumeCmd(volumeName).exec();
- try {
- dockerClient.inspectVolumeCmd(volumeName).exec();
- fail("Expected NotFoundException");
- } catch (NotFoundException e) {
- // just ignore
- }
+ dockerClient.inspectVolumeCmd(volumeName).exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java
index 4920ac087..84916f082 100644
--- a/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java
@@ -71,14 +71,9 @@ public void restartContainer() throws DockerException {
dockerClient.killContainerCmd(container.getId()).exec();
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void restartNonExistingContainer() throws DockerException, InterruptedException {
- try {
- dockerClient.restartContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.restartContainerCmd("non-existing").exec();
}
-
}
diff --git a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java
index 2b32e00c5..4bb8f2b99 100644
--- a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java
@@ -251,7 +251,7 @@ public void startContainerWithRandomPortBindings() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = InternalServerErrorException.class)
public void startContainerWithConflictingPortBindings() throws DockerException {
ExposedPort tcp22 = ExposedPort.tcp(22);
@@ -268,13 +268,7 @@ public void startContainerWithConflictingPortBindings() throws DockerException {
assertThat(container.getId(), not(isEmptyString()));
- try {
- dockerClient.startContainerCmd(container.getId()).exec();
- fail("expected InternalServerErrorException");
- } catch (InternalServerErrorException e) {
-
- }
-
+ dockerClient.startContainerCmd(container.getId()).exec();
}
@Test
@@ -412,13 +406,10 @@ public void startContainer() throws DockerException {
}
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void testStartNonExistingContainer() throws DockerException {
- try {
+
dockerClient.startContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
}
/**
diff --git a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java
index 913ed9474..7ae6a09cc 100644
--- a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java
@@ -69,21 +69,15 @@ public void testStopContainer() throws DockerException {
assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false)));
final Integer exitCode = inspectContainerResponse.getState().getExitCode();
- if (apiVersion.equals(VERSION_1_22)) {
- assertThat(exitCode, is(0));
- } else {
- assertThat(exitCode, not(0));
- }
+
+ assertThat(exitCode, is(137));
+
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void testStopNonExistingContainer() throws DockerException {
- try {
- dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java
index 94d4291d0..3bf033212 100644
--- a/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java
@@ -49,15 +49,11 @@ public void tagImage() throws Exception {
dockerClient.removeImageCmd("docker-java/busybox:" + tag).exec();
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void tagNonExistingImage() throws Exception {
- String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE);
- try {
- dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE);
+ dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java
new file mode 100644
index 000000000..2f41b67ae
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java
@@ -0,0 +1,118 @@
+package com.github.dockerjava.core.command;
+
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.exception.InternalServerErrorException;
+import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.client.AbstractDockerClientTest;
+import com.github.dockerjava.utils.ContainerUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isEmptyString;
+import static org.hamcrest.Matchers.not;
+
+@Test(groups = {"integration", "ignoreInCircleCi"})
+public class UnpauseCmdImplTest extends AbstractDockerClientTest {
+
+ public static final Logger LOG = LoggerFactory.getLogger(UnpauseCmdImplTest.class);
+
+ @BeforeTest
+ public void beforeTest() throws Exception {
+ super.beforeTest();
+ }
+
+ @AfterTest
+ public void afterTest() {
+ super.afterTest();
+ }
+
+ @BeforeMethod
+ public void beforeMethod(Method method) {
+ super.beforeMethod(method);
+ }
+
+ @AfterMethod
+ public void afterMethod(ITestResult result) {
+ super.afterMethod(result);
+ }
+
+ @Test
+ public void unpausePausedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+
+ ContainerUtils.unpauseContainer(dockerClient, container);
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseRunningContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseStoppedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.stopContainer(dockerClient, container);
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = NotFoundException.class)
+ public void unpauseNonExistingContainer() {
+
+ dockerClient.unpauseContainerCmd("non-existing").exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseCreatedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseUnpausedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java
index c230fbb02..df53d671b 100644
--- a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java
@@ -79,15 +79,15 @@ public void updateContainer() throws DockerException, IOException {
// .withCpusetCpus("0") // depends on env
.withCpusetMems("0")
.withMemory(314572800L)
- .withMemorySwap(514288000L)
+// .withMemorySwap(514288000L) Your kernel does not support swap limit capabilities, memory limited without swap.
.withMemoryReservation(209715200L)
// .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first.
.exec();
- // docker toolbox 1.10.1
- assertThat(updateResponse.getWarnings(), hasSize(1));
- assertThat(updateResponse.getWarnings().get(0),
- is("Your kernel does not support Block I/O weight. Weight discarded."));
+ // true only on docker toolbox (1.10.1)
+// assertThat(updateResponse.getWarnings(), hasSize(1));
+// assertThat(updateResponse.getWarnings().get(0),
+// is("Your kernel does not support Block I/O weight. Weight discarded."));
InspectContainerResponse inspectAfter = dockerClient.inspectContainerCmd(containerId).exec();
final HostConfig afterHostConfig = inspectAfter.getHostConfig();
@@ -102,7 +102,7 @@ public void updateContainer() throws DockerException, IOException {
assertThat(afterHostConfig.getCpusetMems(), is("0"));
assertThat(afterHostConfig.getMemoryReservation(), is(209715200L));
- assertThat(afterHostConfig.getMemorySwap(), is(514288000L));
+// assertThat(afterHostConfig.getMemorySwap(), is(514288000L));
}
diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java
index 8997a6d80..b37754a6a 100644
--- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java
+++ b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java
@@ -1,20 +1,20 @@
package com.github.dockerjava.core.dockerfile;
-import com.google.common.base.Function;
-import junit.framework.TestCase;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
+import static com.google.common.collect.Collections2.transform;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
-import static com.google.common.collect.Collections2.transform;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsInAnyOrder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
-public class DockerfileAddMultipleFilesTest extends TestCase {
+public class DockerfileAddMultipleFilesTest {
private static final Logger log = LoggerFactory.getLogger(DockerfileAddMultipleFilesTest.class);
@@ -26,13 +26,48 @@ public String apply(File file) {
};
@Test
- public void testAddMultipleFiles() throws IOException {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddMultipleFiles")
- .getFile());
+ public void nestedDirsPatterns() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/NestedDirsDockerignore");
+ Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir);
+ Dockerfile.ScannedResult result = dockerfile.parse();
+ Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES);
+
+ assertThat(filesToAdd,
+ containsInAnyOrder("Dockerfile", ".dockerignore", "README.md", "README-grand.md", "b.txt"));
+ }
+
+ @Test
+ public void effectiveIgnorePatterns() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/EffectiveDockerignorePatterns");
+ Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir);
+ Dockerfile.ScannedResult result = dockerfile.parse();
+ Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES);
+
+ assertThat(filesToAdd, containsInAnyOrder("Dockerfile", ".dockerignore", "README.md"));
+ }
+
+ @Test
+ public void ineffectiveIgnorePattern() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/IneffectiveDockerignorePattern");
+ Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir);
+ Dockerfile.ScannedResult result = dockerfile.parse();
+ Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES);
+
+ assertThat(filesToAdd, containsInAnyOrder("Dockerfile", ".dockerignore", "README.md", "README-secret.md"));
+ }
+
+ @Test
+ public void addFiles() throws IOException {
+ File baseDir = fileFromBuildTestResource("ADD/files");
Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir);
Dockerfile.ScannedResult result = dockerfile.parse();
Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES);
assertThat(filesToAdd, containsInAnyOrder("Dockerfile", "src1", "src2"));
}
+
+ private File fileFromBuildTestResource(String resource) {
+ return new File(Thread.currentThread().getContextClassLoader()
+ .getResource("buildTests/" + resource).getFile());
+ }
}
diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java
deleted file mode 100644
index 390bcf647..000000000
--- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.github.dockerjava.core.dockerfile;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-public class DockerfileTest extends TestCase {
-
- private static final Logger log = LoggerFactory.getLogger(DockerfileTest.class);
-
- @Test
- public void testAllItems() throws IOException {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("netcat").getFile());
-
- File root = baseDir.getParentFile();
-
- Map dockerfiles = new HashMap();
- Map results = new HashMap();
-
- for (File child : root.listFiles()) {
- if (new File(child, "Dockerfile").exists()) {
- Dockerfile dockerfile = new Dockerfile(new File(child, "Dockerfile"), baseDir);
- dockerfiles.put(child.getName(), dockerfile);
- }
- }
-
- for (String name : dockerfiles.keySet()) {
- log.info("Scanning {}", name);
- try {
- results.put(name, dockerfiles.get(name).parse());
- } catch (Exception ex) {
- log.error("Error in {}", name, ex);
- }
-
- }
-
- for (String name : results.keySet()) {
- log.info("Name: {} = {}", name, results.get(name));
- }
- }
-
-}
diff --git a/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java b/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java
index 44a541808..57f7aa421 100644
--- a/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java
+++ b/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java
@@ -12,6 +12,6 @@ public abstract class AbstractNettyDockerClientTest extends AbstractDockerClient
@Override
protected TestDockerCmdExecFactory initTestDockerCmdExecFactory() {
- return new TestDockerCmdExecFactory(new DockerCmdExecFactoryImpl());
+ return new TestDockerCmdExecFactory(new NettyDockerCmdExecFactory());
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/WebTargetTest.java b/src/test/java/com/github/dockerjava/netty/WebTargetTest.java
new file mode 100644
index 000000000..a462eb8b5
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/netty/WebTargetTest.java
@@ -0,0 +1,39 @@
+package com.github.dockerjava.netty;
+
+import static org.testng.Assert.assertEquals;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * @author Alexander Koshevoy
+ */
+public class WebTargetTest {
+ @Mock private ChannelProvider channelProvider;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void verifyImmutability() throws Exception {
+ WebTarget emptyWebTarget = new WebTarget(channelProvider);
+
+ WebTarget initWebTarget = emptyWebTarget.path("/containers/{id}/attach").resolveTemplate("id", "d03da378b592")
+ .queryParam("logs", "true");
+
+ WebTarget anotherWebTarget = emptyWebTarget.path("/containers/{id}/attach")
+ .resolveTemplate("id", "2cfada4e3c07").queryParam("stdin", "true");
+
+ assertEquals(new WebTarget(channelProvider), emptyWebTarget);
+
+ assertEquals(new WebTarget(channelProvider).path("/containers/d03da378b592/attach")
+ .queryParam("logs", "true"), initWebTarget);
+
+ assertEquals(new WebTarget(channelProvider).path("/containers/2cfada4e3c07/attach")
+ .queryParam("stdin", "true"), anotherWebTarget);
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java
index 7f8e66609..66219dc72 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java
@@ -1,15 +1,15 @@
package com.github.dockerjava.netty.exec;
+import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
-import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.lang.reflect.Method;
-import java.util.concurrent.TimeUnit;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
@@ -70,7 +70,7 @@ public void onNext(Frame frame) {
};
dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true)
- .withLogs(true).exec(callback).awaitCompletion(10, TimeUnit.SECONDS);
+ .withLogs(true).exec(callback).awaitCompletion(10, SECONDS);
callback.close();
assertThat(callback.toString(), containsString(snippet));
@@ -81,8 +81,11 @@ public void attachContainerWithStdin() throws Exception {
String snippet = "hello world";
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/sh", "-c", "read line && echo $line")
- .withTty(false).withStdinOpen(true).exec();
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/sh", "-c", "sleep 1 && read line && echo $line")
+ .withTty(false)
+ .withStdinOpen(true)
+ .exec();
LOG.info("Created container: {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
@@ -94,18 +97,27 @@ public void attachContainerWithStdin() throws Exception {
assertTrue(inspectContainerResponse.getState().getRunning());
AttachContainerTestCallback callback = new AttachContainerTestCallback() {
-
@Override
public void onNext(Frame frame) {
assertEquals(frame.getStreamType(), StreamType.STDOUT);
super.onNext(frame);
- };
+ }
};
- InputStream stdin = new ByteArrayInputStream((snippet + "\n").getBytes());
+ PipedOutputStream out = new PipedOutputStream();
+ PipedInputStream in = new PipedInputStream(out);
- dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true)
- .withStdIn(stdin).exec(callback).awaitCompletion(2, TimeUnit.SECONDS);
+ dockerClient.attachContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .withStdIn(in)
+ .exec(callback);
+
+ out.write((snippet + "\n").getBytes());
+ out.flush();
+
+ callback.awaitCompletion(15, SECONDS);
callback.close();
assertThat(callback.toString(), containsString(snippet));
@@ -134,8 +146,12 @@ public void onNext(Frame frame) {
};
};
- dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true)
- .exec(callback).awaitCompletion(10, TimeUnit.SECONDS);
+ dockerClient.attachContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .exec(callback)
+ .awaitCompletion(10, SECONDS);
callback.close();
// HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0);
diff --git a/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java
index 66ac1bce3..690d478f4 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java
@@ -44,14 +44,8 @@ public void testAuth() throws Exception {
assertEquals(response.getStatus(), "Login Succeeded");
}
- @Test()
+ @Test(expectedExceptions = UnauthorizedException.class)
public void testAuthInvalid() throws Exception {
-
- try {
- DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec();
- fail("Expected a UnauthorizedException caused by a bad password.");
- } catch (UnauthorizedException e) {
- assertEquals(e.getMessage(), "Wrong login/password, please try again\n");
- }
+ DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java
index 92975f38f..f567dcfc8 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java
@@ -1,11 +1,11 @@
package com.github.dockerjava.netty.exec;
+import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import java.io.File;
@@ -13,11 +13,13 @@
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Collection;
+import java.util.Collections;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.testng.ITestResult;
+import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
@@ -35,6 +37,7 @@
import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Ports;
import com.github.dockerjava.api.model.Ports.Binding;
+import com.github.dockerjava.core.RemoteApiVersion;
import com.github.dockerjava.core.command.BuildImageResultCallback;
import com.github.dockerjava.core.command.PushImageResultCallback;
import com.github.dockerjava.core.command.WaitContainerResultCallback;
@@ -65,10 +68,9 @@ public void afterMethod(ITestResult result) {
}
@Test
- public void testNginxDockerfileBuilder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nginx").getFile());
+ public void author() throws Exception {
- String imageId = buildImage(baseDir);
+ String imageId = buildImage(fileFromBuildTestResource("AUTHOR"));
InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
assertThat(inspectImageResponse, not(nullValue()));
@@ -77,27 +79,9 @@ public void testNginxDockerfileBuilder() throws Exception {
assertThat(inspectImageResponse.getAuthor(), equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\""));
}
- @Test(groups = "ignoreInCircleCi")
- public void testNonstandard1() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader()
- .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile());
-
- buildImage(baseDir);
- }
-
- @Test(groups = "ignoreInCircleCi")
- public void testNonstandard2() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nonstandard").getFile());
- File dockerFile = new File(Thread.currentThread().getContextClassLoader()
- .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile());
-
- dockerClient.buildImageCmd().withBaseDirectory(baseDir).withDockerfile(dockerFile).withNoCache(true)
- .exec(new BuildImageResultCallback()).awaitImageId();
- }
-
@Test
- public void testDockerBuilderFromTar() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFile").getFile());
+ public void buildImageFromTar() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/file");
Collection files = FileUtils.listFiles(baseDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
File tarFile = CompressArchiveUtil.archiveTARFiles(baseDir, files, UUID.randomUUID().toString());
String response = dockerfileBuild(new FileInputStream(tarFile));
@@ -105,41 +89,43 @@ public void testDockerBuilderFromTar() throws Exception {
}
@Test
- public void testDockerBuilderAddUrl() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddUrl").getFile());
+ public void onBuild() throws Exception {
+ File baseDir = fileFromBuildTestResource("ONBUILD/parent");
+
+ dockerClient.buildImageCmd(baseDir).withNoCache(true).withTag("docker-java-onbuild")
+ .exec(new BuildImageResultCallback()).awaitImageId();
+ baseDir = fileFromBuildTestResource("ONBUILD/child");
String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Docker"));
+ assertThat(response, containsString("Successfully executed testrun.sh"));
}
@Test
- public void testDockerBuilderAddFileInSubfolder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFileInSubfolder")
- .getFile());
+ public void addUrl() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/url");
String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Successfully executed testrun.sh"));
+ assertThat(response, containsString("Example Domain"));
}
@Test
- public void testDockerBuilderAddFilesViaWildcard() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFilesViaWildcard")
- .getFile());
+ public void addFileInSubfolder() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/fileInSubfolder");
String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Successfully executed testinclude1.sh"));
- assertThat(response, not(containsString("Successfully executed testinclude2.sh")));
+ assertThat(response, containsString("Successfully executed testrun.sh"));
}
@Test
- public void testDockerBuilderAddFolder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFolder").getFile());
+ public void addFilesViaWildcard() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/filesViaWildcard");
String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Successfully executed testAddFolder.sh"));
+ assertThat(response, containsString("Successfully executed testinclude1.sh"));
+ assertThat(response, not(containsString("Successfully executed testinclude2.sh")));
}
@Test
- public void testDockerBuilderEnv() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testEnv").getFile());
+ public void addFolder() throws Exception {
+ File baseDir = fileFromBuildTestResource("ADD/folder");
String response = dockerfileBuild(baseDir);
- assertThat(response, containsString("Successfully executed testrun.sh"));
+ assertThat(response, containsString("Successfully executed testAddFolder.sh"));
}
private String dockerfileBuild(InputStream tarInputStream) throws Exception {
@@ -168,80 +154,42 @@ private String execBuild(BuildImageCmd buildImageCmd) throws Exception {
}
@Test(expectedExceptions = {DockerClientException.class})
- public void testDockerfileIgnored() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileIgnored")
- .getFile());
+ public void dockerignoreDockerfileIgnored() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/DockerfileIgnored");
dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
}
@Test
- public void testDockerfileNotIgnored() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileNotIgnored")
- .getFile());
+ public void dockerignoreDockerfileNotIgnored() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/DockerfileNotIgnored");
dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
}
@Test(expectedExceptions = {DockerClientException.class})
- public void testInvalidDockerIgnorePattern() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader()
- .getResource("testInvalidDockerignorePattern").getFile());
+ public void dockerignoreInvalidDockerIgnorePattern() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/InvalidDockerignorePattern");
dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId();
}
- @Test(groups = "ignoreInCircleCi")
- public void testDockerIgnore() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerignore")
- .getFile());
+ @Test()
+ public void dockerignoreValidDockerIgnorePattern() throws Exception {
+ File baseDir = fileFromBuildTestResource("dockerignore/ValidDockerignorePattern");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("/tmp/a/a /tmp/a/c /tmp/a/d"));
}
@Test
- public void testNetCatDockerfileBuilder() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("netcat").getFile());
-
- String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback())
- .awaitImageId();
-
- assertNotNull(imageId, "Not successful in build");
-
- InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
- assertThat(inspectImageResponse, not(nullValue()));
- assertThat(inspectImageResponse.getId(), not(nullValue()));
- LOG.info("Image Inspect: {}", inspectImageResponse.toString());
-
- CreateContainerResponse container = dockerClient.createContainerCmd(inspectImageResponse.getId()).exec();
- assertThat(container.getId(), not(isEmptyString()));
- dockerClient.startContainerCmd(container.getId()).exec();
-
- InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
-
- assertThat(inspectContainerResponse.getId(), notNullValue());
- assertThat(inspectContainerResponse.getNetworkSettings().getPorts(), notNullValue());
-
- // No use as such if not running on the server
- // for (Ports.Port p : inspectContainerResponse.getNetworkSettings().getPorts().getAllPorts()) {
- // int port = Integer.valueOf(p.getHostPort());
- // LOG.info("Checking port {} is open", port);
- // assertThat(available(port), is(false));
- // }
- dockerClient.stopContainerCmd(container.getId()).withTimeout(0).exec();
-
- }
-
- @Test
- public void testAddAndCopySubstitution() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testENVSubstitution")
- .getFile());
+ public void env() throws Exception {
+ File baseDir = fileFromBuildTestResource("ENV");
String response = dockerfileBuild(baseDir);
assertThat(response, containsString("testENVSubstitution successfully completed"));
}
@Test
- public void testBuildFromPrivateRegistry() throws Exception {
+ public void fromPrivateRegistry() throws Exception {
File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("privateRegistry").getFile());
String imageId = buildImage(baseDir);
@@ -282,17 +230,13 @@ public void testBuildFromPrivateRegistry() throws Exception {
dockerClient.removeImageCmd("localhost:5000/testuser/busybox").withForce(true).exec();
- baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildFromPrivateRegistry")
- .getFile());
+ baseDir = fileFromBuildTestResource("FROM/privateRegistry");
AuthConfigurations authConfigurations = new AuthConfigurations();
authConfigurations.addConfig(authConfig);
- imageId = dockerClient.buildImageCmd(baseDir)
- .withNoCache(true)
- .withBuildAuthConfigs(authConfigurations)
- .exec(new BuildImageResultCallback())
- .awaitImageId();
+ imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildAuthConfigs(authConfigurations)
+ .exec(new BuildImageResultCallback()).awaitImageId();
inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
assertThat(inspectImageResponse, not(nullValue()));
@@ -301,8 +245,8 @@ public void testBuildFromPrivateRegistry() throws Exception {
}
@Test
- public void testBuildArgs() throws Exception {
- File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildArgs").getFile());
+ public void buildArgs() throws Exception {
+ File baseDir = fileFromBuildTestResource("buildArgs");
String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildArg("testArg", "abc")
.exec(new BuildImageResultCallback())
@@ -314,4 +258,41 @@ public void testBuildArgs() throws Exception {
assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc"));
}
+
+ @Test
+ public void labels() throws Exception {
+ if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) {
+ throw new SkipException("API version should be >= 1.23");
+ }
+
+ File baseDir = fileFromBuildTestResource("labels");
+
+ String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true)
+ .withLabels(Collections.singletonMap("test", "abc"))
+ .exec(new BuildImageResultCallback())
+ .awaitImageId();
+
+ InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec();
+ assertThat(inspectImageResponse, not(nullValue()));
+ LOG.info("Image Inspect: {}", inspectImageResponse.toString());
+
+ assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc"));
+ }
+
+ public void dockerfileNotInBaseDirectory() throws Exception {
+ File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory");
+ File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile");
+ BuildImageCmd command = dockerClient.buildImageCmd()
+ .withBaseDirectory(baseDirectory)
+ .withDockerfile(dockerfile);
+
+ String response = execBuild(command);
+
+ assertThat(response, containsString("Successfully executed testrun.sh"));
+ }
+
+ private File fileFromBuildTestResource(String resource) {
+ return new File(Thread.currentThread().getContextClassLoader()
+ .getResource("buildTests/" + resource).getFile());
+ }
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java
index 0186f4233..3d1a66333 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java
@@ -68,13 +68,10 @@ public void commit() throws DockerException {
assertThat(inspectImageResponse.getParent(), equalTo(busyboxImg.getId()));
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void commitNonExistingContainer() throws DockerException {
- try {
- dockerClient.commitCmd("non-existent").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.commitCmd("non-existent").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java
index ee1a681b6..7e290a98e 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java
@@ -3,6 +3,8 @@
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.CreateNetworkResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.exception.DockerException;
+import com.github.dockerjava.api.exception.NotFoundException;
import com.github.dockerjava.api.model.ContainerNetwork;
import com.github.dockerjava.api.model.Network;
import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
@@ -17,6 +19,10 @@
import java.lang.reflect.Method;
import java.util.Collections;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
@Test(groups = "integration")
public class ConnectToNetworkCmdExecTest extends AbstractNettyDockerClientTest {
@@ -61,38 +67,49 @@ public void connectToNetwork() throws InterruptedException {
@Test
public void connectToNetworkWithContainerNetwork() throws InterruptedException {
+ final String NETWORK_SUBNET = "10.100.101.0/24";
+ final String NETWORK_NAME = "nettyTestNetwork";
+ final String CONTAINER_IP = "10.100.101.100";
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("sleep", "9999")
+ .exec();
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
dockerClient.startContainerCmd(container.getId()).exec();
+ try {
+ dockerClient.removeNetworkCmd(NETWORK_NAME).exec();
+ } catch (DockerException ignore) {
+ }
+
CreateNetworkResponse network = dockerClient.createNetworkCmd()
- .withName("testNetwork")
+ .withName(NETWORK_NAME)
.withIpam(new Network.Ipam()
- .withConfig(new Network.Ipam.Config()
- .withSubnet("10.100.100.0/24")))
+ .withConfig(new Network.Ipam.Config()
+ .withSubnet(NETWORK_SUBNET)))
.exec();
dockerClient.connectToNetworkCmd()
.withNetworkId(network.getId())
.withContainerId(container.getId())
.withContainerNetwork(new ContainerNetwork()
- .withAliases("testing")
- .withIpamConfig(new ContainerNetwork.Ipam()
- .withIpv4Address("10.100.100.100")))
+ .withAliases("aliasName")
+ .withIpamConfig(new ContainerNetwork.Ipam()
+ .withIpv4Address(CONTAINER_IP)))
.exec();
Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec();
Network.ContainerNetworkConfig containerNetworkConfig = updatedNetwork.getContainers().get(container.getId());
assertNotNull(containerNetworkConfig);
- assertEquals(containerNetworkConfig.getIpv4Address(), "10.100.100.100/24");
+ assertThat(containerNetworkConfig.getIpv4Address(), is(CONTAINER_IP + "/24"));
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
- ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork");
+ ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get(NETWORK_NAME);
assertNotNull(testNetwork);
- assertEquals(testNetwork.getAliases(), Collections.singletonList("testing"));
- assertEquals(testNetwork.getGateway(), "10.100.100.1");
- assertEquals(testNetwork.getIpAddress(), "10.100.100.100");
+ assertThat(testNetwork.getAliases(), hasItem("aliasName"));
+ assertEquals(testNetwork.getGateway(), "10.100.101.1");
+ assertEquals(testNetwork.getIpAddress(), CONTAINER_IP);
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java
index 57c4b46a0..c21c426b5 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java
@@ -68,13 +68,10 @@ public void testContainerDiff() throws DockerException {
assertThat(testChangeLog, hasField("kind", equalTo(1)));
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void testContainerDiffWithNonExistingContainer() throws DockerException {
- try {
- dockerClient.containerDiffCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.containerDiffCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java
index caec336a2..02b56156d 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java
@@ -70,13 +70,10 @@ public void copyFromContainer() throws Exception {
assertTrue(responseAsString.length() > 0);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void copyFromNonExistingContainer() throws Exception {
- try {
- dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException ignored) {
- }
+
+ dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec();
}
@Test
diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java
index eb43b54de..d75d36ea8 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java
@@ -84,14 +84,10 @@ private void assertFileCopied(CreateContainerResponse container) throws IOExcept
}
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void copyToNonExistingContainer() throws Exception {
- try {
- dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile")
- .exec();
- fail("expected NotFoundException");
- } catch (NotFoundException ignored) {
- }
+
+ dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile").exec();
}
@Test
diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java
index b9682c592..1060ae82a 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java
@@ -1,5 +1,6 @@
package com.github.dockerjava.netty.exec;
+import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
@@ -7,7 +8,9 @@
import java.io.InputStream;
import java.lang.reflect.Method;
+import com.github.dockerjava.core.RemoteApiVersion;
import org.testng.ITestResult;
+import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
@@ -43,6 +46,10 @@ public void afterMethod(ITestResult result) {
@Test
public void copyFromContainer() throws Exception {
+ if (getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) {
+ throw new SkipException("Doesn't work since 1.24");
+ }
+
// TODO extract this into a shared method
CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
.withName("docker-java-itest-copyFromContainer").withCmd("touch", "/copyFromContainer").exec();
@@ -62,12 +69,9 @@ public void copyFromContainer() throws Exception {
assertTrue(responseAsString.length() > 0);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void copyFromNonExistingContainer() throws Exception {
- try {
- dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException ignored) {
- }
+
+ dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java
index 3dbe21f16..aa97b8839 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java
@@ -2,6 +2,7 @@
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.CreateNetworkResponse;
+import com.github.dockerjava.api.command.CreateVolumeResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.exception.ConflictException;
import com.github.dockerjava.api.exception.DockerException;
@@ -9,18 +10,22 @@
import com.github.dockerjava.api.model.ContainerNetwork;
import com.github.dockerjava.api.model.Device;
import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.Link;
import com.github.dockerjava.api.model.LogConfig;
import com.github.dockerjava.api.model.Network;
import com.github.dockerjava.api.model.Ports;
import com.github.dockerjava.api.model.Ports.Binding;
+import com.github.dockerjava.core.RemoteApiVersion;
import com.github.dockerjava.api.model.RestartPolicy;
import com.github.dockerjava.api.model.Ulimit;
import com.github.dockerjava.api.model.Volume;
import com.github.dockerjava.api.model.VolumesFrom;
import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
+import org.apache.commons.io.FileUtils;
import org.testng.ITestResult;
+import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
@@ -38,11 +43,13 @@
import static com.github.dockerjava.api.model.Capability.MKNOD;
import static com.github.dockerjava.api.model.Capability.NET_ADMIN;
+import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItemInArray;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyString;
@@ -135,6 +142,39 @@ public void createContainerWithReadOnlyVolume() throws DockerException {
// assertFalse(inspectContainerResponse.getMounts().get(0).getRW());
}
+ @Test
+ public void createContainerWithNoCopyVolumes() throws DockerException {
+ final RemoteApiVersion apiVersion = getVersion(dockerClient);
+
+ if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) {
+ throw new SkipException("API version should be >= 1.23");
+ }
+
+ Volume volume1 = new Volume("/opt/webapp1");
+ String container1Name = UUID.randomUUID().toString();
+
+ CreateVolumeResponse volumeResponse = dockerClient.createVolumeCmd().withName("webapp1").exec();
+ assertThat(volumeResponse.getName(), equalTo("webapp1"));
+ assertThat(volumeResponse.getDriver(), equalTo("local"));
+ assertThat(volumeResponse.getMountpoint(), containsString("/webapp1/"));
+
+ Bind bind1 = new Bind("webapp1", volume1, true);
+
+ CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999")
+ .withName(container1Name)
+ .withBinds(bind1).exec();
+ LOG.info("Created container1 {}", container1.toString());
+
+ InspectContainerResponse inspectContainerResponse1 = dockerClient.inspectContainerCmd(container1.getId()).exec();
+
+ assertThat(Arrays.asList(inspectContainerResponse1.getHostConfig().getBinds()), contains(bind1));
+ assertThat(inspectContainerResponse1, mountedVolumes(contains(volume1)));
+
+ assertThat(inspectContainerResponse1.getMounts().get(0).getDestination(), equalTo(volume1));
+ assertThat(inspectContainerResponse1.getMounts().get(0).getMode(), equalTo("rw,nocopy"));
+ assertThat(inspectContainerResponse1.getMounts().get(0).getRW(), equalTo(true));
+ }
+
@Test
public void createContainerWithVolumesFrom() throws DockerException {
@@ -189,9 +229,12 @@ public void createContainerWithVolumesFrom() throws DockerException {
@Test
public void createContainerWithEnv() throws Exception {
+ final String testVariable = "VARIABLE=success";
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withEnv("VARIABLE=success")
- .withCmd("env").exec();
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withEnv(testVariable)
+ .withCmd("env")
+ .exec();
LOG.info("Created container {}", container.toString());
@@ -199,11 +242,11 @@ public void createContainerWithEnv() throws Exception {
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
- assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), containsInAnyOrder("VARIABLE=success"));
+ assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), hasItem(testVariable));
dockerClient.startContainerCmd(container.getId()).exec();
- assertThat(containerLog(container.getId()), containsString("VARIABLE=success"));
+ assertThat(containerLog(container.getId()), containsString(testVariable));
}
@Test
@@ -364,7 +407,7 @@ public void createContainerWithAlias() throws DockerException {
.exec();
ContainerNetwork aliasNet = inspectContainerResponse.getNetworkSettings().getNetworks().get("aliasNet");
- assertEquals(aliasNet.getAliases(), Collections.singletonList("server"));
+ assertThat(aliasNet.getAliases(), hasItem("server"));
}
@Test
@@ -672,4 +715,20 @@ public void createContainerWithCgroupParent() throws DockerException {
assertThat(inspectContainer.getHostConfig().getCgroupParent(), is("/parent"));
}
+
+ @SuppressWarnings("Duplicates")
+ @Test
+ public void createContainerWithShmSize() throws DockerException {
+ HostConfig hostConfig = new HostConfig().withShmSize(96 * FileUtils.ONE_MB);
+ CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE)
+ .withHostConfig(hostConfig).withCmd("true").exec();
+
+ LOG.info("Created container {}", container.toString());
+
+ assertThat(container.getId(), not(isEmptyString()));
+
+ InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
+
+ assertEquals(inspectContainerResponse.getHostConfig().getShmSize(), hostConfig.getShmSize());
+ }
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java
index a634e2562..2a446569d 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java
@@ -22,8 +22,6 @@
@Test(groups = "integration")
public class EventsCmdExecTest extends AbstractNettyDockerClientTest {
- private static int KNOWN_NUM_EVENTS = 4;
-
private static String getEpochTime() {
return String.valueOf(System.currentTimeMillis() / 1000);
}
@@ -48,9 +46,6 @@ public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
- /*
- * This specific test may fail with boot2docker as time may not in sync with host system
- */
@Test
public void testEventStreamTimeBound() throws Exception {
// Don't include other tests events
@@ -60,82 +55,84 @@ public void testEventStreamTimeBound() throws Exception {
int expectedEvents = generateEvents();
String endTime = getEpochTime();
- CountDownLatch countDownLatch = new CountDownLatch(expectedEvents);
- EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch);
-
- dockerClient.eventsCmd().withSince(startTime).withUntil(endTime).exec(eventCallback);
-
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
-
- eventCallback.close();
-
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
- }
-
- @Test
- public void testEventStreaming1() throws Exception {
- // Don't include other tests events
- TimeUnit.SECONDS.sleep(1);
-
- CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS);
- EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch);
+ EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
- dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback);
+ dockerClient.eventsCmd()
+ .withSince(startTime)
+ .withUntil(endTime)
+ .exec(eventCallback);
- generateEvents();
-
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
+ List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
- eventCallback.close();
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
+ // we may receive more events as expected
+ assertTrue(events.size() >= expectedEvents, "Received events: " + events);
}
@Test
- public void testEventStreaming2() throws Exception {
+ public void testEventStreaming() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
+
+ String startTime = getEpochTime();
+ int expectedEvents = generateEvents();
- CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS);
- EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch);
+ EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
- dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback);
+ dockerClient.eventsCmd()
+ .withSince(startTime)
+ .exec(eventCallback);
generateEvents();
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
-
- eventCallback.close();
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
+ List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
+
+ // we may receive more events as expected
+ assertTrue(events.size() >= expectedEvents, "Received events: " + events);
}
+
public void testEventStreamingWithFilter() throws Exception {
// Don't include other tests events
TimeUnit.SECONDS.sleep(1);
+
+ String startTime = getEpochTime();
+ int expectedEvents = 1;
- CountDownLatch countDownLatch = new CountDownLatch(1);
- EventsTestCallback eventCallback = dockerClient.eventsCmd().withEventFilter("start")
- .exec(new EventsTestCallback(countDownLatch));
+ EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents);
+
+ dockerClient.eventsCmd()
+ .withSince(startTime)
+ .withEventFilter("start")
+ .exec(eventCallback);
generateEvents();
- Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS);
-
- eventCallback.close();
- assertTrue(zeroCount, "Received only: " + eventCallback.getEvents());
+ List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES);
+
+ // we should get exactly one "start" event here
+ assertEquals(events.size(), expectedEvents, "Received events: " + events);
}
/**
- * This method generates {#link KNOWN_NUM_EVENTS} events
+ * This method generates some events and returns the number of events being generated
*/
private int generateEvents() throws Exception {
- String testImage = "busybox";
+ String testImage = "busybox:latest";
dockerClient.pullImageCmd(testImage).exec(new PullImageResultCallback()).awaitSuccess();
-
CreateContainerResponse container = dockerClient.createContainerCmd(testImage).withCmd("sleep", "9999").exec();
dockerClient.startContainerCmd(container.getId()).exec();
- dockerClient.stopContainerCmd(container.getId()).exec();
- return KNOWN_NUM_EVENTS;
+ dockerClient.stopContainerCmd(container.getId()).withTimeout(1).exec();
+
+ // generates 5 events with remote api 1.24:
+
+ // Event[status=pull,id=busybox:latest,from=,node=,type=IMAGE,action=pull,actor=com.github.dockerjava.api.model.EventActor@417db6d7[id=busybox:latest,attributes={name=busybox}],time=1473455186,timeNano=1473455186436681587]
+ // Event[status=create,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=create,actor=com.github.dockerjava.api.model.EventActor@40bcec[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186470713257]
+ // Event[status=,id=,from=,node=,type=NETWORK,action=connect,actor=com.github.dockerjava.api.model.EventActor@318a1b01[id=10870ceb13abb7cf841ea68868472da881b33c8ed08d2cde7dbb39d7c24d1d27,attributes={container=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c, name=bridge, type=bridge}],time=1473455186,timeNano=1473455186544318466]
+ // Event[status=start,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=start,actor=com.github.dockerjava.api.model.EventActor@606f43a3[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186786163819]
+ // Event[status=kill,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=kill,actor=com.github.dockerjava.api.model.EventActor@72a9ffcf[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport, signal=15}],time=1473455186,timeNano=1473455186792963392]
+
+ return 5;
}
private class EventsTestCallback extends EventsResultCallback {
@@ -144,18 +141,25 @@ private class EventsTestCallback extends EventsResultCallback {
private final List events = new ArrayList();
- public EventsTestCallback(CountDownLatch countDownLatch) {
- this.countDownLatch = countDownLatch;
+ public EventsTestCallback(int expextedEvents) {
+ this.countDownLatch = new CountDownLatch(expextedEvents);
}
public void onNext(Event event) {
LOG.info("Received event #{}: {}", countDownLatch.getCount(), event);
- countDownLatch.countDown();
events.add(event);
+ countDownLatch.countDown();
}
-
- public List getEvents() {
- return new ArrayList(events);
+
+ public List awaitExpectedEvents(long timeout, TimeUnit unit ) {
+ try {
+ countDownLatch.await(timeout, unit);
+ close();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return new ArrayList(events);
}
}
}
+
diff --git a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java
index 2938ac8c0..52db7fe44 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java
@@ -1,5 +1,8 @@
package com.github.dockerjava.netty.exec;
+import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22;
+import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_23;
+import static com.github.dockerjava.utils.TestUtils.getVersion;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
@@ -12,6 +15,7 @@
import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;
+import com.github.dockerjava.core.RemoteApiVersion;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
@@ -46,7 +50,7 @@ public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
- @Test(groups = "ignoreInCircleCi")
+ @Test()
public void execStart() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
@@ -58,9 +62,14 @@ public void execStart() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
- .withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec();
- dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false)
- .exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
+ .withAttachStdout(true)
+ .withCmd("touch", "/execStartTest.log")
+ .exec();
+
+ dockerClient.execStartCmd(execCreateCmdResponse.getId())
+ .withDetach(false)
+ .exec(new ExecStartResultCallback(System.out, System.err))
+ .awaitCompletion();
InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec();
@@ -73,7 +82,7 @@ public void execStart() throws Exception {
assertTrue(responseAsString.length() > 0);
}
- @Test(groups = "ignoreInCircleCi")
+ @Test()
public void execStartAttached() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
@@ -85,9 +94,14 @@ public void execStartAttached() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
- .withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec();
- dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false)
- .exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion();
+ .withAttachStdout(true)
+ .withCmd("touch", "/execStartTest.log")
+ .exec();
+
+ dockerClient.execStartCmd(execCreateCmdResponse.getId())
+ .withDetach(false)
+ .exec(new ExecStartResultCallback(System.out, System.err))
+ .awaitCompletion();
InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec();
Boolean bytesAvailable = response.available() > 0;
@@ -99,7 +113,7 @@ public void execStartAttached() throws Exception {
assertTrue(responseAsString.length() > 0);
}
- @Test(groups = "ignoreInCircleCi")
+ @Test()
public void execStartAttachStdin() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
@@ -115,14 +129,23 @@ public void execStartAttachStdin() throws Exception {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
- .withAttachStdout(true).withAttachStdin(true).withCmd("cat").exec();
- boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).withStdIn(stdin)
- .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS);
+ .withAttachStdout(true)
+ .withAttachStdin(true)
+ .withCmd("cat")
+ .exec();
+
+ boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId())
+ .withDetach(false)
+ .withTty(true)
+ .withStdIn(stdin)
+ .exec(new ExecStartResultCallback(stdout, System.err))
+ .awaitCompletion(5, TimeUnit.SECONDS);
assertTrue(completed, "The process was not finished.");
assertEquals(stdout.toString("UTF-8"), "STDIN\n");
}
+ @Test()
public void execStartAttachStdinToShell() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
@@ -156,7 +179,7 @@ public void execStartAttachStdinToShell() throws Exception {
assertThat(stdout.toString(), containsString("etc\n"));
}
- @Test(groups = "ignoreInCircleCi")
+ @Test()
public void execStartNotAttachedStdin() throws Exception {
String containerName = "generated_" + new SecureRandom().nextInt();
@@ -172,11 +195,24 @@ public void execStartNotAttachedStdin() throws Exception {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId())
- .withAttachStdout(true).withAttachStdin(false).withCmd("/bin/sh").exec();
- boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withStdIn(stdin)
- .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS);
+ .withAttachStdout(true)
+ .withAttachStdin(false)
+ .withCmd("/bin/sh")
+ .exec();
+
+ boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId())
+ .withDetach(false)
+ .withStdIn(stdin)
+ .exec(new ExecStartResultCallback(stdout, System.err))
+ .awaitCompletion(5, TimeUnit.SECONDS);
- assertTrue(completed, "The process was not finished.");
assertEquals(stdout.toString(), "");
+
+ if (getVersion(dockerClient).isGreaterOrEqual(VERSION_1_23)) {
+ assertFalse(completed, "The process was not finished.");
+ } else {
+ assertTrue(completed, "with v1.22 of the remote api the server closed the connection when no stdin " +
+ "was attached while exec create, so completed was true");
+ }
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java
index 867373e63..d354c8df3 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java
@@ -67,14 +67,10 @@ public void killContainer() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void killNonExistingContainer() throws DockerException {
- try {
- dockerClient.killContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.killContainerCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java
new file mode 100644
index 000000000..d978f5662
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java
@@ -0,0 +1,76 @@
+package com.github.dockerjava.netty.exec;
+
+import com.github.dockerjava.api.model.Image;
+
+import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
+import com.github.dockerjava.utils.TestResources;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+@Test(groups = "integration")
+public class LoadImageCmdExecTest extends AbstractNettyDockerClientTest {
+
+ private String expectedImageId;
+
+ @BeforeTest
+ public void beforeTest() throws Exception {
+ super.beforeTest();
+ }
+
+ @AfterTest
+ public void afterTest() {
+ super.afterTest();
+ }
+
+ @BeforeMethod
+ public void beforeMethod(Method method) {
+ super.beforeMethod(method);
+ expectedImageId = "sha256:56031f66eb0cef2e2e5cb2d1dabafaa0ebcd0a18a507d313b5bdb8c0472c5eba";
+ if (findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec()) != null) {
+ dockerClient.removeImageCmd(expectedImageId).exec();
+ }
+ }
+
+ @AfterMethod
+ public void afterMethod(ITestResult result) {
+ dockerClient.removeImageCmd(expectedImageId).exec();
+ super.afterMethod(result);
+ }
+
+ @Test
+ public void loadImageFromTar() throws Exception {
+ try (InputStream uploadStream = Files.newInputStream(TestResources.getApiImagesLoadTestTarball())) {
+ dockerClient.loadImageCmd(uploadStream).exec();
+ }
+
+ final Image image = findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec());
+
+ assertThat("Can't find expected image after loading from a tar archive!", image, notNullValue());
+ assertThat("Image after loading from a tar archive has wrong tags!",
+ asList(image.getRepoTags()), equalTo(singletonList("docker-java/load:1.0")));
+ }
+
+ private Image findImageWithId(final String id, final List images) {
+ for (Image image : images) {
+ if (id.equals(image.getId())) {
+ return image;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java
index 310994755..fe408ac18 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java
@@ -8,6 +8,7 @@
import java.io.IOException;
import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
@@ -18,6 +19,7 @@
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.api.model.StreamType;
import com.github.dockerjava.core.command.WaitContainerResultCallback;
import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
@@ -45,31 +47,65 @@ public void afterMethod(ITestResult result) {
}
@Test
- public void asyncLogContainer() throws Exception {
+ public void asyncLogContainerWithTtyEnabled() throws Exception {
- String snippet = "hello world";
-
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet)
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done")
+ .withTty(true)
.exec();
LOG.info("Created container: {}", container.toString());
assertThat(container.getId(), not(isEmptyString()));
- dockerClient.startContainerCmd(container.getId()).exec();
+ dockerClient.startContainerCmd(container.getId())
+ .exec();
- int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback())
- .awaitStatusCode();
+ LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true);
- assertThat(exitCode, equalTo(0));
+ // this essentially test the since=0 case
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .withTailAll()
+ .exec(loggingCallback);
- LogContainerTestCallback loggingCallback = new LogContainerTestCallback();
+ loggingCallback.awaitCompletion(3, TimeUnit.SECONDS);
+
+ assertTrue(loggingCallback.toString().contains("hello"));
+
+ assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.RAW);
+ }
+
+ @Test
+ public void asyncLogContainerWithTtyDisabled() throws Exception {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done")
+ .withTty(false)
+ .exec();
+
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.startContainerCmd(container.getId())
+ .exec();
+
+ LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true);
// this essentially test the since=0 case
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withFollowStream(true)
+ .withTailAll()
+ .exec(loggingCallback);
- loggingCallback.awaitCompletion();
+ loggingCallback.awaitCompletion(3, TimeUnit.SECONDS);
- assertTrue(loggingCallback.toString().contains(snippet));
+ assertTrue(loggingCallback.toString().contains("hello"));
+
+ assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.STDOUT);
}
@Test
@@ -106,7 +142,8 @@ public void asyncMultipleLogContainer() throws Exception {
String snippet = "hello world";
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet)
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/echo", snippet)
.exec();
LOG.info("Created container: {}", container.toString());
@@ -114,26 +151,36 @@ public void asyncMultipleLogContainer() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
- int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback())
+ int exitCode = dockerClient.waitContainerCmd(container.getId())
+ .exec(new WaitContainerResultCallback())
.awaitStatusCode();
assertThat(exitCode, equalTo(0));
LogContainerTestCallback loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .exec(loggingCallback);
loggingCallback.close();
loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .exec(loggingCallback);
loggingCallback.close();
loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback);
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .exec(loggingCallback);
loggingCallback.awaitCompletion();
@@ -144,7 +191,8 @@ public void asyncMultipleLogContainer() throws Exception {
public void asyncLogContainerWithSince() throws Exception {
String snippet = "hello world";
- CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet)
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox")
+ .withCmd("/bin/echo", snippet)
.exec();
LOG.info("Created container: {}", container.toString());
@@ -154,19 +202,22 @@ public void asyncLogContainerWithSince() throws Exception {
dockerClient.startContainerCmd(container.getId()).exec();
- int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback())
+ int exitCode = dockerClient.waitContainerCmd(container.getId())
+ .exec(new WaitContainerResultCallback())
.awaitStatusCode();
assertThat(exitCode, equalTo(0));
LogContainerTestCallback loggingCallback = new LogContainerTestCallback();
- dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withSince(timestamp)
+ dockerClient.logContainerCmd(container.getId())
+ .withStdErr(true)
+ .withStdOut(true)
+ .withSince(timestamp)
.exec(loggingCallback);
loggingCallback.awaitCompletion();
assertThat(loggingCallback.toString(), containsString(snippet));
}
-
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java b/src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java
new file mode 100644
index 000000000..612c3efd2
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java
@@ -0,0 +1,103 @@
+package com.github.dockerjava.netty.exec;
+
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.exception.InternalServerErrorException;
+import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
+import com.github.dockerjava.utils.ContainerUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isEmptyString;
+import static org.hamcrest.Matchers.not;
+
+@Test(groups = {"integration", "ignoreInCircleCi"})
+public class PauseCmdImplTest extends AbstractNettyDockerClientTest {
+
+ public static final Logger LOG = LoggerFactory.getLogger(PauseCmdImplTest.class);
+
+ @BeforeTest
+ public void beforeTest() throws Exception {
+ super.beforeTest();
+ }
+
+ @AfterTest
+ public void afterTest() {
+ super.afterTest();
+ }
+
+ @BeforeMethod
+ public void beforeMethod(Method method) {
+ super.beforeMethod(method);
+ }
+
+ @AfterMethod
+ public void afterMethod(ITestResult result) {
+ super.afterMethod(result);
+ }
+
+ @Test
+ public void pauseRunningContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+ }
+
+ @Test(expectedExceptions = NotFoundException.class)
+ public void pauseNonExistingContainer() {
+
+ dockerClient.pauseContainerCmd("non-existing").exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void pauseStoppedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.stopContainer(dockerClient, container);
+
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void pausePausedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void pauseCreatedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java
index 777cc8eed..73e99af6d 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java
@@ -21,7 +21,7 @@
import com.github.dockerjava.core.command.PushImageResultCallback;
import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
-@Test(groups = "integration")
+@Test(groups = {"integration", "integration-auth"})
public class PushImageCmdExecTest extends AbstractNettyDockerClientTest {
public static final Logger LOG = LoggerFactory.getLogger(PushImageCmdExecTest.class);
diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java
index ffe456c09..1e7abebdb 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java
@@ -69,13 +69,10 @@ public void removeContainer() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeNonExistingContainer() throws DockerException {
- try {
- dockerClient.removeContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.removeContainerCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java
index e2f69ac1e..857bec714 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java
@@ -74,14 +74,10 @@ public void removeImage() throws DockerException, InterruptedException {
assertThat(containers, matcher);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeNonExistingImage() throws DockerException, InterruptedException {
- try {
- dockerClient.removeImageCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.removeImageCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java
index 9fda49f21..f8e7d26ca 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java
@@ -64,13 +64,10 @@ public void removeNetwork() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeNonExistingContainer() throws DockerException {
- try {
- dockerClient.removeNetworkCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.removeNetworkCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java
index 59aafde67..d7995861c 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java
@@ -41,7 +41,7 @@ public void afterMethod(ITestResult result) {
super.afterMethod(result);
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void removeVolume() throws DockerException {
String volumeName = "volume1";
@@ -55,11 +55,6 @@ public void removeVolume() throws DockerException {
dockerClient.removeVolumeCmd(volumeName).exec();
- try {
- dockerClient.inspectVolumeCmd(volumeName).exec();
- fail("Expected NotFoundException");
- } catch (NotFoundException e) {
- // just ignore
- }
+ dockerClient.inspectVolumeCmd(volumeName).exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java
index 3360057a8..3b1ada5c2 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java
@@ -71,14 +71,10 @@ public void restartContainer() throws DockerException {
dockerClient.killContainerCmd(container.getId()).exec();
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void restartNonExistingContainer() throws DockerException, InterruptedException {
- try {
- dockerClient.restartContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.restartContainerCmd("non-existing").exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java
index 0527b793f..a2fab38a7 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java
@@ -47,8 +47,9 @@ public void afterMethod(ITestResult result) {
@Test
public void saveImage() throws Exception {
- InputStream image = IOUtils.toBufferedInputStream(dockerClient.saveImageCmd("busybox").exec());
- assertThat(image.available(), greaterThan(0));
+ try (InputStream image = dockerClient.saveImageCmd("busybox").exec()) {
+ assertThat(image.available(), greaterThan(0));
+ }
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java
index f4a36c2b1..eed82fcd9 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java
@@ -254,7 +254,7 @@ public void startContainerWithRandomPortBindings() throws DockerException {
}
- @Test
+ @Test(expectedExceptions = InternalServerErrorException.class)
public void startContainerWithConflictingPortBindings() throws DockerException {
ExposedPort tcp22 = ExposedPort.tcp(22);
@@ -271,13 +271,7 @@ public void startContainerWithConflictingPortBindings() throws DockerException {
assertThat(container.getId(), not(isEmptyString()));
- try {
- dockerClient.startContainerCmd(container.getId()).exec();
- fail("expected InternalServerErrorException");
- } catch (InternalServerErrorException e) {
-
- }
-
+ dockerClient.startContainerCmd(container.getId()).exec();
}
@Test
@@ -415,13 +409,10 @@ public void startContainer() throws DockerException {
}
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void testStartNonExistingContainer() throws DockerException {
- try {
- dockerClient.startContainerCmd("non-existing").exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+
+ dockerClient.startContainerCmd("non-existing").exec();
}
/**
diff --git a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java
index b3f545a42..063bcee30 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java
@@ -61,7 +61,7 @@ public void testStopContainer() throws DockerException {
dockerClient.startContainerCmd(container.getId()).exec();
LOG.info("Stopping container: {}", container.getId());
- dockerClient.stopContainerCmd(container.getId()).withTimeout(2).exec();
+ dockerClient.stopContainerCmd(container.getId()).withTimeout(10).exec();
InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
LOG.info("Container Inspect: {}", inspectContainerResponse.toString());
@@ -69,21 +69,15 @@ public void testStopContainer() throws DockerException {
assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false)));
final Integer exitCode = inspectContainerResponse.getState().getExitCode();
- if (apiVersion.equals(VERSION_1_22)) {
- assertThat(exitCode, is(0));
- } else {
- assertThat(exitCode, not(0));
- }
+
+ assertThat(exitCode, is(137));
+
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void testStopNonExistingContainer() throws DockerException {
- try {
- dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ dockerClient.stopContainerCmd("non-existing").withTimeout(10).exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java
index bbab169ef..6c84775ee 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java
@@ -49,15 +49,11 @@ public void tagImage() throws Exception {
dockerClient.removeImageCmd("docker-java/busybox:" + tag).exec();
}
- @Test
+ @Test(expectedExceptions = NotFoundException.class)
public void tagNonExistingImage() throws Exception {
- String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE);
- try {
- dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec();
- fail("expected NotFoundException");
- } catch (NotFoundException e) {
- }
+ String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE);
+ dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec();
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java b/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java
new file mode 100644
index 000000000..cb30babc4
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java
@@ -0,0 +1,118 @@
+package com.github.dockerjava.netty.exec;
+
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.exception.InternalServerErrorException;
+import com.github.dockerjava.api.exception.NotFoundException;
+import com.github.dockerjava.netty.AbstractNettyDockerClientTest;
+import com.github.dockerjava.utils.ContainerUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isEmptyString;
+import static org.hamcrest.Matchers.not;
+
+@Test(groups = {"integration", "ignoreInCircleCi"})
+public class UnpauseCmdImplTest extends AbstractNettyDockerClientTest {
+
+ public static final Logger LOG = LoggerFactory.getLogger(UnpauseCmdImplTest.class);
+
+ @BeforeTest
+ public void beforeTest() throws Exception {
+ super.beforeTest();
+ }
+
+ @AfterTest
+ public void afterTest() {
+ super.afterTest();
+ }
+
+ @BeforeMethod
+ public void beforeMethod(Method method) {
+ super.beforeMethod(method);
+ }
+
+ @AfterMethod
+ public void afterMethod(ITestResult result) {
+ super.afterMethod(result);
+ }
+
+ @Test
+ public void unpausePausedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+
+ ContainerUtils.unpauseContainer(dockerClient, container);
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseRunningContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseStoppedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.stopContainer(dockerClient, container);
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = NotFoundException.class)
+ public void unpauseNonExistingContainer() {
+
+ dockerClient.unpauseContainerCmd("non-existing").exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseCreatedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+
+ @Test(expectedExceptions = InternalServerErrorException.class)
+ public void unpauseUnpausedContainer() {
+
+ CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec();
+ LOG.info("Created container: {}", container.toString());
+ assertThat(container.getId(), not(isEmptyString()));
+
+ ContainerUtils.startContainer(dockerClient, container);
+
+ ContainerUtils.pauseContainer(dockerClient, container);
+
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java
index e2907dc8a..681839c17 100644
--- a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java
+++ b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java
@@ -78,15 +78,15 @@ public void updateContainer() throws DockerException, IOException {
// .withCpusetCpus("0") // depends on env
.withCpusetMems("0")
.withMemory(314572800L)
- .withMemorySwap(514288000L)
+// .withMemorySwap(514288000L) Your kernel does not support swap limit capabilities, memory limited without swap.
.withMemoryReservation(209715200L)
// .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first.
.exec();
- // docker toolbox 1.10.1
- assertThat(updateResponse.getWarnings(), hasSize(1));
- assertThat(updateResponse.getWarnings().get(0),
- is("Your kernel does not support Block I/O weight. Weight discarded."));
+ // found only on docker toolbox (1.10.1)
+// assertThat(updateResponse.getWarnings(), hasSize(1));
+// assertThat(updateResponse.getWarnings().get(0),
+// is("Your kernel does not support Block I/O weight. Weight discarded."));
InspectContainerResponse inspectAfter = dockerClient.inspectContainerCmd(containerId).exec();
final HostConfig afterHostConfig = inspectAfter.getHostConfig();
@@ -101,7 +101,7 @@ public void updateContainer() throws DockerException, IOException {
assertThat(afterHostConfig.getCpusetMems(), is("0"));
assertThat(afterHostConfig.getMemoryReservation(), is(209715200L));
- assertThat(afterHostConfig.getMemorySwap(), is(514288000L));
+// assertThat(afterHostConfig.getMemorySwap(), is(514288000L));
}
}
diff --git a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java
index 6652f3eba..eea9ddc0f 100644
--- a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java
+++ b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java
@@ -1,13 +1,21 @@
package com.github.dockerjava.netty.handler;
+import static com.github.dockerjava.netty.handler.HttpResponseStreamHandler.HttpResponseInputStream;
+import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
-import java.io.InputStream;
-
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
import org.apache.commons.io.IOUtils;
import org.mockito.Mockito;
import org.testng.annotations.Test;
@@ -25,9 +33,81 @@ public void testNoBytesSkipped() throws Exception {
ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
ByteBuf buffer = generateByteBuf();
streamHandler.channelRead0(ctx, buffer);
- streamHandler.channelReadComplete(ctx);
+ streamHandler.channelInactive(ctx);
+
+ try (InputStream inputStream = callback.getInputStream()) {
+ assertTrue(IOUtils.contentEquals(inputStream, new ByteBufInputStream(buffer)));
+ }
+ }
+
+ @Test
+ public void testReadByteByByte() throws Exception {
+ ResultCallbackTest callback = new ResultCallbackTest();
+ HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback);
+ ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
+ ByteBuf buffer = generateByteBuf();
+ streamHandler.channelRead0(ctx, buffer);
+ streamHandler.channelInactive(ctx);
+
+ try (InputStream inputStream = callback.getInputStream()) {
+ for (int i = 0; i < buffer.readableBytes(); i++) {
+ int b = inputStream.read();
+ assertEquals(b, buffer.getByte(i));
+ }
+ assertTrue(inputStream.read() == -1);
+ }
+ }
+
+ @Test
+ public void testCloseResponseStreamBeforeWrite() throws Exception {
+ HttpResponseInputStream inputStream = new HttpResponseInputStream();
+ ByteBuf buffer = generateByteBuf();
+
+ inputStream.write(buffer);
+ inputStream.close();
+ inputStream.write(buffer);
+ }
+
+ @Test
+ public void testCloseResponseStreamOnWrite() throws Exception {
+ final HttpResponseInputStream inputStream = new HttpResponseInputStream();
+
+ final ByteBuf buffer = generateByteBuf();
+
+ final CountDownLatch firstWrite = new CountDownLatch(1);
+
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ Future> submit = executor.submit(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ inputStream.write(buffer);
+ firstWrite.countDown();
+ inputStream.write(buffer);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ firstWrite.await();
+ assertTrue(inputStream.available() > 0);
+
+ // second write should have started
+ Thread.sleep(500L);
+ inputStream.close();
+
+ submit.get();
+ }
+
+ @Test(expectedExceptions = IOException.class)
+ public void testReadClosedResponseStream() throws Exception {
+ HttpResponseInputStream inputStream = new HttpResponseInputStream();
+ ByteBuf buffer = generateByteBuf();
- assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer)));
+ inputStream.write(buffer);
+ inputStream.close();
+ inputStream.read();
}
private ByteBuf generateByteBuf() {
@@ -46,7 +126,7 @@ public void onNext(InputStream stream) {
this.stream = stream;
}
- public InputStream getInputStream() {
+ private InputStream getInputStream() {
return stream;
}
}
diff --git a/src/test/java/com/github/dockerjava/utils/ContainerUtils.java b/src/test/java/com/github/dockerjava/utils/ContainerUtils.java
new file mode 100644
index 000000000..206be0693
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/utils/ContainerUtils.java
@@ -0,0 +1,70 @@
+package com.github.dockerjava.utils;
+
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Container cmd utils
+ */
+public class ContainerUtils {
+
+ private ContainerUtils() {
+ }
+
+ /**
+ * Starts container and ensures that it running
+ *
+ * @param dockerClient docker client
+ * @param container container
+ */
+ public static void startContainer(DockerClient dockerClient, CreateContainerResponse container) {
+ dockerClient.startContainerCmd(container.getId()).exec();
+
+ InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
+ assertThat(inspectContainerResponse.getState().getRunning(), is(true));
+ }
+
+ /**
+ * Pauses container and ensures that it paused
+ *
+ * @param dockerClient docker client
+ * @param container container
+ */
+ public static void pauseContainer(DockerClient dockerClient, CreateContainerResponse container) {
+ dockerClient.pauseContainerCmd(container.getId()).exec();
+
+ InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
+ assertThat(inspectContainerResponse.getState().getPaused(), is(true));
+ }
+
+ /**
+ * Stops container and ensures that it stopped
+ *
+ * @param dockerClient docker client
+ * @param container container
+ */
+ public static void stopContainer(DockerClient dockerClient, CreateContainerResponse container) {
+ dockerClient.stopContainerCmd(container.getId()).exec();
+
+ InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
+ assertThat(inspectContainerResponse.getState().getRunning(), is(false));
+ }
+
+ /**
+ * Unpauses container and ensures that it unpaused (running)
+ *
+ * @param dockerClient docker client
+ * @param container container
+ */
+ public static void unpauseContainer(DockerClient dockerClient, CreateContainerResponse container) {
+ dockerClient.unpauseContainerCmd(container.getId()).exec();
+
+ InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec();
+ assertThat(inspectContainerResponse.getState().getPaused(), is(false));
+ assertThat(inspectContainerResponse.getState().getRunning(), is(true));
+ }
+}
diff --git a/src/test/java/com/github/dockerjava/utils/TestResources.java b/src/test/java/com/github/dockerjava/utils/TestResources.java
new file mode 100644
index 000000000..35ece680f
--- /dev/null
+++ b/src/test/java/com/github/dockerjava/utils/TestResources.java
@@ -0,0 +1,14 @@
+package com.github.dockerjava.utils;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class TestResources {
+
+ private TestResources() {
+ }
+
+ public static Path getApiImagesLoadTestTarball() {
+ return Paths.get("src/test/resources/api/images/load/image.tar");
+ }
+}
diff --git a/src/test/resources/api/images/load/image.tar b/src/test/resources/api/images/load/image.tar
new file mode 100644
index 000000000..6f2f08f9e
Binary files /dev/null and b/src/test/resources/api/images/load/image.tar differ
diff --git a/src/test/resources/testAddFile/Dockerfile b/src/test/resources/buildTests/ADD/file/Dockerfile
similarity index 100%
rename from src/test/resources/testAddFile/Dockerfile
rename to src/test/resources/buildTests/ADD/file/Dockerfile
diff --git a/src/test/resources/testAddFile/testrun.sh b/src/test/resources/buildTests/ADD/file/testrun.sh
similarity index 100%
rename from src/test/resources/testAddFile/testrun.sh
rename to src/test/resources/buildTests/ADD/file/testrun.sh
diff --git a/src/test/resources/testAddFileInSubfolder/Dockerfile b/src/test/resources/buildTests/ADD/fileInSubfolder/Dockerfile
similarity index 100%
rename from src/test/resources/testAddFileInSubfolder/Dockerfile
rename to src/test/resources/buildTests/ADD/fileInSubfolder/Dockerfile
diff --git a/src/test/resources/testAddFileInSubfolder/files/testrun.sh b/src/test/resources/buildTests/ADD/fileInSubfolder/files/testrun.sh
similarity index 100%
rename from src/test/resources/testAddFileInSubfolder/files/testrun.sh
rename to src/test/resources/buildTests/ADD/fileInSubfolder/files/testrun.sh
diff --git a/src/test/resources/testAddMultipleFiles/Dockerfile b/src/test/resources/buildTests/ADD/files/Dockerfile
similarity index 100%
rename from src/test/resources/testAddMultipleFiles/Dockerfile
rename to src/test/resources/buildTests/ADD/files/Dockerfile
diff --git a/src/test/resources/testAddMultipleFiles/src1 b/src/test/resources/buildTests/ADD/files/src1
similarity index 100%
rename from src/test/resources/testAddMultipleFiles/src1
rename to src/test/resources/buildTests/ADD/files/src1
diff --git a/src/test/resources/testAddMultipleFiles/src2 b/src/test/resources/buildTests/ADD/files/src2
similarity index 100%
rename from src/test/resources/testAddMultipleFiles/src2
rename to src/test/resources/buildTests/ADD/files/src2
diff --git a/src/test/resources/testAddFilesViaWildcard/Dockerfile b/src/test/resources/buildTests/ADD/filesViaWildcard/Dockerfile
similarity index 100%
rename from src/test/resources/testAddFilesViaWildcard/Dockerfile
rename to src/test/resources/buildTests/ADD/filesViaWildcard/Dockerfile
diff --git a/src/test/resources/testAddFilesViaWildcard/folder1/testrun.sh b/src/test/resources/buildTests/ADD/filesViaWildcard/folder1/testrun.sh
similarity index 100%
rename from src/test/resources/testAddFilesViaWildcard/folder1/testrun.sh
rename to src/test/resources/buildTests/ADD/filesViaWildcard/folder1/testrun.sh
diff --git a/src/test/resources/testAddFilesViaWildcard/folder2/testinclude1.sh b/src/test/resources/buildTests/ADD/filesViaWildcard/folder2/testinclude1.sh
similarity index 100%
rename from src/test/resources/testAddFilesViaWildcard/folder2/testinclude1.sh
rename to src/test/resources/buildTests/ADD/filesViaWildcard/folder2/testinclude1.sh
diff --git a/src/test/resources/testAddFilesViaWildcard/ignore/testinclude2.sh b/src/test/resources/buildTests/ADD/filesViaWildcard/ignore/testinclude2.sh
similarity index 100%
rename from src/test/resources/testAddFilesViaWildcard/ignore/testinclude2.sh
rename to src/test/resources/buildTests/ADD/filesViaWildcard/ignore/testinclude2.sh
diff --git a/src/test/resources/testAddFolder/Dockerfile b/src/test/resources/buildTests/ADD/folder/Dockerfile
similarity index 100%
rename from src/test/resources/testAddFolder/Dockerfile
rename to src/test/resources/buildTests/ADD/folder/Dockerfile
diff --git a/src/test/resources/testAddFolder/folderA/testAddFolder.sh b/src/test/resources/buildTests/ADD/folder/folderA/testAddFolder.sh
similarity index 100%
rename from src/test/resources/testAddFolder/folderA/testAddFolder.sh
rename to src/test/resources/buildTests/ADD/folder/folderA/testAddFolder.sh
diff --git a/src/test/resources/testAddUrl/Dockerfile b/src/test/resources/buildTests/ADD/url/Dockerfile
similarity index 71%
rename from src/test/resources/testAddUrl/Dockerfile
rename to src/test/resources/buildTests/ADD/url/Dockerfile
index d9a0676d4..2b10c34e5 100644
--- a/src/test/resources/testAddUrl/Dockerfile
+++ b/src/test/resources/buildTests/ADD/url/Dockerfile
@@ -2,7 +2,7 @@ FROM ubuntu:latest
# Copy testrun.sh files into the container
-ADD https://hub.docker.com/r/marcuslinke/busybox/ /tmp/docker_home.html
+ADD http://www.example.com/index.html /tmp/some.html
ADD ./testrun.sh /tmp/
RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh
diff --git a/src/test/resources/buildTests/ADD/url/testrun.sh b/src/test/resources/buildTests/ADD/url/testrun.sh
new file mode 100755
index 000000000..4d240d5ae
--- /dev/null
+++ b/src/test/resources/buildTests/ADD/url/testrun.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cat /tmp/some.html
+
diff --git a/src/test/resources/nginx/Dockerfile b/src/test/resources/buildTests/AUTHOR/Dockerfile
similarity index 81%
rename from src/test/resources/nginx/Dockerfile
rename to src/test/resources/buildTests/AUTHOR/Dockerfile
index 2d0fa24cb..32ffcedc7 100644
--- a/src/test/resources/nginx/Dockerfile
+++ b/src/test/resources/buildTests/AUTHOR/Dockerfile
@@ -9,4 +9,4 @@ MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com"
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
-RUN apt-get install -y inotify-tools nginx apache2 openssh-server
\ No newline at end of file
+RUN apt-get install -y nginx
\ No newline at end of file
diff --git a/src/test/resources/testENVSubstitution/Dockerfile b/src/test/resources/buildTests/ENV/Dockerfile
similarity index 100%
rename from src/test/resources/testENVSubstitution/Dockerfile
rename to src/test/resources/buildTests/ENV/Dockerfile
diff --git a/src/test/resources/testENVSubstitution/subst-file-2-abc123.txt b/src/test/resources/buildTests/ENV/subst-file-2-abc123.txt
similarity index 100%
rename from src/test/resources/testENVSubstitution/subst-file-2-abc123.txt
rename to src/test/resources/buildTests/ENV/subst-file-2-abc123.txt
diff --git a/src/test/resources/testENVSubstitution/subst-file-abc123.txt b/src/test/resources/buildTests/ENV/subst-file-abc123.txt
similarity index 100%
rename from src/test/resources/testENVSubstitution/subst-file-abc123.txt
rename to src/test/resources/buildTests/ENV/subst-file-abc123.txt
diff --git a/src/test/resources/testENVSubstitution/testrun.sh b/src/test/resources/buildTests/ENV/testrun.sh
similarity index 100%
rename from src/test/resources/testENVSubstitution/testrun.sh
rename to src/test/resources/buildTests/ENV/testrun.sh
diff --git a/src/test/resources/testBuildFromPrivateRegistry/Dockerfile b/src/test/resources/buildTests/FROM/privateRegistry/Dockerfile
similarity index 100%
rename from src/test/resources/testBuildFromPrivateRegistry/Dockerfile
rename to src/test/resources/buildTests/FROM/privateRegistry/Dockerfile
diff --git a/src/test/resources/testAddOnBuild/test/Dockerfile b/src/test/resources/buildTests/ONBUILD/child/Dockerfile
similarity index 100%
rename from src/test/resources/testAddOnBuild/test/Dockerfile
rename to src/test/resources/buildTests/ONBUILD/child/Dockerfile
diff --git a/src/test/resources/testAddOnBuild/test/testrun.sh b/src/test/resources/buildTests/ONBUILD/child/testrun.sh
similarity index 100%
rename from src/test/resources/testAddOnBuild/test/testrun.sh
rename to src/test/resources/buildTests/ONBUILD/child/testrun.sh
diff --git a/src/test/resources/testAddOnBuild/onbuild/Dockerfile b/src/test/resources/buildTests/ONBUILD/parent/Dockerfile
similarity index 100%
rename from src/test/resources/testAddOnBuild/onbuild/Dockerfile
rename to src/test/resources/buildTests/ONBUILD/parent/Dockerfile
diff --git a/src/test/resources/testBuildArgs/Dockerfile b/src/test/resources/buildTests/buildArgs/Dockerfile
similarity index 100%
rename from src/test/resources/testBuildArgs/Dockerfile
rename to src/test/resources/buildTests/buildArgs/Dockerfile
diff --git a/src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile b/src/test/resources/buildTests/dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile
similarity index 100%
rename from src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile
rename to src/test/resources/buildTests/dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile
diff --git a/src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh b/src/test/resources/buildTests/dockerfileNotInBaseDirectory/testrunFolder/testrun.sh
similarity index 100%
rename from src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh
rename to src/test/resources/buildTests/dockerfileNotInBaseDirectory/testrunFolder/testrun.sh
diff --git a/src/test/resources/testDockerfileIgnored/.dockerignore b/src/test/resources/buildTests/dockerignore/DockerfileIgnored/.dockerignore
similarity index 100%
rename from src/test/resources/testDockerfileIgnored/.dockerignore
rename to src/test/resources/buildTests/dockerignore/DockerfileIgnored/.dockerignore
diff --git a/src/test/resources/testDockerfileIgnored/Dockerfile b/src/test/resources/buildTests/dockerignore/DockerfileIgnored/Dockerfile
similarity index 100%
rename from src/test/resources/testDockerfileIgnored/Dockerfile
rename to src/test/resources/buildTests/dockerignore/DockerfileIgnored/Dockerfile
diff --git a/src/test/resources/testDockerfileIgnored/testrun.sh b/src/test/resources/buildTests/dockerignore/DockerfileIgnored/testrun.sh
similarity index 100%
rename from src/test/resources/testDockerfileIgnored/testrun.sh
rename to src/test/resources/buildTests/dockerignore/DockerfileIgnored/testrun.sh
diff --git a/src/test/resources/testDockerfileNotIgnored/.dockerignore b/src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/.dockerignore
similarity index 100%
rename from src/test/resources/testDockerfileNotIgnored/.dockerignore
rename to src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/.dockerignore
diff --git a/src/test/resources/testDockerfileNotIgnored/Dockerfile b/src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/Dockerfile
similarity index 100%
rename from src/test/resources/testDockerfileNotIgnored/Dockerfile
rename to src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/Dockerfile
diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore
new file mode 100644
index 000000000..f22e777b8
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore
@@ -0,0 +1,3 @@
+*.md
+!README*.md
+README-secret.md
\ No newline at end of file
diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile
new file mode 100644
index 000000000..65fa210c7
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile
@@ -0,0 +1,3 @@
+FROM ubuntu:latest
+
+CMD ["echo", "Success"]
diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md
new file mode 100644
index 000000000..64237b5a7
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md
@@ -0,0 +1 @@
+No markdown files are included in the context except README files other than README-secret.md.
\ No newline at end of file
diff --git a/src/test/resources/testDockerignore/a/a b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README.md
similarity index 100%
rename from src/test/resources/testDockerignore/a/a
rename to src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README.md
diff --git a/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore
new file mode 100644
index 000000000..f1a1f3799
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore
@@ -0,0 +1,3 @@
+*.md
+README-secret.md
+!README*.md
diff --git a/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile
new file mode 100644
index 000000000..65fa210c7
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile
@@ -0,0 +1,3 @@
+FROM ubuntu:latest
+
+CMD ["echo", "Success"]
diff --git a/src/test/resources/testDockerignore/a/b b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README-secret.md
similarity index 100%
rename from src/test/resources/testDockerignore/a/b
rename to src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README-secret.md
diff --git a/src/test/resources/testDockerignore/a/c b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README.md
similarity index 100%
rename from src/test/resources/testDockerignore/a/c
rename to src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README.md
diff --git a/src/test/resources/testInvalidDockerignorePattern/.dockerignore b/src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/.dockerignore
similarity index 100%
rename from src/test/resources/testInvalidDockerignorePattern/.dockerignore
rename to src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/.dockerignore
diff --git a/src/test/resources/testInvalidDockerignorePattern/Dockerfile b/src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/Dockerfile
similarity index 100%
rename from src/test/resources/testInvalidDockerignorePattern/Dockerfile
rename to src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/Dockerfile
diff --git a/src/test/resources/testInvalidDockerignorePattern/testrun.sh b/src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/testrun.sh
similarity index 100%
rename from src/test/resources/testInvalidDockerignorePattern/testrun.sh
rename to src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/testrun.sh
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore
new file mode 100644
index 000000000..d32df2a06
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore
@@ -0,0 +1,5 @@
+**/*.txt
+parent/*/grandChild/README*.md
+parent/anotherChild/README*.md
+!parent/anotherChild/*/*.md
+!parent/child
\ No newline at end of file
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile
new file mode 100644
index 000000000..65fa210c7
--- /dev/null
+++ b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile
@@ -0,0 +1,3 @@
+FROM ubuntu:latest
+
+CMD ["echo", "Success"]
diff --git a/src/test/resources/testDockerignore/a/d b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/README.md
similarity index 100%
rename from src/test/resources/testDockerignore/a/d
rename to src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/README.md
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/a.txt b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/a.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/README-child.md b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/README-child.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/README-grand.md b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/README-grand.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/c.txt b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/c.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/child/b.txt b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/child/b.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/testDockerignore/.dockerignore b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/.dockerignore
similarity index 100%
rename from src/test/resources/testDockerignore/.dockerignore
rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/.dockerignore
diff --git a/src/test/resources/testDockerignore/Dockerfile b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/Dockerfile
similarity index 100%
rename from src/test/resources/testDockerignore/Dockerfile
rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/Dockerfile
diff --git a/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/a b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/a
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/b b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/b
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/c b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/c
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/d b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/d
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/test/resources/testDockerignore/testrun.sh b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/testrun.sh
similarity index 100%
rename from src/test/resources/testDockerignore/testrun.sh
rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/testrun.sh
diff --git a/src/test/resources/buildTests/labels/Dockerfile b/src/test/resources/buildTests/labels/Dockerfile
new file mode 100644
index 000000000..6a8106b86
--- /dev/null
+++ b/src/test/resources/buildTests/labels/Dockerfile
@@ -0,0 +1,3 @@
+FROM ubuntu:latest
+
+CMD ["echo", "Success"]
diff --git a/src/test/resources/checkstyle/checkstyle-config.xml b/src/test/resources/checkstyle/checkstyle-config.xml
index 33508c723..76671ded3 100644
--- a/src/test/resources/checkstyle/checkstyle-config.xml
+++ b/src/test/resources/checkstyle/checkstyle-config.xml
@@ -92,7 +92,9 @@
-
+
+
+
diff --git a/src/test/resources/netcat/Dockerfile b/src/test/resources/netcat/Dockerfile
deleted file mode 100644
index 1974f1063..000000000
--- a/src/test/resources/netcat/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Firefox over VNC
-#
-# VERSION 0.3
-
-FROM ubuntu:latest
-
-#install netcat
-RUN apt-get install -y netcat
-
-EXPOSE 6900
-CMD ["nc", "-l", "6900"]
\ No newline at end of file
diff --git a/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard b/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard
deleted file mode 100644
index 2d0fa24cb..000000000
--- a/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard
+++ /dev/null
@@ -1,12 +0,0 @@
-# Nginx
-#
-# VERSION 0.0.1
-
-FROM ubuntu:latest
-MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com"
-
-# make sure the package repository is up to date
-RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
-RUN apt-get update
-
-RUN apt-get install -y inotify-tools nginx apache2 openssh-server
\ No newline at end of file
diff --git a/src/test/resources/samples/1.24/events/docs1.json b/src/test/resources/samples/1.24/events/docs1.json
new file mode 100644
index 000000000..f62f2284e
--- /dev/null
+++ b/src/test/resources/samples/1.24/events/docs1.json
@@ -0,0 +1,17 @@
+{
+ "status": "create",
+ "id": "ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743",
+ "from": "alpine",
+ "Type": "container",
+ "Action": "create",
+ "Actor": {
+ "ID": "ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743",
+ "Attributes": {
+ "com.example.some-label": "some-label-value",
+ "image": "alpine",
+ "name": "my-container"
+ }
+ },
+ "time": 1461943101,
+ "timeNano": 1461943101381709551
+}
diff --git a/src/test/resources/testAddUrl/testrun.sh b/src/test/resources/testAddUrl/testrun.sh
deleted file mode 100755
index 8eb4630b3..000000000
--- a/src/test/resources/testAddUrl/testrun.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-cat /tmp/docker_home.html
-
diff --git a/src/test/resources/testEnv/Dockerfile b/src/test/resources/testEnv/Dockerfile
deleted file mode 100644
index a0a084633..000000000
--- a/src/test/resources/testEnv/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM ubuntu:latest
-
-ENV varA ./subFolder
-ENV varB $varA/testrun.sh
-
-ADD $varB /tmp/
-
-RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh
-
-CMD ["testrun.sh"]
diff --git a/src/test/resources/testEnv/subFolder/testrun.sh b/src/test/resources/testEnv/subFolder/testrun.sh
deleted file mode 100755
index 14259aa77..000000000
--- a/src/test/resources/testEnv/subFolder/testrun.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-echo "Successfully executed testrun.sh"
\ No newline at end of file
diff --git a/src/test/resources/travis-logback.xml b/src/test/resources/travis-logback.xml
new file mode 100644
index 000000000..250cbd335
--- /dev/null
+++ b/src/test/resources/travis-logback.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+