Skip to content

Commit e480192

Browse files
authored
Merge pull request #8560 from romayalon/romy-online-upgrade-fixes
NC | Online Upgrade GPFS fixes + new host but existing system fix
2 parents 3aabb04 + de66d95 commit e480192

File tree

4 files changed

+38
-36
lines changed

4 files changed

+38
-36
lines changed

src/manage_nsfs/manage_nsfs_help_utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Usage:
2323
const ARGUMENTS = `
2424
Arguments:
2525
26-
<type> Set the resource type: account, bucket, whitelist, diagnose or logging
26+
<type> Set the resource type: account, bucket, whitelist, diagnose, logging or upgrade
2727
<action> Action could be: add, update, list, status, and delete for accounts/buckets
2828
`;
2929

src/sdk/config_fs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ class ConfigFS {
10631063
} else {
10641064
if (updated_system_json[hostname]?.current_version) return;
10651065
const new_host_data = this._get_new_hostname_data();
1066-
updated_system_json = { ...updated_system_json, new_host_data };
1066+
updated_system_json = { ...updated_system_json, ...new_host_data };
10671067
await this.update_system_config_file(JSON.stringify(updated_system_json));
10681068
dbg.log0('updated NC system data with version: ', pkg.version);
10691069
return updated_system_json;
@@ -1171,7 +1171,7 @@ class ConfigFS {
11711171
return {
11721172
[os.hostname()]: {
11731173
current_version: pkg.version,
1174-
upgrade_history: {
1174+
upgrade_history: {
11751175
successful_upgrades: []
11761176
},
11771177
},

src/upgrade/nc_upgrade_scripts/1.0.0/config_dir_restructure.js

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* Copyright (C) 2024 NooBaa */
22
'use strict';
33

4+
const util = require('util');
45
const path = require('path');
56
const P = require('../../../util/promise');
67
const config = require('../../../../config');
@@ -37,13 +38,11 @@ async function run({ dbg }) {
3738

3839
await config_fs.create_dir_if_missing(config_fs.identities_dir_path);
3940
await config_fs.create_dir_if_missing(config_fs.accounts_by_name_dir_path);
40-
const tmp_access_keys_path = path.join(config_fs.access_keys_dir_path, native_fs_utils.get_config_files_tmpdir());
41-
await config_fs.create_dir_if_missing(tmp_access_keys_path);
4241

4342
const old_account_names = await config_fs.list_old_accounts();
44-
const failed_accounts = await upgrade_accounts_config_files(config_fs, old_account_names, tmp_access_keys_path, dbg);
43+
const failed_accounts = await upgrade_accounts_config_files(config_fs, old_account_names, dbg);
4544

46-
if (failed_accounts.length > 0) throw new Error('NC upgrade process failed, failed_accounts array length is bigger than 0' + failed_accounts);
45+
if (failed_accounts.length > 0) throw new Error('NC upgrade process failed, failed_accounts array length is bigger than 0' + util.inspect(failed_accounts));
4746
await move_old_accounts_dir(fs_context, config_fs, old_account_names, dbg);
4847
} catch (err) {
4948
dbg.error('NC upgrade process failed due to - ', err);
@@ -60,13 +59,17 @@ async function run({ dbg }) {
6059
* @param {*} dbg
6160
* @returns {Promise<Object[]>}
6261
*/
63-
async function upgrade_accounts_config_files(config_fs, old_account_names, tmp_access_keys_path, dbg) {
62+
async function upgrade_accounts_config_files(config_fs, old_account_names, dbg) {
6463
const failed_accounts = [];
64+
65+
const backup_access_keys_path = path.join(config_fs.config_root, '.backup_access_keys_dir/');
66+
await config_fs.create_dir_if_missing(backup_access_keys_path);
67+
6568
for (const account_name of old_account_names) {
6669
let retries = 3;
6770
while (retries > 0) {
6871
try {
69-
await upgrade_account_config_file(config_fs, account_name, tmp_access_keys_path, dbg);
72+
await upgrade_account_config_file(config_fs, account_name, backup_access_keys_path, dbg);
7073
break;
7174
} catch (err) {
7275
retries -= 1;
@@ -79,6 +82,12 @@ async function upgrade_accounts_config_files(config_fs, old_account_names, tmp_a
7982
}
8083
}
8184
}
85+
try {
86+
// delete dir only if it's empty
87+
await nb_native().fs.rmdir(config_fs.fs_context, backup_access_keys_path);
88+
} catch (err) {
89+
dbg.warn(`config_dir_restructure.upgrade_accounts_cofig_files could not delete access keys backup directory ${backup_access_keys_path} err ${err}`);
90+
}
8291
return failed_accounts;
8392
}
8493

@@ -90,18 +99,18 @@ async function upgrade_accounts_config_files(config_fs, old_account_names, tmp_a
9099
* 1.4. delete account old path
91100
* @param {import('../../../sdk/config_fs').ConfigFS} config_fs
92101
* @param {String} account_name
93-
* @param {String} tmp_access_keys_path
102+
* @param {String} backup_access_keys_path
94103
* @param {*} dbg
95104
* @returns
96105
*/
97-
async function upgrade_account_config_file(config_fs, account_name, tmp_access_keys_path, dbg) {
106+
async function upgrade_account_config_file(config_fs, account_name, backup_access_keys_path, dbg) {
98107
let account_upgrade_params;
99108
const fs_context = config_fs.fs_context;
100109
try {
101110
account_upgrade_params = await prepare_account_upgrade_params(config_fs, account_name);
102111
await create_identity_if_missing(fs_context, account_upgrade_params, dbg);
103112
await create_account_name_index_if_missing(config_fs, account_upgrade_params, dbg);
104-
await create_account_access_keys_index_if_missing(config_fs, account_upgrade_params, tmp_access_keys_path, dbg);
113+
await create_account_access_keys_index_if_missing(config_fs, account_upgrade_params, backup_access_keys_path, dbg);
105114
} catch (err) {
106115
dbg.warn(`upgrade account config failed ${account_name}, err ${err}`);
107116
throw err;
@@ -130,7 +139,7 @@ async function prepare_account_upgrade_params(config_fs, account_name) {
130139
const identity_dir_path = config_fs.get_identity_dir_path_by_id(_id);
131140

132141
const is_gpfs = native_fs_utils._is_gpfs(fs_context);
133-
const dst_file = is_gpfs ? await native_fs_utils.open_file(fs_context, undefined, identity_path, 'r') : undefined;
142+
const dst_file = is_gpfs ? await native_fs_utils.open_file(fs_context, undefined, identity_path, 'w') : undefined;
134143

135144
return {
136145
account_name,
@@ -192,48 +201,41 @@ async function create_account_name_index_if_missing(config_fs, account_upgrade_p
192201
* 1. iterate all access keys array (there should be only one access_key)
193202
* 2. check if we already have an access_key symlink pointing to the identity, if there is, continue
194203
* 3. symlink tmp access_key path to the identity path
195-
* 4. if GPFS - linkfileat the tmp access_key path to access_key path
196-
* 5. if POSIX - rename tmp access_key path to access_key path
197-
* on GPFS it's better to use linkfileat for performance improvements rather then rename
198-
* linkfileat also overrides the existing file
199-
* TODO - test on GPFS
204+
* 4. rename tmp access_key path to access_key path - this will replace atomically the old symlink with the new one
200205
* @param {import('../../../sdk/config_fs').ConfigFS} config_fs
201206
* @param {AccountUpgradeParams} account_upgrade_params
207+
* @param {String} backup_access_keys_path
202208
* @param {*} dbg
203209
* @returns {Promise<Void>}
204210
*/
205-
async function create_account_access_keys_index_if_missing(config_fs, account_upgrade_params, tmp_access_keys_path, dbg) {
211+
async function create_account_access_keys_index_if_missing(config_fs, account_upgrade_params, backup_access_keys_path, dbg) {
206212
const { fs_context } = config_fs;
207213
const { access_keys, _id, identity_path } = account_upgrade_params;
208214

209215
if (access_keys) {
210216
for (const { access_key } of access_keys) {
211217
const access_key_path = config_fs.get_account_or_user_path_by_access_key(access_key);
212-
const tmp_access_key_path = path.join(tmp_access_keys_path, native_fs_utils.get_config_files_tmpdir());
218+
const tmp_access_key_path = path.join(backup_access_keys_path, config_fs.symlink(access_key));
213219
const account_config_relative_path = config_fs.get_account_relative_path_by_id(_id);
214220

215-
const access_key_already_linked = await config_fs._is_symlink_pointing_to_identity(access_key_path, identity_path);
216-
if (access_key_already_linked) continue;
221+
try {
222+
const access_key_already_linked = await config_fs._is_symlink_pointing_to_identity(access_key_path, identity_path);
223+
if (access_key_already_linked) continue;
224+
} catch (err) {
225+
dbg.warn(`config_dir_restructure.create_account_access_keys_index_if_missing _is_symlink_pointing_to_identity failed ${access_key}`, err);
226+
}
217227

218228
try {
219229
await nb_native().fs.symlink(fs_context, account_config_relative_path, tmp_access_key_path);
220230
} catch (err) {
221231
if (err.code !== 'EEXIST') throw err;
222232
dbg.warn(`account access key backup was already linked on a previous run of the upgrade script, continue ${access_keys}, ${tmp_access_key_path}`);
223233
}
224-
let src_file;
225234
try {
226-
if (native_fs_utils._is_gpfs(fs_context)) {
227-
src_file = await nb_native().fs.open(fs_context, tmp_access_key_path, 'r', native_fs_utils.get_umasked_mode(config.BASE_MODE_CONFIG_FILE));
228-
await src_file.linkfileat(fs_context, access_key_path);
229-
} else {
230-
await nb_native().fs.rename(fs_context, tmp_access_key_path, access_key_path);
231-
}
235+
await nb_native().fs.rename(fs_context, tmp_access_key_path, access_key_path);
232236
} catch (err) {
233237
if (err.code !== 'EEXIST') throw err;
234238
dbg.warn(`account access key was already linked on a previous run of the upgrade script, skipping ${access_keys}, ${_id}`);
235-
} finally {
236-
if (src_file) await src_file.close(fs_context);
237239
}
238240
}
239241
}

src/util/native_fs_utils.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,12 @@ async function safe_unlink(fs_context, src_path, src_ver_info, gpfs_options, tmp
189189

190190
async function safe_link(fs_context, src_path, dst_path, src_ver_info, gpfs_options) {
191191
if (_is_gpfs(fs_context)) {
192-
const { src_file = undefined, dir_file = undefined } = gpfs_options;
193-
if (dir_file) {
194-
await safe_link_gpfs(fs_context, src_path, src_file, dir_file);
192+
const { src_file = undefined, dst_file = undefined } = gpfs_options;
193+
if (dst_file) {
194+
await safe_link_gpfs(fs_context, dst_path, src_file, dst_file);
195195
} else {
196-
dbg.error(`safe_link: dir_file is ${dir_file}, cannot use it to call safe_unlink_gpfs`);
197-
throw new Error(`dir_file is ${dir_file}, need a value to safe unlink GPFS`);
196+
dbg.error(`safe_link: dst_file is ${dst_file}, cannot use it to call safe_link_gpfs`);
197+
throw new Error(`dst_file is ${dst_file}, need a value to safe link GPFS`);
198198
}
199199
} else {
200200
await safe_link_posix(fs_context, src_path, dst_path, src_ver_info);

0 commit comments

Comments
 (0)