mirror of
https://github.com/kopia/kopia.git
synced 2026-01-25 23:08:01 -05:00
* build(deps): bump the kopia-ui-npm-dependencies group across 1 directory with 9 updates Bumps the kopia-ui-npm-dependencies group with 7 updates in the /app directory: | Package | From | To | | --- | --- | --- | | [electron-log](https://github.com/megahertz/electron-log) | `5.1.2` | `5.1.5` | | [electron-store](https://github.com/sindresorhus/electron-store) | `8.2.0` | `10.0.0` | | [electron-updater](https://github.com/electron-userland/electron-builder/tree/HEAD/packages/electron-updater) | `6.3.0-alpha.6` | `6.3.0-alpha.7` | | [uuid](https://github.com/uuidjs/uuid) | `9.0.1` | `10.0.0` | | [@electron/notarize](https://github.com/electron/notarize) | `2.3.0` | `2.3.2` | | [@playwright/test](https://github.com/microsoft/playwright) | `1.42.1` | `1.45.1` | | [electron](https://github.com/electron/electron) | `29.1.6` | `31.2.0` | Updates `electron-log` from 5.1.2 to 5.1.5 - [Changelog](https://github.com/megahertz/electron-log/blob/master/CHANGELOG.md) - [Commits](https://github.com/megahertz/electron-log/compare/v5.1.2...v5.1.5) Updates `electron-store` from 8.2.0 to 10.0.0 - [Release notes](https://github.com/sindresorhus/electron-store/releases) - [Commits](https://github.com/sindresorhus/electron-store/compare/v8.2.0...v10.0.0) Updates `electron-updater` from 6.3.0-alpha.6 to 6.3.0-alpha.7 - [Release notes](https://github.com/electron-userland/electron-builder/releases) - [Changelog](https://github.com/electron-userland/electron-builder/blob/master/packages/electron-updater/CHANGELOG.md) - [Commits](https://github.com/electron-userland/electron-builder/commits/electron-updater@6.3.0-alpha.7/packages/electron-updater) Updates `uuid` from 9.0.1 to 10.0.0 - [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md) - [Commits](https://github.com/uuidjs/uuid/compare/v9.0.1...v10.0.0) Updates `@electron/notarize` from 2.3.0 to 2.3.2 - [Release notes](https://github.com/electron/notarize/releases) - [Changelog](https://github.com/electron/notarize/blob/main/.releaserc.json) - [Commits](https://github.com/electron/notarize/compare/v2.3.0...v2.3.2) Updates `@playwright/test` from 1.42.1 to 1.45.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.42.1...v1.45.1) Updates `electron` from 29.1.6 to 31.2.0 - [Release notes](https://github.com/electron/electron/releases) - [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md) - [Commits](https://github.com/electron/electron/compare/v29.1.6...v31.2.0) Updates `playwright` from 1.42.1 to 1.45.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.42.1...v1.45.1) Updates `playwright-core` from 1.42.1 to 1.45.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.42.1...v1.45.1) --- updated-dependencies: - dependency-name: electron-log dependency-type: direct:production update-type: version-update:semver-patch dependency-group: kopia-ui-npm-dependencies - dependency-name: electron-store dependency-type: direct:production update-type: version-update:semver-major dependency-group: kopia-ui-npm-dependencies - dependency-name: electron-updater dependency-type: direct:production update-type: version-update:semver-patch dependency-group: kopia-ui-npm-dependencies - dependency-name: uuid dependency-type: direct:production update-type: version-update:semver-major dependency-group: kopia-ui-npm-dependencies - dependency-name: "@electron/notarize" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: kopia-ui-npm-dependencies - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: kopia-ui-npm-dependencies - dependency-name: electron dependency-type: direct:development update-type: version-update:semver-major dependency-group: kopia-ui-npm-dependencies - dependency-name: playwright dependency-type: direct:development update-type: version-update:semver-minor dependency-group: kopia-ui-npm-dependencies - dependency-name: playwright-core dependency-type: direct:development update-type: version-update:semver-minor dependency-group: kopia-ui-npm-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * upgraded app to ES modules * renamed notarize.js and sign.js to CommonJS --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jarek Kowalski <jaak@jkowalski.net>
256 lines
8.3 KiB
JavaScript
256 lines
8.3 KiB
JavaScript
import { ipcMain } from 'electron';
|
|
const path = await import('path');
|
|
const https = await import('https');
|
|
|
|
import { defaultServerBinary } from './utils.js';
|
|
import { spawn } from 'child_process';
|
|
import log from "electron-log";
|
|
import { configDir, isPortableConfig } from './config.js';
|
|
|
|
let servers = {};
|
|
|
|
function newServerForRepo(repoID) {
|
|
let runningServerProcess = null;
|
|
let runningServerCertSHA256 = "";
|
|
let runningServerPassword = "";
|
|
let runningServerControlPassword = "";
|
|
let runningServerAddress = "";
|
|
let runningServerCertificate = "";
|
|
let runningServerStatusDetails = {
|
|
startingUp: true,
|
|
};
|
|
let serverLog = [];
|
|
|
|
const maxLogLines = 100;
|
|
|
|
return {
|
|
actuateServer() {
|
|
log.info('actuating Server', repoID);
|
|
this.stopServer();
|
|
this.startServer();
|
|
},
|
|
|
|
startServer() {
|
|
let kopiaPath = defaultServerBinary();
|
|
let args = [];
|
|
|
|
args.push('server', 'start', '--ui',
|
|
'--tls-print-server-cert',
|
|
'--tls-generate-cert-name=127.0.0.1',
|
|
'--random-password',
|
|
'--random-server-control-password',
|
|
'--tls-generate-cert',
|
|
'--async-repo-connect',
|
|
'--shutdown-on-stdin', // shutdown the server when parent dies
|
|
'--address=127.0.0.1:0');
|
|
|
|
|
|
args.push("--config-file", path.resolve(configDir(), repoID + ".config"));
|
|
if (isPortableConfig()) {
|
|
const cacheDir = path.resolve(configDir(), "cache", repoID);
|
|
const logsDir = path.resolve(configDir(), "logs", repoID);
|
|
args.push("--cache-directory", cacheDir);
|
|
args.push("--log-dir", logsDir);
|
|
}
|
|
|
|
log.info(`spawning ${kopiaPath} ${args.join(' ')}`);
|
|
runningServerProcess = spawn(kopiaPath, args, {
|
|
});
|
|
this.raiseStatusUpdatedEvent();
|
|
|
|
runningServerProcess.stdout.on('data', this.appendToLog.bind(this));
|
|
runningServerProcess.stderr.on('data', this.detectServerParam.bind(this));
|
|
|
|
const p = runningServerProcess;
|
|
|
|
log.info('starting polling loop');
|
|
|
|
const statusUpdated = this.raiseStatusUpdatedEvent.bind(this);
|
|
|
|
const pollInterval = 3000;
|
|
|
|
function pollOnce() {
|
|
if (!runningServerAddress || !runningServerCertificate || !runningServerPassword || !runningServerControlPassword) {
|
|
return;
|
|
}
|
|
|
|
const req = https.request({
|
|
ca: [runningServerCertificate],
|
|
host: "127.0.0.1",
|
|
port: parseInt(new URL(runningServerAddress).port),
|
|
method: "GET",
|
|
path: "/api/v1/control/status",
|
|
timeout: pollInterval,
|
|
headers: {
|
|
'Authorization': 'Basic ' + Buffer.from("server-control" + ':' + runningServerControlPassword).toString('base64')
|
|
}
|
|
}, (resp) => {
|
|
if (resp.statusCode === 200) {
|
|
resp.on('data', x => {
|
|
try {
|
|
const newDetails = JSON.parse(x);
|
|
if (JSON.stringify(newDetails) != JSON.stringify(runningServerStatusDetails)) {
|
|
runningServerStatusDetails = newDetails;
|
|
statusUpdated();
|
|
}
|
|
} catch (e) {
|
|
log.warn('unable to parse status JSON', e);
|
|
}
|
|
});
|
|
} else {
|
|
log.warn('error fetching status', resp.statusMessage);
|
|
}
|
|
});
|
|
req.on('error', (e)=>{
|
|
log.info('error fetching status', e);
|
|
});
|
|
req.end();
|
|
}
|
|
|
|
const statusPollInterval = setInterval(pollOnce, pollInterval);
|
|
|
|
runningServerProcess.on('close', (code, signal) => {
|
|
this.appendToLog(`child process exited with code ${code} and signal ${signal}`);
|
|
if (runningServerProcess === p) {
|
|
clearInterval(statusPollInterval);
|
|
|
|
runningServerAddress = "";
|
|
runningServerPassword = "";
|
|
runningServerControlPassword = "";
|
|
runningServerCertSHA256 = "";
|
|
runningServerProcess = null;
|
|
this.raiseStatusUpdatedEvent();
|
|
}
|
|
});
|
|
},
|
|
|
|
detectServerParam(data) {
|
|
let lines = (data + '').split('\n');
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const p = lines[i].indexOf(": ");
|
|
if (p < 0) {
|
|
continue
|
|
}
|
|
|
|
const key = lines[i].substring(0, p);
|
|
const value = lines[i].substring(p + 2);
|
|
switch (key) {
|
|
case "SERVER PASSWORD":
|
|
runningServerPassword = value;
|
|
this.raiseStatusUpdatedEvent();
|
|
break;
|
|
|
|
case "SERVER CONTROL PASSWORD":
|
|
runningServerControlPassword = value;
|
|
this.raiseStatusUpdatedEvent();
|
|
break;
|
|
|
|
case "SERVER CERT SHA256":
|
|
runningServerCertSHA256 = value;
|
|
this.raiseStatusUpdatedEvent();
|
|
break;
|
|
|
|
case "SERVER CERTIFICATE":
|
|
runningServerCertificate = Buffer.from(value, 'base64').toString('ascii');
|
|
this.raiseStatusUpdatedEvent();
|
|
break;
|
|
|
|
case "SERVER ADDRESS":
|
|
runningServerAddress = value;
|
|
this.raiseStatusUpdatedEvent();
|
|
break;
|
|
}
|
|
}
|
|
|
|
this.appendToLog(data);
|
|
},
|
|
|
|
appendToLog(data) {
|
|
const l = serverLog.push(data);
|
|
if (l > maxLogLines) {
|
|
serverLog.splice(0, 1);
|
|
}
|
|
|
|
ipcMain.emit('logs-updated-event', {
|
|
repoID: repoID,
|
|
logs: serverLog.join(''),
|
|
});
|
|
log.info(`${data}`);
|
|
},
|
|
|
|
stopServer() {
|
|
if (!runningServerProcess) {
|
|
log.info('stopServer: server not started');
|
|
return;
|
|
}
|
|
|
|
runningServerProcess.kill();
|
|
runningServerAddress = "";
|
|
runningServerPassword = "";
|
|
runningServerCertSHA256 = "";
|
|
runningServerCertificate = "";
|
|
runningServerProcess = null;
|
|
this.raiseStatusUpdatedEvent();
|
|
},
|
|
|
|
getServerAddress() {
|
|
return runningServerAddress;
|
|
},
|
|
|
|
getServerCertSHA256() {
|
|
return runningServerCertSHA256;
|
|
},
|
|
|
|
getServerPassword() {
|
|
return runningServerPassword;
|
|
},
|
|
|
|
getServerStatusDetails() {
|
|
return runningServerStatusDetails;
|
|
},
|
|
|
|
getServerStatus() {
|
|
if (!runningServerProcess) {
|
|
return "Stopped";
|
|
}
|
|
|
|
if (runningServerCertSHA256 && runningServerAddress && runningServerPassword) {
|
|
return "Running";
|
|
}
|
|
|
|
return "Starting";
|
|
},
|
|
|
|
raiseStatusUpdatedEvent() {
|
|
const args = {
|
|
repoID: repoID,
|
|
status: this.getServerStatus(),
|
|
serverAddress: this.getServerAddress() || "<pending>",
|
|
serverCertSHA256: this.getServerCertSHA256() || "<pending>",
|
|
};
|
|
|
|
ipcMain.emit('status-updated-event', args);
|
|
},
|
|
};
|
|
};
|
|
|
|
ipcMain.on('status-fetch', (event, args) => {
|
|
const repoID = args.repoID;
|
|
const s = servers[repoID]
|
|
if (s) {
|
|
s.raiseStatusUpdatedEvent();
|
|
}
|
|
})
|
|
|
|
export function serverForRepo(repoID) {
|
|
let s = servers[repoID];
|
|
if (s) {
|
|
return s;
|
|
}
|
|
|
|
s = newServerForRepo(repoID);
|
|
servers[repoID] = s;
|
|
return s;
|
|
}
|
|
|