diff options
author | John Molakvoæ <skjnldsv@protonmail.com> | 2022-10-20 16:03:19 +0200 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2022-11-29 11:23:05 +0100 |
commit | 064fa10ecfe4725398895a21ab8bafd171e2eadd (patch) | |
tree | 5f2d8124eb131a65eac207edee560c49ea7835f3 /cypress/dockerNode.ts | |
parent | cedae7c6d74e11c8aaa59b09a38db04dbebc818d (diff) | |
download | nextcloud-server-064fa10ecfe4725398895a21ab8bafd171e2eadd.tar.gz nextcloud-server-064fa10ecfe4725398895a21ab8bafd171e2eadd.zip |
Extract colour from custom background
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'cypress/dockerNode.ts')
-rw-r--r-- | cypress/dockerNode.ts | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/cypress/dockerNode.ts b/cypress/dockerNode.ts new file mode 100644 index 00000000000..13e75c605b2 --- /dev/null +++ b/cypress/dockerNode.ts @@ -0,0 +1,243 @@ +/** + * @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com> + * + * @author John Molakvoæ <skjnldsv@protonmail.com> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +/* eslint-disable no-console */ +/* eslint-disable node/no-unpublished-import */ + +import Docker from 'dockerode' +import waitOn from 'wait-on' +import tar from 'tar' + +export const docker = new Docker() + +const CONTAINER_NAME = 'nextcloud-cypress-tests-server' +const SERVER_IMAGE = 'ghcr.io/nextcloud/continuous-integration-shallow-server' + +/** + * Start the testing container + * + * @param {string} branch the branch of your current work + */ +export const startNextcloud = async function(branch: string = 'master'): Promise<any> { + + try { + // Pulling images + console.log('\nPulling images... ⏳') + await new Promise((resolve, reject): any => docker.pull(SERVER_IMAGE, (err, stream) => { + if (err) { + reject(err) + } + // https://github.com/apocas/dockerode/issues/357 + docker.modem.followProgress(stream, onFinished) + + function onFinished(err) { + if (!err) { + resolve(true) + return + } + reject(err) + } + })) + console.log('└─ Done') + + // Remove old container if exists + console.log('\nChecking running containers... 🔍') + try { + const oldContainer = docker.getContainer(CONTAINER_NAME) + const oldContainerData = await oldContainer.inspect() + if (oldContainerData) { + console.log('├─ Existing running container found') + console.log('├─ Removing... ⏳') + // Forcing any remnants to be removed just in case + await oldContainer.remove({ force: true }) + console.log('└─ Done') + } + } catch (error) { + console.log('└─ None found!') + } + + // Starting container + console.log('\nStarting Nextcloud container... 🚀') + console.log(`├─ Using branch '${branch}'`) + const container = await docker.createContainer({ + Image: SERVER_IMAGE, + name: CONTAINER_NAME, + HostConfig: { + Binds: [], + }, + }) + await container.start() + + // Get container's IP + const ip = await getContainerIP(container) + + console.log(`├─ Nextcloud container's IP is ${ip} 🌏`) + return ip + } catch (err) { + console.log('└─ Unable to start the container 🛑') + console.log(err) + stopNextcloud() + throw new Error('Unable to start the container') + } +} + +/** + * Configure Nextcloud + */ +export const configureNextcloud = async function() { + console.log('\nConfiguring nextcloud...') + const container = docker.getContainer(CONTAINER_NAME) + await runExec(container, ['php', 'occ', '--version'], true) + + // Be consistent for screenshots + await runExec(container, ['php', 'occ', 'config:system:set', 'default_language', '--value', 'en'], true) + await runExec(container, ['php', 'occ', 'config:system:set', 'force_language', '--value', 'en'], true) + await runExec(container, ['php', 'occ', 'config:system:set', 'default_locale', '--value', 'en_US'], true) + await runExec(container, ['php', 'occ', 'config:system:set', 'force_locale', '--value', 'en_US'], true) + await runExec(container, ['php', 'occ', 'config:system:set', 'enforce_theme', '--value', 'light'], true) + + // Enable the app and give status + await runExec(container, ['php', 'occ', 'app:enable', '--force', 'viewer'], true) + // await runExec(container, ['php', 'occ', 'app:list'], true) + + console.log('└─ Nextcloud is now ready to use 🎉') +} + +/** + * Applying local changes to the container + * Only triggered if we're not in CI. Otherwise the + * continuous-integration-shallow-server image will + * already fetch the proper branch. + */ +export const applyChangesToNextcloud = async function() { + console.log('\nApply local changes to nextcloud...') + const container = docker.getContainer(CONTAINER_NAME) + + const htmlPath = '/var/www/html' + const folderPaths = [ + './apps', + './core', + './dist', + './lib', + './ocs', + ] + + // Tar-streaming the above folder sinto the container + const serverTar = tar.c({ gzip: false }, folderPaths) + await container.putArchive(serverTar, { + path: htmlPath, + }) + + // Making sure we have the proper permissions + await runExec(container, ['chown', '-R', 'www-data:www-data', htmlPath], false, 'root') + + console.log('└─ Changes applied successfully 🎉') +} + +/** + * Force stop the testing container + */ +export const stopNextcloud = async function() { + try { + const container = docker.getContainer(CONTAINER_NAME) + console.log('Stopping Nextcloud container...') + container.remove({ force: true }) + console.log('└─ Nextcloud container removed 🥀') + } catch (err) { + console.log(err) + } +} + +/** + * Get the testing container's IP + * + * @param {Docker.Container} container the container to get the IP from + */ +export const getContainerIP = async function( + container = docker.getContainer(CONTAINER_NAME) +): Promise<string> { + let ip = '' + let tries = 0 + while (ip === '' && tries < 10) { + tries++ + + await container.inspect(function(err, data) { + if (err) { + throw err + } + ip = data?.NetworkSettings?.IPAddress || '' + }) + + if (ip !== '') { + break + } + + await sleep(1000 * tries) + } + + return ip +} + +// Would be simpler to start the container from cypress.config.ts, +// but when checking out different branches, it can take a few seconds +// Until we can properly configure the baseUrl retry intervals, +// We need to make sure the server is already running before cypress +// https://github.com/cypress-io/cypress/issues/22676 +export const waitOnNextcloud = async function(ip: string) { + console.log('├─ Waiting for Nextcloud to be ready... ⏳') + await waitOn({ resources: [`http://${ip}/index.php`] }) + console.log('└─ Done') +} + +const runExec = async function( + container: Docker.Container, + command: string[], + verbose = false, + user = 'www-data' +) { + const exec = await container.exec({ + Cmd: command, + AttachStdout: true, + AttachStderr: true, + User: user, + }) + + return new Promise((resolve, reject) => { + exec.start({}, (err, stream) => { + if (err) { + reject(err) + } + if (stream) { + stream.setEncoding('utf-8') + stream.on('data', str => { + if (verbose && str.trim() !== '') { + console.log(`├─ ${str.trim().replace(/\n/gi, '\n├─ ')}`) + } + }) + stream.on('end', resolve) + } + }) + }) +} + +const sleep = function(milliseconds: number) { + return new Promise((resolve) => setTimeout(resolve, milliseconds)) +} |