@@ -22,29 +50,43 @@
Redis container is not running.
-
-
- DB |
- Key |
- Value |
-
-
- getKeys() as $db_name => $keys): ?>
-
-
-
+ getKeys(); ?>
+
+ $keys): ?>
+ |
+
+ Database:
+ Items:
+ |
-
- $val): ?>
-
- |
- |
-
|
+
+
+ DB |
+ Key |
+ Expires |
+ Type |
+ Value |
+
-
+
+
+ |
+ |
+ s |
+ |
+
+
+
+
+ |
+
+
-
+
+
+ No keys set.
+
diff --git a/.devilbox/www/include/lib/container/Memcd.php b/.devilbox/www/include/lib/container/Memcd.php
index bf4e7eb1..87ef85b4 100644
--- a/.devilbox/www/include/lib/container/Memcd.php
+++ b/.devilbox/www/include/lib/container/Memcd.php
@@ -43,7 +43,7 @@ class Memcd extends BaseClass implements BaseInterface
if (empty($list)) {
$memcd->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
- $memcd->setOption(\Memcached::OPT_BINARY_PROTOCOL, false);
+ $memcd->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$memcd->addServer($hostname, 11211);
}
@@ -67,13 +67,15 @@ class Memcd extends BaseClass implements BaseInterface
$this->_connect_errno = 3;
return;
}
-
- $memcd->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
+ $memcd->getDelayed(array('devilbox-version'));
+ if (!$memcd->fetchAll()) {
+ $memcd->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
+ }
$this->_memcached = $memcd;
} else {
$ret = 0;
- loadClass('Helper')->exec('echo "stats" | nc 127.0.0.1 11211', $ret);
+ loadClass('Helper')->exec('printf "stats\nquit\n" | nc '.$hostname.' 11211', $ret);
if ($ret == 0) {
$this->_memcached = true;
}
@@ -104,16 +106,55 @@ class Memcd extends BaseClass implements BaseInterface
public function getKeys()
{
$store = array();
+
+ // CLI seems to only sometimes get the results, so we will just loop a bit
+ // It's a very quick operation anyway.
+ $cli_retries = 100;
+
+ // Memcached >= 1.5
+ for ($i=0; $i<$cli_retries; $i++) {
+
+ $output = array();
+ exec('printf "stats cachedump 1 0\nquit\n" | nc memcd 11211 | grep -E \'^ITEM\'', $output);
+ foreach ($output as $line) {
+ $matches = array();
+ preg_match('/(^ITEM)\s*(.+?)\s*\[([0-9]+\s*b);\s*([0-9]+\s*s)\s*\]/', $line, $matches);
+ $key = $matches[2];
+ $store[] = array(
+ 'key' => $key,
+ 'val' => $this->_memcached->get($key),
+ 'ttl' => $matches[4],
+ 'size' => $matches[3],
+ );
+ }
+ // If we actually got a result, we can break here
+ if (count($store)) {
+ return $store;
+ }
+ }
+
+ // This will only work for Memcached < 1.5
if (class_exists('Memcached')) {
if ($this->_memcached) {
+
+ // Ensure we retrieve data not in binary
+ $this->_memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, false);
+
if (!($keys = $this->_memcached->getAllKeys())) {
$keys = array();
}
- $this->_memcached->getDelayed($keys);
- $store = $this->_memcached->fetchAll();
- if (!is_array($store)) {
- $store = array();
+ $this->_memcached->getDelayed($keys, true);
+ $data = $this->_memcached->fetchAll();
+ if (is_array($data)) {
+ for ($i=0; $size=count($data), $i<$size; $i++) {
+ $store[$i]['key'] = $data[$i]['key'];
+ $store[$i]['val'] = $data[$i]['value'];
+ $store[$i]['ttl'] = '?';
+ $store[$i]['size'] = strlen($data[$i]['value']);
+ }
}
+ // Revert Memcachd protocol
+ $this->_memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
}
}
return $store;
@@ -128,14 +169,14 @@ class Memcd extends BaseClass implements BaseInterface
}
} else {
$ret = 0;
- $output = loadClass('Helper')->exec('echo "stats" | nc 127.0.0.1 11211 | sed "s/^STAT[[:space:]]*//g" | grep -v "END"', $ret);
+ $output = loadClass('Helper')->exec('printf "stats\nquit\n" | nc memcd 11211 | sed "s/^STAT[[:space:]]*//g" | grep -v "END"', $ret);
if ($ret == 0) {
$output = explode("\n", $output);
foreach ($output as $line) {
$tmp = explode(' ', $line);
$key = isset($tmp[0]) ? $tmp[0] : '';
$val = isset($tmp[1]) ? $tmp[1] : '';
- $stats['127.0.0.1'][$key] = $val;
+ $stats['memcd'][$key] = $val;
}
}
}
@@ -167,51 +208,13 @@ class Memcd extends BaseClass implements BaseInterface
return $this->_can_connect[$hostname];
}
- if (class_exists('Memcached')) {
- // Silence errors and try to connect
- //error_reporting(-1);
- $memcd = new \Memcached();
- $memcd->resetServerList();
-
-
- if (!$memcd->addServer($hostname, 11211)) {
- $memcd->quit();
- $err = 'Failed to connect to Memcached host on '.$hostname;
- $this->_can_connect[$hostname] = false;
- $this->_can_connect_err[$hostname] = $err;
- return false;
- }
-
- $stats = $memcd->getStats();
- if (!isset($stats[$hostname.':11211'])) {
- $err = 'Failed to connect to Memcached host on '.$hostname;
- $this->_can_connect[$hostname] = false;
- }
- else if (!isset($stats[$hostname.':11211']['pid'])) {
- $err = 'Failed to connect to Memcached host on '.$hostname;
- $this->_can_connect[$hostname] = false;
- }
- else if ($stats[$hostname.':11211']['pid'] < 1) {
- $err = 'Failed to connect to Memcached host on '.$hostname;
- $this->_can_connect[$hostname] = false;
- }
- else {
- $this->_can_connect[$hostname] = true;
- }
-
- $memcd->quit();
-
- $this->_can_connect_err[$hostname] = $err;
+ $ret = 0;
+ loadClass('Helper')->exec('printf "stats\nquit\n" | nc '.$hostname.' 11211', $ret);
+ if ($ret == 0) {
+ $this->_can_connect[$hostname] = true;
} else {
-
- $ret = 0;
- loadClass('Helper')->exec('echo "stats" | nc '.$hostname.' 11211', $ret);
- if ($ret == 0) {
- $this->_can_connect[$hostname] = true;
- } else {
- $err = 'Failed to connect to Memcached host on '.$hostname;
- $this->_can_connect[$hostname] = false;
- }
+ $err = 'Failed to connect to Memcached host on '.$hostname;
+ $this->_can_connect[$hostname] = false;
}
return $this->_can_connect[$hostname];
@@ -249,7 +252,7 @@ class Memcd extends BaseClass implements BaseInterface
}
}
} else {
- $version = loadClass('Helper')->exec('echo "version" | nc 127.0.0.1 11211 | grep -oE "[0-9.-]+"', $ret);
+ $version = loadClass('Helper')->exec('printf "version\nquit\n" | nc memcd 11211 | grep -oE "[0-9.-]+"', $ret);
$this->_version = $version;
}
return $this->_version;
diff --git a/.devilbox/www/include/lib/container/Mongo.php b/.devilbox/www/include/lib/container/Mongo.php
index a78b241d..0b941d29 100644
--- a/.devilbox/www/include/lib/container/Mongo.php
+++ b/.devilbox/www/include/lib/container/Mongo.php
@@ -91,10 +91,9 @@ class Mongo extends BaseClass implements BaseInterface
*/
private function command($command)
{
- $cmd = new \MongoDB\Driver\Command($command);
-
if ($this->_mongo) {
try {
+ $cmd = new \MongoDB\Driver\Command($command);
$cursor = $this->_mongo->executeCommand('admin', $cmd);
return $cursor->toArray();
} catch(\MongoDB\Driver\Exception $e) {
diff --git a/.devilbox/www/include/lib/container/Redis.php b/.devilbox/www/include/lib/container/Redis.php
index e2f142b5..0a0f1bf5 100644
--- a/.devilbox/www/include/lib/container/Redis.php
+++ b/.devilbox/www/include/lib/container/Redis.php
@@ -70,6 +70,17 @@ class Redis extends BaseClass implements BaseInterface
* Select functions
*
*********************************************************************************/
+ public function flushDB($db)
+ {
+ if ($this->_redis) {
+ if ( !$this->_redis->select($db) ) {
+ return FALSE;
+ }
+ return $this->_redis->flushDb();
+ } else {
+ return FALSE;
+ }
+ }
public function getInfo()
{
@@ -101,7 +112,35 @@ class Redis extends BaseClass implements BaseInterface
$this->_redis->select($db);
$keys = $this->_redis->keys('*');
foreach ($keys as $key) {
- $store[$db][$key] = $this->_redis->get($key);
+
+ switch($this->_redis->type($key)) {
+ case \Redis::REDIS_STRING:
+ $dtype = 'string';
+ break;
+ case \Redis::REDIS_SET:
+ $dtype = 'set';
+ break;
+ case \Redis::REDIS_LIST:
+ $dtype = 'list';
+ break;
+ case \Redis::REDIS_ZSET:
+ $dtype = 'zset';
+ break;
+ case \Redis::REDIS_HASH:
+ $dtype = 'hash';
+ break;
+ case \Redis::REDIS_NOT_FOUND:
+ $dtype = 'other';
+ break;
+ default:
+ $dtype = 'unknown';
+ }
+ $store[$db][] = array(
+ 'name' => $key,
+ 'val' => $this->_redis->get($key),
+ 'type' => $dtype,
+ 'ttl' => $this->_redis->ttl($key)
+ );
}
}
}
diff --git a/.tests/intra-tests/homepage.sh b/.tests/intra-tests/homepage.sh
index 0b1bf733..f029a7ac 100755
--- a/.tests/intra-tests/homepage.sh
+++ b/.tests/intra-tests/homepage.sh
@@ -17,9 +17,11 @@ printf "[TEST] dvlbox-ok"
TEST_OK="$( curl -sS localhost/index.php | grep -c 'dvlbox-ok' || true )"
if [ "${TEST_OK}" != "${NUM_OK}" ]; then
# 2nd Try
+ sleep 1
TEST_OK="$( curl -sS localhost/index.php | grep -c 'dvlbox-ok' || true )"
if [ "${TEST_OK}" != "${NUM_OK}" ]; then
# 3rd Try
+ sleep 1
TEST_OK="$( curl -sS localhost/index.php | grep -c 'dvlbox-ok' || true )"
if [ "${TEST_OK}" != "${NUM_OK}" ]; then
printf "\r[FAIL] dvlbox-ok\n"
@@ -45,9 +47,11 @@ printf "[TEST] dvlbox-err"
TEST_ERR="$( curl -sS localhost/index.php | grep -c 'dvlbox-err' || true )"
if [ "${TEST_ERR}" != "${NUM_ERR}" ]; then
# 2nd Try
+ sleep 1
TEST_ERR="$( curl -sS localhost/index.php | grep -c 'dvlbox-err' || true )"
if [ "${TEST_ERR}" != "${NUM_ERR}" ]; then
# 3rd Try
+ sleep 1
TEST_ERR="$( curl -sS localhost/index.php | grep -c 'dvlbox-err' || true )"
if [ "${TEST_ERR}" != "${NUM_ERR}" ]; then
printf "\r[FAIL] dvlbox-err\n"
diff --git a/.tests/intra-tests/memcached.sh b/.tests/intra-tests/memcached.sh
new file mode 100755
index 00000000..4196e9eb
--- /dev/null
+++ b/.tests/intra-tests/memcached.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+set -o pipefail
+
+
+printf "[TEST] devilbox-version key in Memcached"
+# 1st Try
+if ! curl -sS localhost/db_memcd.php | grep -q 'devilbox-version'; then
+ sleep 1
+ if ! curl -sS localhost/db_memcd.php | grep -q 'devilbox-version'; then
+ sleep 1
+ if ! curl -sS localhost/db_memcd.php | grep -q 'devilbox-version'; then
+ printf "\r[FAIL] devilbox-version key in Memcached\n"
+ curl -sS localhost/db_memcd.php || true
+ exit 1
+ else
+ printf "\r[OK] devilbox-version key in Memcached (3 rounds)\n"
+ fi
+ else
+ printf "\r[OK] devilbox-version key in Memcached (2 rounds)\n"
+ fi
+else
+ printf "\r[OK] devilbox-version key in Memcached (1 round)\n"
+fi
diff --git a/.tests/intra-tests/redis.sh b/.tests/intra-tests/redis.sh
new file mode 100755
index 00000000..4ce521a5
--- /dev/null
+++ b/.tests/intra-tests/redis.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+set -o pipefail
+
+
+printf "[TEST] devilbox-version key in Redis"
+# 1st Try
+if ! curl -sS localhost/db_redis.php | grep -q 'devilbox-version'; then
+ sleep 1
+ if ! curl -sS localhost/db_redis.php | grep -q 'devilbox-version'; then
+ sleep 1
+ if ! curl -sS localhost/db_redis.php | grep -q 'devilbox-version'; then
+ printf "\r[FAIL] devilbox-version key in Redis\n"
+ curl -sS localhost/db_redis.php || true
+ exit 1
+ else
+ printf "\r[OK] devilbox-version key in Redis (3 rounds)\n"
+ fi
+ else
+ printf "\r[OK] devilbox-version key in Redis (2 rounds)\n"
+ fi
+else
+ printf "\r[OK] devilbox-version key in Redis (1 round)\n"
+fi
diff --git a/.travis.yml b/.travis.yml
index 8434a6f6..8efbeb0a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -124,19 +124,22 @@ env:
### Installation
###
install:
+ # Update Debian/Ubuntu package index
+ - if [ "${S1}" != "DOCUMENTATION" ]; then
+ until sudo apt-get update -qq; do sleep 1; done
+ fi
+
# Install dependencies for documentation
- if [ "${S1}" = "DOCUMENTATION" ]; then
- max=100; i=0; while [ $i -lt $max ]; do if pip install sphinx; then break; else i=$((i+1)); fi done;
- max=100; i=0; while [ $i -lt $max ]; do if pip install sphinx-autobuild; then break; else i=$((i+1)); fi done;
- max=100; i=0; while [ $i -lt $max ]; do if pip install recommonmark; then break; else i=$((i+1)); fi done;
- max=100; i=0; while [ $i -lt $max ]; do if pip install sphinx_rtd_theme; then break; else i=$((i+1)); fi done;
+ until pip install sphinx; do sleep 1; done;
+ until pip install sphinx-autobuild; do sleep 1; done;
+ until pip install recommonmark; do sleep 1; done;
+ until pip install sphinx_rtd_theme; do sleep 1; done;
fi
# Determine latest Docker version in apt
- - set -e;
- DOCKER_APT="";
+ - DOCKER_APT="";
if [ "${S1}" = "DOCKER" ]; then
- max=100; i=0; while [ $i -lt $max ]; do if sudo apt-get update -qq; then break; else i=$((i+1)); fi; done;
DOCKER_APT="$( curl -sS https://raw.githubusercontent.com/cytopia/tools/master/docker-apt-versions | sh -s "${V1}" )";
fi;
if [ -n "${DOCKER_APT}" ]; then
@@ -145,8 +148,7 @@ install:
echo "${DOCKER_APT}";
# Determine latest Docker Compose version
- - set -e;
- if [ "${S2}" = "COMPOSE" ]; then
+ - if [ "${S2}" = "COMPOSE" ]; then
COMPOSE_VERSION="$( curl -sS https://raw.githubusercontent.com/cytopia/tools/master/docker-compose-versions | sh -s "${V2}" )";
else
COMPOSE_VERSION="$( curl -sS https://raw.githubusercontent.com/cytopia/tools/master/docker-compose-versions | sh -s 1 )";
@@ -154,17 +156,9 @@ install:
echo "${COMPOSE_VERSION}";
# Install Docker and Docker Compose
- - set -e;
- if [ "${S1}" != "DOCUMENTATION" ]; then
- max=100; i=0; while [ $i -lt $max ]; do
- if sudo apt-get update -qq; then break; else i=$((i+1)); fi;
- done;
- max=100; i=0; while [ $i -lt $max ]; do
- if sudo apt-get -y -qq -o Dpkg::Options::="--force-confnew" install docker-ce${DOCKER_APT}; then break; else i=$((i+1)); fi;
- done;
- max=100; i=0; while [ $i -lt $max ]; do
- if curl -L --retry 100 --retry-max-time 0 https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose; then break; else i=$((i+1)); fi;
- done;
+ - if [ "${S1}" != "DOCUMENTATION" ]; then
+ until sudo apt-get -y -qq -o Dpkg::Options::="--force-confnew" install docker-ce${DOCKER_APT}; do sleep 1; done;
+ until curl -L -sS --retry 100 --retry-max-time 0 https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose; do sleep 1; done;
chmod +x docker-compose;
sudo mv -f docker-compose /usr/local/bin;
fi
diff --git a/docker-compose.yml b/docker-compose.yml
index a52070ea..dfde3948 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -95,7 +95,7 @@ services:
# PHP / HHVM
# ------------------------------------------------------------
php:
- image: devilbox/php-fpm:${PHP_SERVER:-7.2}-work-0.52
+ image: devilbox/php-fpm:${PHP_SERVER:-7.2}-work-0.54
##
## All .env variables