Skip to content

Commit 9a25606

Browse files
Merge pull request #8795 from romayalon/romy-5.18-backports2
5.18 Backport | online upgrade | make hosts verification optional
2 parents 67f2d44 + 07be72d commit 9a25606

File tree

7 files changed

+87
-34
lines changed

7 files changed

+87
-34
lines changed

docs/NooBaaNonContainerized/NooBaaCLI.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ The `upgrade start` command is used to start a config directory upgrade run.
483483

484484
#### Usage
485485
```sh
486-
noobaa-cli upgrade start --expected_version <expected-version> --expected_hosts <expected-hosts> [--skip-verification] [--custom_upgrade_scripts_dir]
486+
noobaa-cli upgrade start --expected_version <expected-version> [--expected_hosts] <expected-hosts> [--skip-verification] [--custom_upgrade_scripts_dir]
487487
```
488488

489489
#### Flags -
@@ -492,7 +492,7 @@ noobaa-cli upgrade start --expected_version <expected-version> --expected_hosts
492492
- Description: Specifies the upgrade's expected target version.
493493
- Example - `--expected_version 5.18.0`
494494

495-
- `expected_hosts` (Required)
495+
- `expected_hosts`
496496
- Type: String
497497
- Description: Specifies the upgrade's expected hosts. String of hostnames separated by comma (,).
498498
- Example - `--expected_hosts hostname1,hostname2,hostname3`

docs/NooBaaNonContainerized/Upgrade.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ Online Upgrade Algorithm commands examples -
103103
2. Stop NooBaa service - `systemctl stop noobaa`
104104
3. RPM upgrade on a specific node - `rpm -Uvh /path/to/new_noobaa_rpm_version.rpm`
105105
4. Restart NooBaa service - `systemctl restart noobaa`
106-
5. `noobaa-cli upgrade start --expected_version=5.18.0 --expected_hosts=hostname1,hostname2,hostname3`
106+
5. Check that each node has NooBaa service running with the new code - `curl -k https://localhost:6443/_/version` or `curl http://${host_address}:6001/_/version`
107+
6. `noobaa-cli upgrade start --expected_version=5.18.0`
108+
107109

108110
### Additional Upgrade Properties of `system.json`
109111

src/endpoint/endpoint.js

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require('../util/dotenv').load();
77
require('../util/panic');
88
require('../util/fips');
9+
const pkg = require('../../package.json');
910

1011
const dbg = require('../util/debug_module')(__filename);
1112
if (!dbg.get_process_name()) dbg.set_process_name('Endpoint');
@@ -294,6 +295,14 @@ function create_endpoint_handler(server_type, init_request_sdk, { virtual_hosts,
294295
return fork_count_handler(req, res);
295296
} else if (req.url.startsWith('/endpoint_fork_id')) {
296297
return endpoint_fork_id_handler(req, res);
298+
} else if (req.url.startsWith('/_/')) {
299+
// internals non S3 requests
300+
const api = req.url.slice('/_/'.length);
301+
if (api === 'version') {
302+
return version_handler(req, res);
303+
} else {
304+
return internal_api_error(req, res, `Unknown API call ${api}`);
305+
}
297306
} else {
298307
return s3_rest.handler(req, res);
299308
}
@@ -325,28 +334,67 @@ function create_endpoint_handler(server_type, init_request_sdk, { virtual_hosts,
325334
}
326335
}
327336

337+
///////////////////////////
338+
// INTERNAL API HANDLERS //
339+
///////////////////////////
340+
341+
/**
342+
* version_handler returns the version of noobaa package
343+
* @param {EndpointRequest} req
344+
* @param {import('http').ServerResponse} res
345+
*/
346+
function version_handler(req, res) {
347+
const noobaa_package_version = pkg.version;
348+
res.statusCode = 200;
349+
res.setHeader('Content-Type', 'text/plain');
350+
res.setHeader('Content-Length', Buffer.byteLength(noobaa_package_version));
351+
res.end(noobaa_package_version);
352+
}
353+
354+
/**
355+
* internal_api_error returns an internal api error response
356+
* @param {EndpointRequest} req
357+
* @param {import('http').ServerResponse} res
358+
* @param {string} error_message
359+
*/
360+
function internal_api_error(req, res, error_message) {
361+
const buffer = Buffer.from(JSON.stringify({ error: 'Internal Server Error', message: error_message }));
362+
res.statusCode = 500;
363+
res.setHeader('Content-Type', 'application/json');
364+
res.setHeader('Content-Length', buffer.length);
365+
res.end(buffer);
366+
}
367+
368+
/**
369+
* endpoint_fork_id_handler returns the worker id of the current fork
370+
* @param {EndpointRequest} req
371+
* @param {import('http').ServerResponse} res
372+
*/
328373
function endpoint_fork_id_handler(req, res) {
329374
let reply = {};
330375
if (cluster.isWorker) {
331-
reply = {
332-
worker_id: cluster.worker.id,
333-
};
376+
reply = { worker_id: cluster.worker.id };
334377
}
335378
P.delay(500);
336379
res.statusCode = 200;
380+
const buffer = Buffer.from(JSON.stringify(reply));
337381
res.setHeader('Content-Type', 'application/json');
338-
res.setHeader('Content-Length', Buffer.byteLength(JSON.stringify(reply)));
339-
res.end(JSON.stringify(reply));
382+
res.setHeader('Content-Length', buffer.length);
383+
res.end(buffer);
340384
}
341385

386+
/**
387+
* fork_count_handler returns the total number of forks
388+
* @param {EndpointRequest} req
389+
* @param {import('http').ServerResponse} res
390+
*/
342391
function fork_count_handler(req, res) {
343-
const reply = {
344-
fork_count: fork_count,
345-
};
392+
const reply = { fork_count: fork_count };
346393
res.statusCode = 200;
394+
const buffer = Buffer.from(JSON.stringify(reply));
347395
res.setHeader('Content-Type', 'application/json');
348-
res.setHeader('Content-Length', Buffer.byteLength(JSON.stringify(reply)));
349-
res.end(JSON.stringify(reply));
396+
res.setHeader('Content-Length', buffer.length);
397+
res.end(buffer);
350398
}
351399

352400
/**

src/manage_nsfs/manage_nsfs_help_utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ Usage:
437437
Flags:
438438
439439
--expected_version <string> The expected target version of the upgrade
440-
--expected_hosts <string> The expected hosts running NooBaa NC, a string of hosts separated by ,
440+
--expected_hosts <string> (optional) The expected hosts running NooBaa NC, a string of hosts separated by ,
441441
--skip_verification <boolean> (optional) skip upgrade verification
442442
WARNING: can cause corrupted config dir files created by hosts running old code.
443443
this should generally not be used and is intended exclusively for NooBaa team support.

src/manage_nsfs/upgrade.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async function start_config_dir_upgrade(user_input, config_fs) {
4949
new NoobaaEvent(NoobaaEvent.CONFIG_DIR_UPGRADE_STARTED).create_event(undefined, { expected_version, expected_hosts }, undefined);
5050

5151
if (!expected_version) throw new Error('expected_version flag is required');
52-
if (!expected_hosts) throw new Error('expected_hosts flag is required');
52+
if (!expected_hosts) dbg.warn('expected_hosts flag is empty, config dir upgrade will be performed without hosts version verification');
5353

5454
const nc_upgrade_manager = new NCUpgradeManager(config_fs, { custom_upgrade_scripts_dir });
5555
const upgrade_res = await nc_upgrade_manager.upgrade_config_dir(expected_version, expected_hosts, { skip_verification });

src/test/unit_tests/jest_tests/test_cli_upgrade.test.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,12 +270,11 @@ describe('noobaa cli - upgrade', () => {
270270
expect(parsed_res.error.cause).toContain('expected_version flag is required');
271271
});
272272

273-
it('upgrade start - should fail on no expected_hosts', async () => {
273+
it('upgrade start - should succeed although missing expected hosts', async () => {
274274
await fs_utils.replace_file(config_fs.system_json_path, JSON.stringify(old_rpm_expected_system_json));
275275
const res = await exec_manage_cli(TYPES.UPGRADE, UPGRADE_ACTIONS.START, { config_root, expected_version: pkg.version }, true);
276-
const parsed_res = JSON.parse(res.stdout);
277-
expect(parsed_res.error.message).toBe(ManageCLIError.UpgradeFailed.message);
278-
expect(parsed_res.error.cause).toContain('expected_hosts flag is required');
276+
const parsed_res = JSON.parse(res);
277+
expect(parsed_res.response.code).toBe(ManageCLIResponse.UpgradeSuccessful.code);
279278
});
280279

281280
it('upgrade start - should fail on missing expected_hosts in system.json', async () => {

src/upgrade/nc_upgrade_manager.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class NCUpgradeManager {
9393
* 4.4. moves the current upgrade from in_progress_upgrade to the upgrade_history.successful_upgrades
9494
* 4.5. is 5.17.0 is a good default for from_version?
9595
* @param {string} expected_version
96-
* @param {[string]} hosts_list
96+
* @param {[string]} [hosts_list]
9797
* @param {{skip_verification?: boolean}} [options]
9898
* @returns {Promise<Object>}
9999
*/
@@ -159,7 +159,7 @@ class NCUpgradeManager {
159159
* therefore we can not treat the system.json as the source of truth of the hosts information
160160
* @param {Object} system_data
161161
* @param {String} expected_version
162-
* @param {[String]} expected_hosts
162+
* @param {[String]} [expected_hosts]
163163
* @returns {Promise<Void>}
164164
*/
165165
async _verify_config_dir_upgrade(system_data, expected_version, expected_hosts) {
@@ -175,23 +175,27 @@ class NCUpgradeManager {
175175
err_message = `config dir upgrade can not be started missing hosts_data hosts_data=${util.inspect(hosts_data)}`;
176176
}
177177

178-
const all_hostnames_exist_in_expected_hosts = hostnames.every(item => expected_hosts.includes(item));
179-
if (!all_hostnames_exist_in_expected_hosts) {
180-
dbg.warn(`_verify_config_dir_upgrade - system.json contains one or more hosts info that are not specified in expected_hosts: hosts_data=${util.inspect(hosts_data)} expected_hosts=${util.inspect(expected_hosts)}`);
181-
}
178+
if (expected_hosts) {
179+
const all_hostnames_exist_in_expected_hosts = hostnames.every(item => expected_hosts.includes(item));
180+
if (!all_hostnames_exist_in_expected_hosts) {
181+
dbg.warn(`_verify_config_dir_upgrade - system.json contains one or more hosts info that are not specified in expected_hosts: hosts_data=${util.inspect(hosts_data)} expected_hosts=${util.inspect(expected_hosts)}`);
182+
}
182183

183-
const all_expected_hosts_exist_in_system_json = expected_hosts.every(item => hostnames.includes(item));
184-
if (!err_message && !all_expected_hosts_exist_in_system_json) {
185-
err_message = `config dir upgrade can not be started - expected_hosts contains one or more hosts that are not specified in system.json hosts_data=${util.inspect(hosts_data)} expected_hosts=${util.inspect(expected_hosts)}`;
186-
}
184+
const all_expected_hosts_exist_in_system_json = expected_hosts.every(item => hostnames.includes(item));
185+
if (!err_message && !all_expected_hosts_exist_in_system_json) {
186+
err_message = `config dir upgrade can not be started - expected_hosts contains one or more hosts that are not specified in system.json hosts_data=${util.inspect(hosts_data)} expected_hosts=${util.inspect(expected_hosts)}`;
187+
}
187188

188-
if (!err_message) {
189-
for (const cur_hostname of expected_hosts) {
190-
const host_data = hosts_data[cur_hostname];
191-
if (!host_data.current_version || version_compare(host_data.current_version, new_version) !== 0) {
192-
err_message = `config dir upgrade can not be started until all expected hosts have the expected version=${new_version}, host=${cur_hostname} host's current_version=${host_data.current_version}`;
189+
if (!err_message) {
190+
for (const cur_hostname of expected_hosts) {
191+
const host_data = hosts_data[cur_hostname];
192+
if (!host_data.current_version || version_compare(host_data.current_version, new_version) !== 0) {
193+
err_message = `config dir upgrade can not be started until all expected hosts have the expected version=${new_version}, host=${cur_hostname} host's current_version=${host_data.current_version}`;
194+
}
193195
}
194196
}
197+
} else {
198+
dbg.warn('expected_hosts is empty, config dir upgrade will be performed without hosts version verification');
195199
}
196200

197201
if (!err_message && system_data.config_directory?.in_progress_upgrade) {

0 commit comments

Comments
 (0)