Skip to content

Commit 19a9e16

Browse files
committed
NC | Online Upgrade CLI
Signed-off-by: Romy <[email protected]>
1 parent 1c8a75f commit 19a9e16

File tree

10 files changed

+317
-7
lines changed

10 files changed

+317
-7
lines changed

src/cmd/manage_nsfs.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const ManageCLIResponse = require('../manage_nsfs/manage_nsfs_cli_responses').Ma
1818
const manage_nsfs_glacier = require('../manage_nsfs/manage_nsfs_glacier');
1919
const manage_nsfs_logging = require('../manage_nsfs/manage_nsfs_logging');
2020
const noobaa_cli_diagnose = require('../manage_nsfs/diagnose');
21+
const noobaa_cli_upgrade = require('../manage_nsfs/upgrade');
2122
const { print_usage } = require('../manage_nsfs/manage_nsfs_help_utils');
2223
const { TYPES, ACTIONS, LIST_ACCOUNT_FILTERS, LIST_BUCKET_FILTERS, GLACIER_ACTIONS } = require('../manage_nsfs/manage_nsfs_constants');
2324
const { throw_cli_error, get_bucket_owner_account, write_stdout_response, get_boolean_or_string_value, has_access_keys, set_debug_level,
@@ -65,6 +66,8 @@ async function main(argv = minimist(process.argv.slice(2))) {
6566
await logging_management();
6667
} else if (type === TYPES.DIAGNOSE) {
6768
await noobaa_cli_diagnose.manage_diagnose_operations(action, user_input, config_fs);
69+
} else if (type === TYPES.UPGRADE) {
70+
await noobaa_cli_upgrade.manage_upgrade_operations(action, config_fs);
6871
} else {
6972
throw_cli_error(ManageCLIError.InvalidType);
7073
}

src/manage_nsfs/manage_nsfs_cli_errors.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ ManageCLIError.InvalidDiagnoseAction = Object.freeze({
7575
http_code: 400,
7676
});
7777

78+
ManageCLIError.InvalidUpgradeAction = Object.freeze({
79+
code: 'InvalidUpgradeAction',
80+
message: 'Invalid action, available actions are start, status and history',
81+
http_code: 400,
82+
});
83+
7884
ManageCLIError.InvalidArgument = Object.freeze({
7985
code: 'InvalidArgument',
8086
message: 'Invalid argument',
@@ -89,7 +95,7 @@ ManageCLIError.InvalidArgumentType = Object.freeze({
8995

9096
ManageCLIError.InvalidType = Object.freeze({
9197
code: 'InvalidType',
92-
message: 'Invalid type, available types are account, bucket, logging or whitelist',
98+
message: 'Invalid type, available types are account, bucket, logging, whitelist or upgrade',
9399
http_code: 400,
94100
});
95101

@@ -445,6 +451,34 @@ ManageCLIError.BucketNotEmpty = Object.freeze({
445451
http_code: 400,
446452
});
447453

454+
455+
///////////////////////////////
456+
// UPGRADE ERRORS //
457+
///////////////////////////////
458+
459+
ManageCLIError.UpgradeFailed = Object.freeze({
460+
code: 'UpgradeFailed',
461+
message: 'Upgrade request failed',
462+
http_code: 500,
463+
});
464+
465+
ManageCLIError.UpgradeStatusFailed = Object.freeze({
466+
code: 'UpgradeStatusFailed',
467+
message: 'Upgrade status request failed',
468+
http_code: 500,
469+
});
470+
471+
ManageCLIError.UpgradeHistoryFailed = Object.freeze({
472+
code: 'UpgradeHistoryFailed',
473+
message: 'Upgrade history request failed',
474+
http_code: 500,
475+
});
476+
477+
///////////////////////////////
478+
// ERRORS MAPPING //
479+
///////////////////////////////
480+
481+
448482
ManageCLIError.FS_ERRORS_TO_MANAGE = Object.freeze({
449483
EACCES: ManageCLIError.AccessDenied,
450484
EPERM: ManageCLIError.AccessDenied,

src/manage_nsfs/manage_nsfs_cli_responses.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,37 @@ ManageCLIResponse.BucketList = Object.freeze({
117117
});
118118

119119
///////////////////////////////
120-
// LOGGING RESPONSES ///
120+
// LOGGING RESPONSES //
121121
///////////////////////////////
122+
122123
ManageCLIResponse.LoggingExported = Object.freeze({
123124
code: 'LoggingExported',
124125
status: {}
125126
});
126127

128+
///////////////////////////////
129+
// UPGRADE RESPONSES //
130+
///////////////////////////////
131+
132+
ManageCLIResponse.UpgradeSuccessful = Object.freeze({
133+
code: 'UpgradeSuccessful',
134+
status: {}
135+
});
136+
137+
ManageCLIResponse.UpgradeStatus = Object.freeze({
138+
code: 'UpgradeStatus',
139+
status: {}
140+
});
141+
142+
ManageCLIResponse.UpgradeHistory = Object.freeze({
143+
code: 'UpgradeHistory',
144+
status: {}
145+
});
146+
147+
///////////////////////////////
148+
// RESPONSES-EVENT MAPPING //
149+
///////////////////////////////
150+
127151
const NSFS_CLI_SUCCESS_EVENT_MAP = {
128152
AccountCreated: NoobaaEvent.ACCOUNT_CREATED,
129153
AccountDeleted: NoobaaEvent.ACCOUNT_DELETED,

src/manage_nsfs/manage_nsfs_constants.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const TYPES = {
77
IP_WHITELIST: 'whitelist',
88
GLACIER: 'glacier',
99
LOGGING: 'logging',
10-
DIAGNOSE: 'diagnose'
10+
DIAGNOSE: 'diagnose',
11+
UPGRADE: 'upgrade'
1112
};
1213

1314
const ACTIONS = {
@@ -30,6 +31,12 @@ const DIAGNOSE_ACTIONS = {
3031
METRICS: 'metrics'
3132
};
3233

34+
const UPGRADE_ACTIONS = {
35+
START: 'start',
36+
STATUS: 'status',
37+
HISTORY: 'history'
38+
};
39+
3340

3441
const CONFIG_ROOT_FLAG = 'config_root';
3542
const CLI_MUTUAL_OPTIONS = new Set([CONFIG_ROOT_FLAG, 'config_root_backend', 'debug']);
@@ -134,6 +141,7 @@ exports.TYPES = TYPES;
134141
exports.ACTIONS = ACTIONS;
135142
exports.GLACIER_ACTIONS = GLACIER_ACTIONS;
136143
exports.DIAGNOSE_ACTIONS = DIAGNOSE_ACTIONS;
144+
exports.UPGRADE_ACTIONS = UPGRADE_ACTIONS;
137145
exports.VALID_OPTIONS = VALID_OPTIONS;
138146
exports.OPTION_TYPE = OPTION_TYPE;
139147
exports.FROM_FILE = FROM_FILE;

src/manage_nsfs/manage_nsfs_help_utils.js

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

4-
const { TYPES, ACTIONS, GLACIER_ACTIONS, DIAGNOSE_ACTIONS } = require('./manage_nsfs_constants');
4+
const { TYPES, ACTIONS, GLACIER_ACTIONS, DIAGNOSE_ACTIONS, UPGRADE_ACTIONS } = require('./manage_nsfs_constants');
55

66
const HELP = `
77
Help:
@@ -281,6 +281,42 @@ Usage:
281281
282282
`;
283283

284+
285+
const UPGRADE_OPTIONS = `
286+
Usage:
287+
288+
'upgrade' is a noobaa-core command that will return the exported metrics of the deployed NooBaa system.
289+
290+
Usage:
291+
292+
noobaa-cli upgrade <action> [flags]
293+
294+
List of actions supported:
295+
296+
start
297+
status
298+
history
299+
300+
`;
301+
302+
const UPGRADE_START_OPTIONS = `
303+
'upgrade start' is a noobaa-core command that will start config directory upgrade run.
304+
Run upgrade start after upgrading NooBaa RPMs on all the cluster nodes, after starting an upgrade of the config directory,
305+
S3 I/O, S3 Buckets getters and NooBaa CLI Account/Buckets/Whitelist getters operations will still be working
306+
But updates of the config directory will be blocked during the upgrade of the config directory.
307+
`;
308+
309+
const UPGRADE_STATUS_OPTIONS = `
310+
'upgrade status' is a noobaa-core command that will return the status of an ongoing upgrade run.
311+
312+
`;
313+
314+
const UPGRADE_HISTORY_OPTIONS = `
315+
'upgrade history' is a noobaa-core command that will return the history of past upgrades.
316+
317+
`;
318+
319+
284320
/**
285321
* print_usage would print the help according to the arguments that were passed
286322
* @param {string} type
@@ -306,6 +342,9 @@ function print_usage(type, action) {
306342
case TYPES.DIAGNOSE:
307343
print_help_diagnose(action);
308344
break;
345+
case TYPES.UPGRADE:
346+
print_help_upgrade(action);
347+
break;
309348
default:
310349
process.stdout.write(HELP + '\n');
311350
process.stdout.write(USAGE.trimStart() + '\n');
@@ -368,6 +407,9 @@ function print_help_bucket(action) {
368407
process.exit(0);
369408
}
370409

410+
/**
411+
* @param {string} action
412+
*/
371413
function print_help_glacier(action) {
372414
switch (action) {
373415
case GLACIER_ACTIONS.MIGRATE:
@@ -384,6 +426,9 @@ function print_help_glacier(action) {
384426
}
385427
}
386428

429+
/**
430+
* @param {string} action
431+
*/
387432
function print_help_diagnose(action) {
388433
switch (action) {
389434
case DIAGNOSE_ACTIONS.HEALTH:
@@ -400,5 +445,25 @@ function print_help_diagnose(action) {
400445
}
401446
}
402447

448+
/**
449+
* @param {string} action
450+
*/
451+
function print_help_upgrade(action) {
452+
switch (action) {
453+
case UPGRADE_ACTIONS.START:
454+
process.stdout.write(UPGRADE_START_OPTIONS.trimStart());
455+
break;
456+
case UPGRADE_ACTIONS.STATUS:
457+
process.stdout.write(UPGRADE_STATUS_OPTIONS.trimStart());
458+
break;
459+
case UPGRADE_ACTIONS.HISTORY:
460+
process.stdout.write(UPGRADE_HISTORY_OPTIONS.trimStart());
461+
break;
462+
default:
463+
process.stdout.write(UPGRADE_OPTIONS.trimStart());
464+
}
465+
}
466+
467+
403468
// EXPORTS
404469
exports.print_usage = print_usage;

src/manage_nsfs/manage_nsfs_validations.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const bucket_policy_utils = require('../endpoint/s3/s3_bucket_policy_utils');
1212
const { throw_cli_error, get_bucket_owner_account, get_options_from_file, get_boolean_or_string_value,
1313
check_root_account_owns_user, is_name_update, is_access_key_update } = require('../manage_nsfs/manage_nsfs_cli_utils');
1414
const { TYPES, ACTIONS, VALID_OPTIONS, OPTION_TYPE, FROM_FILE, BOOLEAN_STRING_VALUES, BOOLEAN_STRING_OPTIONS,
15-
GLACIER_ACTIONS, LIST_UNSETABLE_OPTIONS, ANONYMOUS, DIAGNOSE_ACTIONS } = require('../manage_nsfs/manage_nsfs_constants');
15+
GLACIER_ACTIONS, LIST_UNSETABLE_OPTIONS, ANONYMOUS, DIAGNOSE_ACTIONS, UPGRADE_ACTIONS } = require('../manage_nsfs/manage_nsfs_constants');
1616
const iam_utils = require('../endpoint/iam/iam_utils');
1717

1818
/////////////////////////////
@@ -76,6 +76,8 @@ function validate_type_and_action(type, action) {
7676
if (!Object.values(GLACIER_ACTIONS).includes(action)) throw_cli_error(ManageCLIError.InvalidAction);
7777
} else if (type === TYPES.DIAGNOSE) {
7878
if (!Object.values(DIAGNOSE_ACTIONS).includes(action)) throw_cli_error(ManageCLIError.InvalidDiagnoseAction);
79+
} else if (type === TYPES.UPGRADE) {
80+
if (!Object.values(UPGRADE_ACTIONS).includes(action)) throw_cli_error(ManageCLIError.InvalidUpgradeAction);
7981
}
8082
}
8183

src/manage_nsfs/upgrade.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/* Copyright (C) 2024 NooBaa */
2+
'use strict';
3+
4+
const dbg = require('../util/debug_module')(__filename);
5+
const { ManageCLIError } = require('./manage_nsfs_cli_errors');
6+
const { UPGRADE_ACTIONS } = require('./manage_nsfs_constants');
7+
const { ManageCLIResponse } = require('../manage_nsfs/manage_nsfs_cli_responses');
8+
const { throw_cli_error, write_stdout_response } = require('./manage_nsfs_cli_utils');
9+
10+
/**
11+
* manage_upgrade_operations handles cli upgrade operations
12+
* @param {string} action
13+
* @returns {Promise<Void>}
14+
*/
15+
async function manage_upgrade_operations(action, config_fs) {
16+
switch (action) {
17+
case UPGRADE_ACTIONS.START:
18+
await exec_config_dir_upgrade();
19+
break;
20+
case UPGRADE_ACTIONS.STATUS:
21+
await get_upgrade_status(config_fs);
22+
break;
23+
case UPGRADE_ACTIONS.HISTORY:
24+
await get_upgrade_history(config_fs);
25+
break;
26+
default:
27+
throw_cli_error(ManageCLIError.InvalidAction);
28+
}
29+
}
30+
31+
/**
32+
* exec_config_dir_upgrade handles cli upgrade operation
33+
* @returns {Promise<Void>}
34+
*/
35+
async function exec_config_dir_upgrade() {
36+
try {
37+
// TODO - add verifications and a call to the config directory upgrade
38+
throw new Error('Upgrade Config Directory is not implemented yet');
39+
} catch (err) {
40+
dbg.warn('could not upgrade config directory successfully - err', err);
41+
throw_cli_error({ ...ManageCLIError.UpgradeFailed, cause: err?.errors?.[0] || err });
42+
}
43+
}
44+
45+
/**
46+
* get_upgrade_status handles cli upgrade status operation
47+
* @param {import('../sdk/config_fs').ConfigFS} config_fs
48+
* @returns {Promise<Void>}
49+
*/
50+
async function get_upgrade_status(config_fs) {
51+
try {
52+
const system_config = await config_fs.get_system_config_file();
53+
const upgrade_status = system_config?.config_directory?.in_progress_upgrade;
54+
if (!upgrade_status) throw new Error('Config directory upgrade status is empty, there is no ongoing config directory upgrade or there is an error', { cause: system_config });
55+
write_stdout_response(ManageCLIResponse.UpgradeStatus, upgrade_status);
56+
} catch (err) {
57+
dbg.warn('could not get upgrade status response', err);
58+
throw_cli_error({ ...ManageCLIError.UpgradeStatusFailed, cause: err?.errors?.[0] || err });
59+
}
60+
}
61+
62+
/**
63+
* get_upgrade_history handles cli upgrade history operation
64+
* @param {import('../sdk/config_fs').ConfigFS} config_fs
65+
* @returns {Promise<Void>}
66+
*/
67+
async function get_upgrade_history(config_fs) {
68+
try {
69+
const system_config = await config_fs.get_system_config_file();
70+
const upgrade_history = system_config?.config_directory?.upgrade_history;
71+
if (!upgrade_history) throw new Error('Config directory upgrade history is empty', { cause: system_config });
72+
write_stdout_response(ManageCLIResponse.UpgradeHistory, upgrade_history);
73+
} catch (err) {
74+
dbg.warn('could not get upgrade history response', err);
75+
throw_cli_error({ ...ManageCLIError.UpgradeHistoryFailed, cause: err?.errors?.[0] || err });
76+
}
77+
}
78+
79+
exports.manage_upgrade_operations = manage_upgrade_operations;

src/sdk/config_fs.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class ConfigFS {
6767
this.identities_dir_path = path.join(config_root, CONFIG_SUBDIRS.IDENTITIES);
6868
this.access_keys_dir_path = path.join(config_root, CONFIG_SUBDIRS.ACCESS_KEYS);
6969
this.buckets_dir_path = path.join(config_root, CONFIG_SUBDIRS.BUCKETS);
70+
this.system_json_path = path.join(config_root, 'system.json');
7071
this.config_json_path = path.join(config_root, 'config.json');
7172
this.fs_context = fs_context || native_fs_utils.get_process_fs_context(this.config_root_backend);
7273
}
@@ -349,7 +350,7 @@ class ConfigFS {
349350
* @returns {string}
350351
*/
351352
get_identity_dir_path_by_id(id) {
352-
return path.join(this.config_root, CONFIG_SUBDIRS.IDENTITIES, id, '/');
353+
return path.join(this.identities_dir_path, id, '/');
353354
}
354355

355356
/**
@@ -841,6 +842,14 @@ class ConfigFS {
841842
await native_fs_utils.delete_config_file(this.fs_context, this.buckets_dir_path, bucket_config_path);
842843
}
843844

845+
/**
846+
* get_system_config_file read system.json file
847+
* @returns {Promise<Object>}
848+
*/
849+
async get_system_config_file() {
850+
const system_data = await this.get_config_data(this.system_json_path);
851+
return system_data;
852+
}
844853

845854
////////////////////////
846855
/// HELPERS ////

src/test/system_tests/test_utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ function get_coretest_path() {
239239
* @param {string} type
240240
* @param {string} action
241241
* @param {object} options
242-
* @returns {Promise<string>}
242+
* @returns {Promise<string | Error>}
243243
*/
244244
async function exec_manage_cli(type, action, options, is_silent, env) {
245245
let flags = ``;

0 commit comments

Comments
 (0)