Some minor changes
This commit is contained in:
parent
5e6aac77ed
commit
ab7da09c25
@ -129,7 +129,7 @@ export async function write_version(file: string, platform: string, arch: string
|
|||||||
}
|
}
|
||||||
export async function deploy(platform: string, arch: string, channel: string, version: Version, update_file: string, install_file: string, install_suffix: string) {
|
export async function deploy(platform: string, arch: string, channel: string, version: Version, update_file: string, install_file: string, install_suffix: string) {
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
const url = (process.env["teaclient_deploy_url"] || "http://clientapi.teaspeak.de/") + "api.php";
|
const url = (process.env["teaclient_deploy_url"] || "https://clientapi.teaspeak.de/") + "api.php";
|
||||||
console.log("Requesting " + url);
|
console.log("Requesting " + url);
|
||||||
console.log("Uploading update file " + update_file);
|
console.log("Uploading update file " + update_file);
|
||||||
console.log("Uploading install file " + install_file);
|
console.log("Uploading install file " + install_file);
|
||||||
|
@ -28,8 +28,6 @@ export type UpdateStatsCallback = (message: string, progress: number) => void;
|
|||||||
export type UpdateLogCallback = (type: "error" | "info", message: string) => void;
|
export type UpdateLogCallback = (type: "error" | "info", message: string) => void;
|
||||||
|
|
||||||
export function updateServerUrl() : string {
|
export function updateServerUrl() : string {
|
||||||
/* FIXME! */
|
|
||||||
return "https://clientapi.teaspeak.de/";
|
|
||||||
return processArguments.has_value(...Arguments.SERVER_URL) ? processArguments.value(...Arguments.SERVER_URL) : "https://clientapi.teaspeak.de/";
|
return processArguments.has_value(...Arguments.SERVER_URL) ? processArguments.value(...Arguments.SERVER_URL) : "https://clientapi.teaspeak.de/";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,51 +251,54 @@ if(typeof(String.prototype.trim) === "undefined")
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function ensureTargetFilesAreWriteable(updateFile: string) : Promise<string[]> {
|
export async function ensureTargetFilesAreWriteable(updateFile: string) : Promise<string[]> {
|
||||||
const original_fs = require('original-fs');
|
const originalFs = require('original-fs');
|
||||||
if(!fs.existsSync(updateFile)) {
|
if(!fs.existsSync(updateFile)) {
|
||||||
throw "Missing update file (" + updateFile + ")";
|
throw "Missing update file (" + updateFile + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_path = app.getAppPath();
|
let parentPath = await fs.realpath(path.dirname(app.getPath("exe")));
|
||||||
if(parent_path.endsWith(".asar")) {
|
const testAccess = async (file: string, mode: number) => {
|
||||||
parent_path = path.join(parent_path, "..", "..");
|
return await new Promise<NodeJS.ErrnoException>(resolve => originalFs.access(file, mode, resolve));
|
||||||
parent_path = fs.realpathSync(parent_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
const test_access = async (file: string, mode: number) => {
|
|
||||||
return await new Promise<NodeJS.ErrnoException>(resolve => original_fs.access(file, mode, resolve));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let code = await test_access(updateFile, original_fs.constants.R_OK);
|
let code = await testAccess(updateFile, originalFs.constants.R_OK);
|
||||||
if(code)
|
if(code) {
|
||||||
throw "Failed test read for update file. (" + updateFile + " results in " + code.code + ")";
|
throw "Failed test read for update file. (" + updateFile + " results in " + code.code + ")";
|
||||||
|
}
|
||||||
|
|
||||||
const fstream = original_fs.createReadStream(updateFile);
|
const fstream = originalFs.createReadStream(updateFile);
|
||||||
const tar_stream = tar.extract();
|
const tar_stream = tar.extract();
|
||||||
|
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
const tester = async (header: Headers) => {
|
const tester = async (header: Headers) => {
|
||||||
const entry_path = path.normalize(path.join(parent_path, header.name));
|
const entry_path = path.normalize(path.join(parentPath, header.name));
|
||||||
if(header.type == "file") {
|
if(header.type == "file") {
|
||||||
if(original_fs.existsSync(entry_path)) {
|
if(originalFs.existsSync(entry_path)) {
|
||||||
code = await test_access(entry_path, original_fs.constants.W_OK);
|
code = await testAccess(entry_path, originalFs.constants.W_OK);
|
||||||
if(code)
|
if(code) {
|
||||||
errors.push("Failed to acquire write permissions for file " + entry_path + " (Code " + code.code + ")");
|
errors.push("Failed to acquire write permissions for file " + entry_path + " (Code " + code.code + ")");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let directory = path.dirname(entry_path);
|
let directory = path.dirname(entry_path);
|
||||||
while(directory.length != 0 && !original_fs.existsSync(directory))
|
while(directory.length != 0 && !originalFs.existsSync(directory)) {
|
||||||
directory = path.normalize(path.join(directory, ".."));
|
directory = path.normalize(path.join(directory, ".."));
|
||||||
|
}
|
||||||
|
|
||||||
code = await test_access(directory, original_fs.constants.W_OK);
|
code = await testAccess(directory, originalFs.constants.W_OK);
|
||||||
if(code) errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")");
|
if(code) {
|
||||||
|
errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(header.type == "directory") {
|
} else if(header.type == "directory") {
|
||||||
let directory = path.dirname(entry_path);
|
let directory = path.dirname(entry_path);
|
||||||
while(directory.length != 0 && !original_fs.existsSync(directory))
|
while(directory.length != 0 && !originalFs.existsSync(directory)) {
|
||||||
directory = path.normalize(path.join(directory, ".."));
|
directory = path.normalize(path.join(directory, ".."));
|
||||||
|
}
|
||||||
|
|
||||||
code = await test_access(directory, original_fs.constants.W_OK);
|
code = await testAccess(directory, originalFs.constants.W_OK);
|
||||||
if(code) errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")");
|
if(code) {
|
||||||
|
errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -324,7 +325,7 @@ export async function ensureTargetFilesAreWriteable(updateFile: string) : Promis
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace install_config {
|
namespace InstallConfig {
|
||||||
export interface LockFile {
|
export interface LockFile {
|
||||||
filename: string;
|
filename: string;
|
||||||
timeout: number;
|
timeout: number;
|
||||||
@ -350,9 +351,9 @@ namespace install_config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string) : Promise<install_config.ConfigFile> {
|
async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string) : Promise<InstallConfig.ConfigFile> {
|
||||||
console.log("Building update install config for target directory: %s. Update source: %o", targetRoot, sourceRoot);
|
console.log("Building update install config for target directory: %s. Update source: %o", targetRoot, sourceRoot);
|
||||||
const result: install_config.ConfigFile = { } as any;
|
const result: InstallConfig.ConfigFile = { } as any;
|
||||||
|
|
||||||
result.version = 1;
|
result.version = 1;
|
||||||
|
|
||||||
@ -373,7 +374,7 @@ async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string)
|
|||||||
{
|
{
|
||||||
"error-id": "main-exe-lock",
|
"error-id": "main-exe-lock",
|
||||||
filename: app.getPath("exe"),
|
filename: app.getPath("exe"),
|
||||||
timeout: 5000
|
timeout: 10 * 1000
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -382,14 +383,14 @@ async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string)
|
|||||||
];
|
];
|
||||||
|
|
||||||
const dirWalker = async (relative_path: string) => {
|
const dirWalker = async (relative_path: string) => {
|
||||||
const source_directory = path.join(sourceRoot, relative_path);
|
const sourceDirectory = path.join(sourceRoot, relative_path);
|
||||||
const target_directory = path.join(targetRoot, relative_path);
|
const targetDirectory = path.join(targetRoot, relative_path);
|
||||||
|
|
||||||
let files: string[];
|
let files: string[];
|
||||||
try {
|
try {
|
||||||
files = await util.promisify(ofs.readdir)(source_directory);
|
files = await util.promisify(ofs.readdir)(sourceDirectory);
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
console.warn("Failed to iterate over source directory \"%s\": %o", source_directory, error);
|
console.warn("Failed to iterate over source directory \"%s\": %o", sourceDirectory, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,8 +407,8 @@ async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const source_file = path.join(source_directory, file);
|
const source_file = path.join(sourceDirectory, file);
|
||||||
const target_file = path.join(target_directory, file);
|
const target_file = path.join(targetDirectory, file);
|
||||||
|
|
||||||
//TODO check if file content has changed else ignore?
|
//TODO check if file content has changed else ignore?
|
||||||
|
|
||||||
@ -657,25 +658,21 @@ export async function prepareUpdateExecute(targetVersion: UpdateVersion, callbac
|
|||||||
callbackStats("Downloading update", status.percent);
|
callbackStats("Downloading update", status.percent);
|
||||||
}, callbackLog);
|
}, callbackLog);
|
||||||
|
|
||||||
/* TODO: Remove this step and let the actual updater so this. If this fails we'll already receiving appropiate error messages. */
|
/* TODO: Remove this step and let the actual updater so this. If this fails we'll already receiving appropriate error messages. */
|
||||||
if(os.platform() !== "win32") {
|
if(os.platform() !== "win32") {
|
||||||
callbackLog("info", "Checking file permissions");
|
callbackLog("info", "Checking file permissions");
|
||||||
callbackStats("Checking file permissions", .25);
|
callbackStats("Checking file permissions", .25);
|
||||||
|
|
||||||
/* We must be on a unix based system */
|
/* We must be on a unix based system */
|
||||||
try {
|
const inaccessiblePaths = await ensureTargetFilesAreWriteable(updateFilePath);
|
||||||
const inaccessiblePaths = await ensureTargetFilesAreWriteable(updateFilePath);
|
if(inaccessiblePaths.length > 0) {
|
||||||
if(inaccessiblePaths.length > 0) {
|
console.log("Failed to access the following files:");
|
||||||
console.log("Failed to access the following files:");
|
for(const fail of inaccessiblePaths) {
|
||||||
for(const fail of inaccessiblePaths) {
|
console.log(" - " + fail);
|
||||||
console.log(" - " + fail);
|
|
||||||
}
|
|
||||||
|
|
||||||
const executeCommand = "sudo " + path.normalize(app.getAppPath()) + " --update-execute";
|
|
||||||
throw "Failed to access target files.\nPlease execute this app with administrator (sudo) privileges.\nUse the following command:\n" + executeCommand;
|
|
||||||
}
|
}
|
||||||
} catch(error) {
|
|
||||||
console.warn("Failed to validate target file accessibility: %o", error);
|
const executeCommand = "sudo " + path.normalize(app.getPath("exe")) + " --no-sandbox --update-execute";
|
||||||
|
throw "Failed to access target files.\nPlease execute this app with administrator (sudo) privileges.\nUse the following command:\n" + executeCommand;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* the windows update already requests admin privileges */
|
/* the windows update already requests admin privileges */
|
||||||
@ -753,8 +750,9 @@ export async function prepareUpdateExecute(targetVersion: UpdateVersion, callbac
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(electron.app.hasSingleInstanceLock())
|
if(electron.app.hasSingleInstanceLock()) {
|
||||||
electron.app.releaseSingleInstanceLock();
|
electron.app.releaseSingleInstanceLock();
|
||||||
|
}
|
||||||
|
|
||||||
const ids = child_process.execSync("pgrep TeaClient").toString().split(os.EOL).map(e => e.trim()).reverse().join(" ");
|
const ids = child_process.execSync("pgrep TeaClient").toString().split(os.EOL).map(e => e.trim()).reverse().join(" ");
|
||||||
console.log("Executing %s", "kill -9 " + ids);
|
console.log("Executing %s", "kill -9 " + ids);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "TeaClient",
|
"name": "teaspeak_client",
|
||||||
"version": "1.5.0-8",
|
"version": "1.5.0-8",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user