|
1 |
| -'use strict'; |
2 | 1 | const chalk = require('chalk');
|
3 |
| -const execa = require('execa'); |
| 2 | +const sysinfo = require('systeminformation'); |
4 | 3 |
|
5 |
| -const errors = require('../../../errors'); |
6 |
| - |
7 |
| -const taskTitle = 'Checking operating system compatibility'; |
| 4 | +const {SystemError} = require('../../../errors'); |
8 | 5 |
|
| 6 | +const taskTitle = 'Checking system compatibility'; |
9 | 7 | const nginxProgramName = process.env.NGINX_PROGRAM_NAME || 'nginx';
|
| 8 | +const versionRegex = /^(?:16|18|20)/; |
10 | 9 |
|
11 |
| -function systemStack(ctx, task) { |
12 |
| - let promise; |
| 10 | +async function hasSystemd() { |
| 11 | + try { |
| 12 | + const {list} = await sysinfo.processes(); |
| 13 | + const rootProcess = list.find(proc => proc.pid === 1); |
13 | 14 |
|
| 15 | + return Boolean(rootProcess) && rootProcess.name === 'systemd'; |
| 16 | + } catch (error) { |
| 17 | + return false; |
| 18 | + } |
| 19 | +} |
| 20 | + |
| 21 | +async function hasNginx() { |
| 22 | + try { |
| 23 | + const services = await sysinfo.services('*'); |
| 24 | + return services.some(s => s.name === nginxProgramName); |
| 25 | + } catch (error) { |
| 26 | + return false; |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +async function checkSystem(ctx) { |
14 | 31 | if (!ctx.system.platform.linux) {
|
15 |
| - promise = Promise.reject({message: 'Operating system is not Linux'}); |
16 |
| - } else { |
17 |
| - // TODO: refactor to use ctx.system.operatingSystem |
18 |
| - promise = execa.shell('lsb_release -a').catch( |
19 |
| - () => Promise.reject({message: 'Linux version is not Ubuntu 16 or 18'}) |
20 |
| - ).then((result) => { |
21 |
| - if (!result.stdout || !result.stdout.match(/Ubuntu (?:16|18)/)) { |
22 |
| - return Promise.reject({message: 'Linux version is not Ubuntu 16 or 18'}); |
23 |
| - } |
| 32 | + throw new Error('Operating system is not Linux'); |
| 33 | + } |
24 | 34 |
|
25 |
| - return ctx.ui.listr([{ |
26 |
| - title: 'Checking systemd is installed', |
27 |
| - task: () => execa.shell('dpkg -l | grep systemd') |
28 |
| - .catch(() => Promise.reject({missing: 'systemd'})) |
29 |
| - }, { |
30 |
| - title: `Checking ${nginxProgramName} is installed`, |
31 |
| - task: () => execa.shell(`dpkg -l | grep ${nginxProgramName}`) |
32 |
| - .catch(() => Promise.reject({missing: nginxProgramName})) |
33 |
| - }], ctx, { |
34 |
| - concurrent: true, |
35 |
| - exitOnError: false, |
36 |
| - renderer: ctx.ui.verbose ? 'verbose' : 'silent' |
37 |
| - }).catch(error => Promise.reject({ |
38 |
| - message: `Missing package(s): ${error.errors.map(e => e.missing).join(', ')}` |
39 |
| - })); |
40 |
| - }); |
| 35 | + const {distro, release} = await sysinfo.osInfo(); |
| 36 | + if (distro !== 'Ubuntu' || !versionRegex.test(release)) { |
| 37 | + throw new Error('Linux version is not Ubuntu 16, 18, or 20'); |
41 | 38 | }
|
42 | 39 |
|
43 |
| - return promise.catch((error) => { |
| 40 | + const missing = []; |
| 41 | + |
| 42 | + if (!(await hasSystemd())) { |
| 43 | + missing.push('systemd'); |
| 44 | + } |
| 45 | + |
| 46 | + if (!(await hasNginx())) { |
| 47 | + missing.push('nginx'); |
| 48 | + } |
| 49 | + |
| 50 | + if (missing.length) { |
| 51 | + throw new Error(`Missing package(s): ${missing.join(', ')}`); |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +async function systemStack(ctx, task) { |
| 56 | + try { |
| 57 | + await checkSystem(ctx); |
| 58 | + } catch (error) { |
44 | 59 | ctx.ui.log(
|
45 | 60 | `System checks failed with message: '${error.message}'
|
46 | 61 | Some features of Ghost-CLI may not work without additional configuration.
|
47 | 62 | For local installs we recommend using \`ghost install local\` instead.`,
|
48 | 63 | 'yellow'
|
49 | 64 | );
|
50 | 65 |
|
51 |
| - return ctx.ui.confirm(chalk.blue('Continue anyway?'), false).then((confirmed) => { |
52 |
| - if (confirmed) { |
53 |
| - task.skip('System stack check skipped'); |
54 |
| - return Promise.resolve(); |
55 |
| - } |
| 66 | + const skip = await ctx.ui.confirm(chalk.blue('Continue anyway?'), false); |
| 67 | + if (skip) { |
| 68 | + task.skip('System stack check skipped'); |
| 69 | + return; |
| 70 | + } |
56 | 71 |
|
57 |
| - return Promise.reject(new errors.SystemError({ |
58 |
| - message: `System stack checks failed with message: '${error.message}'`, |
59 |
| - task: taskTitle |
60 |
| - })); |
| 72 | + throw new SystemError({ |
| 73 | + message: `System stack checks failed with message: '${error.message}'`, |
| 74 | + task: taskTitle |
61 | 75 | });
|
62 |
| - }); |
| 76 | + } |
63 | 77 | }
|
64 | 78 |
|
65 | 79 | module.exports = {
|
|
0 commit comments