consolidate storage validation logic
This commit is contained in:
+20
-13
@@ -168,6 +168,7 @@ const appstore = require('./appstore.js'),
|
||||
semver = require('semver'),
|
||||
services = require('./services.js'),
|
||||
settings = require('./settings.js'),
|
||||
shell = require('./shell.js'),
|
||||
spawn = require('child_process').spawn,
|
||||
split = require('split'),
|
||||
superagent = require('superagent'),
|
||||
@@ -191,6 +192,8 @@ const APPS_FIELDS_PREFIXED = [ 'apps.id', 'apps.appStoreId', 'apps.installationS
|
||||
|
||||
// const PORT_BINDINGS_FIELDS = [ 'hostPort', 'type', 'environmentVariable', 'appId' ].join(',');
|
||||
|
||||
const CHECKVOLUME_CMD = path.join(__dirname, 'scripts/checkvolume.sh');
|
||||
|
||||
function validatePortBindings(portBindings, manifest) {
|
||||
assert.strictEqual(typeof portBindings, 'object');
|
||||
assert.strictEqual(typeof manifest, 'object');
|
||||
@@ -478,13 +481,24 @@ function validateEnv(env) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateStorage(volume, prefix) {
|
||||
assert.strictEqual(typeof volume, 'object');
|
||||
async function checkStorage(volumeId, prefix) {
|
||||
assert.strictEqual(typeof volumeId, 'string');
|
||||
assert.strictEqual(typeof prefix, 'string');
|
||||
|
||||
if (path.isAbsolute(prefix)) return new BoxError(BoxError.BAD_FIELD, `prefix "${prefix}" must be a relative path`);
|
||||
if (prefix.endsWith('/')) return new BoxError(BoxError.BAD_FIELD, `prefix "${prefix}" contains trailing slash`);
|
||||
if (path.normalize(prefix) !== prefix) return new BoxError(BoxError.BAD_FIELD, `prefix "${prefix}" is not a normalized path`);
|
||||
const volume = await volumes.get(volumeId);
|
||||
if (volume === null) throw new BoxError(BoxError.BAD_FIELD, 'Storage volume not found');
|
||||
|
||||
const status = await volumes.getStatus(volume);
|
||||
if (status.state !== 'active') throw new BoxError(BoxError.BAD_FIELD, 'Volume is not active');
|
||||
|
||||
if (path.isAbsolute(prefix)) throw new BoxError(BoxError.BAD_FIELD, `prefix "${prefix}" must be a relative path`);
|
||||
if (prefix.endsWith('/')) throw new BoxError(BoxError.BAD_FIELD, `prefix "${prefix}" contains trailing slash`);
|
||||
if (prefix !== '' && path.normalize(prefix) !== prefix) throw new BoxError(BoxError.BAD_FIELD, `prefix "${prefix}" is not a normalized path`);
|
||||
|
||||
const storageDir = path.join(volume.hostPath, prefix);
|
||||
const [error] = await safe(shell.promises.sudo('checkStorage', [ CHECKVOLUME_CMD, storageDir ], {}));
|
||||
if (error && error.code === 2) throw new BoxError(BoxError.BAD_FIELD, `Targer directory ${storageDir} is not empty`);
|
||||
if (error && error.code === 3) throw new BoxError(BoxError.BAD_FIELD, `Targer directory ${storageDir} does not support chown`);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1794,14 +1808,7 @@ async function setStorage(app, volumeId, volumePrefix, auditSource) {
|
||||
if (error) throw error;
|
||||
|
||||
if (volumeId) {
|
||||
const volume = await volumes.get(volumeId);
|
||||
if (volume === null) throw new BoxError(BoxError.BAD_FIELD, 'Storage volume not found');
|
||||
|
||||
const status = await volumes.getStatus(volume);
|
||||
if (status.state !== 'active') throw new BoxError(BoxError.BAD_FIELD, 'Volume is not active');
|
||||
|
||||
error = validateStorage(volume, volumePrefix);
|
||||
if (error) throw error;
|
||||
await checkStorage(volumeId, volumePrefix);
|
||||
} else {
|
||||
volumeId = volumePrefix = null;
|
||||
}
|
||||
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
if [[ ${EUID} -ne 0 ]]; then
|
||||
echo "This script should be run as root." > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "No arguments supplied"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$1" == "--check" ]]; then
|
||||
echo "OK"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
volume_dir="$1"
|
||||
|
||||
readonly test_file="${volume_dir}/.chown-test"
|
||||
|
||||
mkdir -p "${volume_dir}"
|
||||
rm -f "${test_file}" # clean up any from previous run
|
||||
|
||||
if [[ -n "$(ls -A \"${volume_dir}\")" ]]; then
|
||||
echo "volume dir is not empty"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
touch "${test_file}"
|
||||
if ! chown yellowtent:yellowtent "${test_file}"; then
|
||||
echo "chown does not work"
|
||||
exit 3
|
||||
fi
|
||||
rm -f "${test_file}"
|
||||
rm -r "${volume_dir}" # will get recreated by the local storage addon
|
||||
|
||||
@@ -20,4 +20,3 @@ fi
|
||||
volume_dir="$1"
|
||||
|
||||
mkdir -p "${volume_dir}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user