diff --git a/run-tests b/run-tests index c8a1ce04c..cfbe52d18 100755 --- a/run-tests +++ b/run-tests @@ -49,5 +49,5 @@ if [[ $# -gt 0 ]]; then fi echo "=> Run tests" -docker run -e BOX_ENV=test -e DATABASE_HOSTNAME=${MYSQL_IP} -v `pwd`:/home/yellowtent/box:ro -v `which node`:/usr/bin/node:ro -t cloudron/boxtest node_modules/.bin/mocha --bail --no-timeouts --colors --exit -R spec src/test +docker run -e BOX_ENV=test -e DATABASE_HOSTNAME=${MYSQL_IP} -v `pwd`:/home/yellowtent/box:ro -v `which node`:/usr/bin/node:ro -v /var/run/docker.sock:/var/run/docker.sock -t cloudron/boxtest node_modules/.bin/mocha --bail --no-timeouts --colors --exit -R spec src/test diff --git a/src/scripts/starttask.sh b/src/scripts/starttask.sh index e01e246cc..1877a7461 100755 --- a/src/scripts/starttask.sh +++ b/src/scripts/starttask.sh @@ -46,11 +46,18 @@ fi # DEBUG has to be hardcoded because it is not set in the tests. --setenv is required for ubuntu 16 (-E does not work) # NODE_OPTIONS is used because env -S does not work in ubuntu 16/18. # it seems systemd-run does not return the exit status of the process despite --wait -if ! systemd-run --unit "${service_name}" --nice "${nice}" --uid=${id} --gid=${id} ${options} --setenv HOME=${HOME} --setenv USER=${SUDO_USER} --setenv DEBUG=box:* --setenv BOX_ENV=${BOX_ENV} --setenv NODE_ENV=production --setenv NODE_OPTIONS=--unhandled-rejections=strict --setenv AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE=1 "${task_worker}" "${task_id}" "${logfile}"; then - echo "Service ${service_name} failed to run" # this only happens if the path to task worker itself is wrong -fi +if [[ "$CI" == "1" ]]; then + if ! DEBUG=box:* NODE_ENV=production NODE_OPTIONS=--unhandled-rejections=strict gosu $id:$id "${task_worker}" "${task_id}" "${logfile}"; then + echo "Service ${service_name} failed to run" # this only happens if the path to task worker itself is wrong + fi + exit_code=$? +else + if ! systemd-run --unit "${service_name}" --nice "${nice}" --uid=${id} --gid=${id} ${options} --setenv HOME=${HOME} --setenv USER=${SUDO_USER} --setenv DEBUG=box:* --setenv BOX_ENV=${BOX_ENV} --setenv NODE_ENV=production --setenv NODE_OPTIONS=--unhandled-rejections=strict --setenv AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE=1 "${task_worker}" "${task_id}" "${logfile}"; then + echo "Service ${service_name} failed to run" # this only happens if the path to task worker itself is wrong + fi -exit_code=$(systemctl show "${service_name}" -p ExecMainCode | sed 's/ExecMainCode=//g') + exit_code=$(systemctl show "${service_name}" -p ExecMainCode | sed 's/ExecMainCode=//g') +fi echo "Service ${service_name} finished with exit code ${exit_code}" exit "${exit_code}" diff --git a/src/shell.js b/src/shell.js index c05a1b5d8..022b30d69 100644 --- a/src/shell.js +++ b/src/shell.js @@ -111,10 +111,10 @@ function sudo(tag, args, options, callback) { cp.stdout.on('data', (data) => { if (options.captureStdout) stdoutResult += data.toString('utf8'); - if (!options.quiet) process.stdout.write(data); // do not use debug to avoid double timestamps when calling backupupload.js + if (!options.quiet) process.stdout.write(data + '\r'); // do not use debug to avoid double timestamps when calling backupupload.js }); cp.stderr.on('data', (data) => { - process.stderr.write(data); // do not use debug to avoid double timestamps when calling backupupload.js + process.stderr.write(data + '\r'); // do not use debug to avoid double timestamps when calling backupupload.js }); cp.on('exit', function (code, signal) { diff --git a/src/storage/filesystem.js b/src/storage/filesystem.js index 68bafe7fb..80b642711 100644 --- a/src/storage/filesystem.js +++ b/src/storage/filesystem.js @@ -81,6 +81,7 @@ async function upload(apiConfig, backupFilePath) { return { stream: fs.createWriteStream(backupFilePath, { autoClose: true }), async finish() { +console.log('OK CHOWNNIG!!!!!', process.env.SUDO_UID, process.getuid()); const backupUid = parseInt(process.env.SUDO_UID, 10) || process.getuid(); // in test, upload() may or may not be called via sudo script if (hasChownSupportSync(apiConfig)) { if (!safe.fs.chownSync(backupFilePath, backupUid, backupUid)) throw new BoxError(BoxError.EXTERNAL_ERROR, `Unable to chown ${backupFilePath}: ${safe.error.message}`); diff --git a/src/system.js b/src/system.js index 25bffbde6..c5d4f649f 100644 --- a/src/system.js +++ b/src/system.js @@ -97,7 +97,7 @@ async function getDisks() { const DISK_TYPES = [ 'ext4', 'xfs', 'cifs', 'nfs', 'fuse.sshfs' ]; // we don't show size of contents in untracked disk types for (const disk of dfEntries) { - if (!DISK_TYPES.includes(disk.type)) continue; + if (!DISK_TYPES.includes(disk.type) && disk.mountpoint !== '/') continue; if (disk.mountpoint === '/') rootDisk = disk; disks[disk.filesystem] = { filesystem: disk.filesystem, diff --git a/src/tasks.js b/src/tasks.js index 1f8e3d058..7fd112fa4 100644 --- a/src/tasks.js +++ b/src/tasks.js @@ -169,7 +169,7 @@ function startTask(id, options, onTaskFinished) { let killTimerId = null, timedOut = false; const sudoOptions = { preserveEnv: true, logStream: null }; - if (constants.TEST) sudoOptions.logStream = fs.createWriteStream('/dev/null'); // without this output is messed up, not sure why + //if (constants.TEST) sudoOptions.logStream = fs.createWriteStream('/dev/null'); // without this output is messed up, not sure why gTasks[id] = shell.sudo('startTask', [ START_TASK_CMD, id, logFile, options.nice || 0, options.memoryLimit || 400, options.oomScoreAdjust || 0 ], sudoOptions, async function (sudoError) { if (!gTasks[id]) return; // ignore task exit since we are shutting down. see stopAllTasks diff --git a/src/test/cloudron-test.js b/src/test/cloudron-test.js index 3e1cbfc3a..73c1b4f8a 100644 --- a/src/test/cloudron-test.js +++ b/src/test/cloudron-test.js @@ -11,7 +11,7 @@ const BoxError = require('../boxerror.js'), expect = require('expect.js'), safe = require('safetydance'); -describe('Settings', function () { +describe('Cloudron', function () { const { setup, cleanup } = common; before(setup); diff --git a/src/test/system-test.js b/src/test/system-test.js index b2034424a..eb2a8952a 100644 --- a/src/test/system-test.js +++ b/src/test/system-test.js @@ -17,27 +17,18 @@ describe('System', function () { after(cleanup); it('can get disks', async function () { - // does not work on archlinux 8! - if (require('child_process').execSync('uname -a').toString().indexOf('-arch') !== -1) return; - const disks = await system.getDisks(); expect(disks).to.be.ok(); expect(Object.keys(disks).some(fs => disks[fs].mountpoint === '/')).to.be.ok(); }); it('can get swaps', async function () { - // does not work on archlinux 8! - if (require('child_process').execSync('uname -a').toString().indexOf('-arch') !== -1) return; - const swaps = await system.getSwaps(); expect(swaps).to.be.ok(); expect(Object.keys(swaps).some(n => swaps[n].type === 'partition' || swaps[n].type === 'file')).to.be.ok(); }); it('can check for disk space', async function () { - // does not work on archlinux 8! - if (require('child_process').execSync('uname -a').toString().indexOf('-arch') !== -1) return; - await system.checkDiskSpace(); }); diff --git a/test/Dockerfile b/test/Dockerfile index f7e7e9014..c519e17f2 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -1,18 +1,23 @@ FROM ubuntu:jammy-20230816@sha256:b492494d8e0113c4ad3fe4528a4b5ff89faa5331f7d52c5c138196f69ce176a6 RUN apt update && \ - apt install -y openssl mysql-client-8.0 sudo lsb-release vim + apt install -y openssl mysql-client-8.0 sudo lsb-release vim gosu curl -RUN useradd --system --uid 808 --comment "Cloudron Box" --create-home --shell /usr/sbin/nologin yellowtent +RUN useradd --system --uid 808 --comment "Cloudron Box" --create-home --shell /usr/bin/bash yellowtent RUN mkdir -p /mnt/cloudron-test-music /media/cloudron-test-music # volume test +# https://download.docker.com/linux/static/stable/x86_64/ +RUN cd /usr/bin && curl -L https://download.docker.com/linux/static/stable/x86_64/docker-25.0.5.tgz | tar -zxvf - --strip-components=1 docker/docker + COPY setup/start/sudoers /etc/sudoers.d/cloudron COPY test/cloak /usr/bin/cloak RUN ln -s /usr/bin/cloak /usr/bin/systemd-run && \ ln -s /usr/bin/cloak /usr/bin/systemctl +COPY test/entrypoint.sh /usr/bin/entrypoint.sh + WORKDIR /home/yellowtent USER yellowtent @@ -24,3 +29,5 @@ RUN bash -c 'openssl req -x509 -newkey rsa:2048 -keyout platformdata/nginx/cert/ WORKDIR /home/yellowtent/box +USER root +ENTRYPOINT [ "/usr/bin/entrypoint.sh" ] diff --git a/test/entrypoint.sh b/test/entrypoint.sh new file mode 100755 index 000000000..95ef4a9bf --- /dev/null +++ b/test/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -eu + +docker_gid=$(stat -c "%g" /run/docker.sock) +addgroup --gid ${docker_gid} --system docker +usermod -aG docker yellowtent + +exec su yellowtent --command "$@" +