Skip to content

Commit 16133d6

Browse files
authored
Merge pull request #8839 from romayalon/romy-lifecycle-cli
NC | CLI | Lifecycle worker
2 parents c62b217 + b418f8e commit 16133d6

File tree

9 files changed

+386
-113
lines changed

9 files changed

+386
-113
lines changed

src/cmd/manage_nsfs.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
/* Copyright (C) 2020 NooBaa */
22
'use strict';
33

4+
// DO NOT PUT NEW REQUIREMENTS BEFORE SETTING process.env.NC_NSFS_NO_DB_ENV = 'true'
5+
// NC nsfs deployments specifying process.env.LOCAL_MD_SERVER=true deployed together with a db
6+
// when a system_store object is initialized VaccumAnalyzer is being called once a day.
7+
// when NC nsfs deployed without db we would like to avoid running VaccumAnalyzer in any flow there is
8+
// because running it will cause a panic.
9+
if (process.env.LOCAL_MD_SERVER !== 'true') {
10+
process.env.NC_NSFS_NO_DB_ENV = 'true';
11+
}
12+
413
const dbg = require('../util/debug_module')(__filename);
14+
if (!dbg.get_process_name()) dbg.set_process_name('noobaa-cli');
15+
516
const _ = require('lodash');
617
const minimist = require('minimist');
718
const config = require('../../config');
@@ -16,6 +27,7 @@ const { account_id_cache } = require('../sdk/accountspace_fs');
1627
const ManageCLIError = require('../manage_nsfs/manage_nsfs_cli_errors').ManageCLIError;
1728
const ManageCLIResponse = require('../manage_nsfs/manage_nsfs_cli_responses').ManageCLIResponse;
1829
const manage_nsfs_glacier = require('../manage_nsfs/manage_nsfs_glacier');
30+
const noobaa_cli_lifecycle = require('../manage_nsfs/nc_lifecycle');
1931
const manage_nsfs_logging = require('../manage_nsfs/manage_nsfs_logging');
2032
const noobaa_cli_diagnose = require('../manage_nsfs/diagnose');
2133
const noobaa_cli_upgrade = require('../manage_nsfs/upgrade');
@@ -79,6 +91,8 @@ async function main(argv = minimist(process.argv.slice(2))) {
7991
await notification_management();
8092
} else if (type === TYPES.CONNECTION) {
8193
await connection_management(action, user_input);
94+
} else if (type === TYPES.LIFECYCLE) {
95+
await lifecycle_management();
8296
} else {
8397
throw_cli_error(ManageCLIError.InvalidType);
8498
}
@@ -858,5 +872,17 @@ async function list_connections() {
858872
return conns;
859873
}
860874

875+
////////////////////
876+
///// LIFECYCLE ////
877+
////////////////////
878+
879+
/**
880+
* lifecycle_management runs the nc lifecycle management
881+
* @returns {Promise<void>}
882+
*/
883+
async function lifecycle_management() {
884+
await noobaa_cli_lifecycle.run_lifecycle(config_fs);
885+
}
886+
861887
exports.main = main;
862888
if (require.main === module) main();

src/cmd/nsfs.js

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,14 @@ if (process.env.LOCAL_MD_SERVER === 'true') {
3232
//const js_utils = require('../util/js_utils');
3333
const nb_native = require('../util/nb_native');
3434
//const schema_utils = require('../util/schema_utils');
35-
const RpcError = require('../rpc/rpc_error');
36-
const ObjectSDK = require('../sdk/object_sdk');
3735
const { cluster } = require('../util/fork_utils');
38-
const NamespaceFS = require('../sdk/namespace_fs');
3936
const BucketSpaceSimpleFS = require('../sdk/bucketspace_simple_fs');
4037
const BucketSpaceFS = require('../sdk/bucketspace_fs');
4138
const SensitiveString = require('../util/sensitive_string');
4239
const endpoint_stats_collector = require('../sdk/endpoint_stats_collector');
4340
//const { RPC_BUFFERS } = require('../rpc');
4441
const AccountSDK = require('../sdk/account_sdk');
42+
const NsfsObjectSDK = require('../sdk/nsfs_object_sdk');
4543
const AccountSpaceFS = require('../sdk/accountspace_fs');
4644
const NoobaaEvent = require('../manage_nsfs/manage_nsfs_events_utils').NoobaaEvent;
4745
const { set_debug_level } = require('../manage_nsfs/manage_nsfs_cli_utils');
@@ -121,98 +119,6 @@ function print_usage() {
121119

122120
let nsfs_config_root;
123121

124-
class NsfsObjectSDK extends ObjectSDK {
125-
constructor(fs_root, fs_config, account, versioning, config_root, nsfs_system) {
126-
// const rpc_client_hooks = new_rpc_client_hooks();
127-
// rpc_client_hooks.account.read_account_by_access_key = async ({ access_key }) => {
128-
// if (access_key) {
129-
// return { access_key };
130-
// }
131-
// };
132-
// rpc_client_hooks.bucket.read_bucket_sdk_info = async ({ name }) => {
133-
// if (name) {
134-
// return { name };
135-
// }
136-
// };
137-
let bucketspace;
138-
if (config_root) {
139-
bucketspace = new BucketSpaceFS({ config_root }, endpoint_stats_collector.instance());
140-
} else {
141-
bucketspace = new BucketSpaceSimpleFS({ fs_root });
142-
}
143-
super({
144-
rpc_client: null,
145-
internal_rpc_client: null,
146-
object_io: null,
147-
bucketspace,
148-
stats: endpoint_stats_collector.instance(),
149-
});
150-
this.nsfs_config_root = nsfs_config_root;
151-
this.nsfs_fs_root = fs_root;
152-
this.nsfs_fs_config = fs_config;
153-
this.nsfs_account = account;
154-
this.nsfs_versioning = versioning;
155-
this.nsfs_namespaces = {};
156-
this.nsfs_system = nsfs_system;
157-
if (!config_root) {
158-
this._get_bucket_namespace = bucket_name => this._simple_get_single_bucket_namespace(bucket_name);
159-
this.load_requesting_account = auth_req => this._simple_load_requesting_account(auth_req);
160-
this.read_bucket_sdk_policy_info = bucket_name => this._simple_read_bucket_sdk_policy_info(bucket_name);
161-
this.read_bucket_sdk_config_info = () => undefined;
162-
this.read_bucket_usage_info = () => undefined;
163-
this.read_bucket_sdk_website_info = () => undefined;
164-
this.read_bucket_sdk_namespace_info = () => undefined;
165-
this.read_bucket_sdk_caching_info = () => undefined;
166-
}
167-
}
168-
169-
async _simple_get_single_bucket_namespace(bucket_name) {
170-
const existing_ns = this.nsfs_namespaces[bucket_name];
171-
if (existing_ns) return existing_ns;
172-
const ns_fs = new NamespaceFS({
173-
fs_backend: this.nsfs_fs_config.backend,
174-
bucket_path: this.nsfs_fs_root + '/' + bucket_name,
175-
bucket_id: 'nsfs',
176-
namespace_resource_id: undefined,
177-
access_mode: undefined,
178-
versioning: this.nsfs_versioning,
179-
stats: endpoint_stats_collector.instance(),
180-
force_md5_etag: false,
181-
});
182-
this.nsfs_namespaces[bucket_name] = ns_fs;
183-
return ns_fs;
184-
}
185-
186-
async _simple_load_requesting_account(auth_req) {
187-
const access_key = this.nsfs_account.access_keys?.[0]?.access_key;
188-
if (access_key) {
189-
const token = this.get_auth_token();
190-
if (!token) {
191-
throw new RpcError('UNAUTHORIZED', `Anonymous access to bucket not allowed`);
192-
}
193-
if (token.access_key !== access_key.unwrap()) {
194-
throw new RpcError('INVALID_ACCESS_KEY_ID', `Account with access_key not found`);
195-
}
196-
}
197-
this.requesting_account = this.nsfs_account;
198-
}
199-
200-
async _simple_read_bucket_sdk_policy_info(bucket_name) {
201-
return {
202-
s3_policy: {
203-
Version: '2012-10-17',
204-
Statement: [{
205-
Effect: 'Allow',
206-
Action: ['*'],
207-
Resource: ['*'],
208-
Principal: [new SensitiveString('*')],
209-
}]
210-
},
211-
bucket_owner: new SensitiveString('nsfs'),
212-
owner_account: new SensitiveString('nsfs-id'), // temp
213-
};
214-
}
215-
}
216122

217123
// NsfsAccountSDK was based on NsfsObjectSDK
218124
// simple flow was not implemented

src/manage_nsfs/health.js

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ const native_fs_utils = require('../util/native_fs_utils');
1212
const { read_stream_join } = require('../util/buffer_utils');
1313
const { make_https_request } = require('../util/http_utils');
1414
const { TYPES } = require('./manage_nsfs_constants');
15-
const { get_boolean_or_string_value, throw_cli_error, write_stdout_response, get_bucket_owner_account_by_id } = require('./manage_nsfs_cli_utils');
15+
const { get_boolean_or_string_value, throw_cli_error, write_stdout_response,
16+
get_bucket_owner_account_by_id, get_service_status, NOOBAA_SERVICE_NAME } = require('./manage_nsfs_cli_utils');
1617
const { ManageCLIResponse } = require('./manage_nsfs_cli_responses');
1718
const ManageCLIError = require('./manage_nsfs_cli_errors').ManageCLIError;
1819
const notifications_util = require('../util/notifications_util');
1920

2021

2122
const HOSTNAME = 'localhost';
22-
const NOOBAA_SERVICE = 'noobaa';
2323

2424
const health_errors = {
2525
NOOBAA_SERVICE_FAILED: {
@@ -118,7 +118,7 @@ class NSFSHealth {
118118
async nc_nsfs_health() {
119119
let endpoint_state;
120120
let memory;
121-
const noobaa_service_state = await this.get_service_state(NOOBAA_SERVICE);
121+
const noobaa_service_state = await this.get_service_state(NOOBAA_SERVICE_NAME);
122122
const { service_status, pid } = noobaa_service_state;
123123
if (pid !== '0') {
124124
endpoint_state = await this.get_endpoint_response();
@@ -139,7 +139,7 @@ class NSFSHealth {
139139
if (this.all_account_details) account_details = await this.get_account_status();
140140
if (this.all_connection_details) connection_details = await this.get_connection_status();
141141
const health = {
142-
service_name: NOOBAA_SERVICE,
142+
service_name: NOOBAA_SERVICE_NAME,
143143
status: service_health,
144144
memory: memory,
145145
error: error_code,
@@ -210,18 +210,8 @@ class NSFSHealth {
210210
}
211211

212212
async get_service_state(service_name) {
213-
let service_status;
214213
let pid;
215-
try {
216-
service_status = await os_util.exec('systemctl show -p ActiveState --value ' + service_name, {
217-
ignore_rc: false,
218-
return_stdout: true,
219-
trim_stdout: true,
220-
});
221-
} catch (err) {
222-
dbg.warn('could not receive service active state', service_name, err);
223-
service_status = 'missing service status info';
224-
}
214+
const service_status = await get_service_status(service_name);
225215
try {
226216
pid = await os_util.exec('systemctl show --property MainPID --value ' + service_name, {
227217
ignore_rc: false,
@@ -308,13 +298,13 @@ class NSFSHealth {
308298
async get_service_memory_usage() {
309299
let memory_status;
310300
try {
311-
memory_status = await os_util.exec('systemctl status ' + NOOBAA_SERVICE + ' | grep Memory ', {
301+
memory_status = await os_util.exec('systemctl status ' + NOOBAA_SERVICE_NAME + ' | grep Memory ', {
312302
ignore_rc: false,
313303
return_stdout: true,
314304
trim_stdout: true,
315305
});
316306
} catch (err) {
317-
dbg.warn('could not receive service active state', NOOBAA_SERVICE, err);
307+
dbg.warn('could not receive service active state', NOOBAA_SERVICE_NAME, err);
318308
memory_status = 'Memory: missing memory info';
319309
}
320310
if (memory_status) {

src/manage_nsfs/manage_nsfs_cli_errors.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,22 @@ ManageCLIError.NoSuchConnection = Object.freeze({
518518
http_code: 404,
519519
});
520520

521+
//////////////////////////////
522+
// LIFECYCLE ERRORS //
523+
//////////////////////////////
524+
525+
ManageCLIError.SystemJsonIsMissing = Object.freeze({
526+
code: 'SystemJsonIsMissing',
527+
message: 'Lifecycle worker can not run when system.json is missing.',
528+
http_code: 400,
529+
});
530+
531+
ManageCLIError.NooBaaServiceIsNotActive = Object.freeze({
532+
code: 'NooBaaServiceIsNotActive',
533+
message: 'Lifecycle worker can not run when NooBaa service is not active.',
534+
http_code: 400,
535+
});
536+
521537
///////////////////////////////
522538
// ERRORS MAPPING //
523539
///////////////////////////////

src/manage_nsfs/manage_nsfs_cli_utils.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'use strict';
33

44
const dbg = require('../util/debug_module')(__filename);
5+
const os_util = require('../util/os_utils');
56
const nb_native = require('../util/nb_native');
67
const native_fs_utils = require('../util/native_fs_utils');
78
const ManageCLIError = require('../manage_nsfs/manage_nsfs_cli_errors').ManageCLIError;
@@ -12,6 +13,7 @@ const { BOOLEAN_STRING_VALUES } = require('../manage_nsfs/manage_nsfs_constants'
1213
const NoobaaEvent = require('../manage_nsfs/manage_nsfs_events_utils').NoobaaEvent;
1314
const { account_id_cache } = require('../sdk/accountspace_fs');
1415

16+
const NOOBAA_SERVICE_NAME = 'noobaa';
1517

1618
function throw_cli_error(error, detail, event_arg) {
1719
const error_event = NSFS_CLI_ERROR_EVENT_MAP[error.code];
@@ -175,6 +177,27 @@ function is_access_key_update(data) {
175177
return new_access_key && cur_access_key && new_access_key !== cur_access_key;
176178
}
177179

180+
/**
181+
* get_service_status returns the active state of a service
182+
* TODO: probablt better to return boolean but requires refactoring in Health script
183+
* @param {String} service_name
184+
* @returns {Promise<String>}
185+
*/
186+
async function get_service_status(service_name) {
187+
let service_status;
188+
try {
189+
service_status = await os_util.exec('systemctl show -p ActiveState --value ' + service_name, {
190+
ignore_rc: false,
191+
return_stdout: true,
192+
trim_stdout: true,
193+
});
194+
} catch (err) {
195+
dbg.warn('could not receive service active state', service_name, err);
196+
service_status = 'missing service status info';
197+
}
198+
return service_status;
199+
}
200+
178201
// EXPORTS
179202
exports.throw_cli_error = throw_cli_error;
180203
exports.write_stdout_response = write_stdout_response;
@@ -187,3 +210,5 @@ exports.has_access_keys = has_access_keys;
187210
exports.set_debug_level = set_debug_level;
188211
exports.is_name_update = is_name_update;
189212
exports.is_access_key_update = is_access_key_update;
213+
exports.get_service_status = get_service_status;
214+
exports.NOOBAA_SERVICE_NAME = NOOBAA_SERVICE_NAME;

src/manage_nsfs/manage_nsfs_constants.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const TYPES = Object.freeze({
1010
DIAGNOSE: 'diagnose',
1111
UPGRADE: 'upgrade',
1212
NOTIFICATION: 'notification',
13-
CONNECTION: 'connection'
13+
CONNECTION: 'connection',
14+
LIFECYCLE: 'lifecycle'
1415
});
1516

1617
const ACTIONS = Object.freeze({
@@ -95,6 +96,7 @@ const VALID_OPTIONS_CONNECTION = {
9596
'status': new Set(['name', 'decrypt', ...CLI_MUTUAL_OPTIONS]),
9697
};
9798

99+
const VALID_OPTIONS_LIFECYCLE = new Set([...CLI_MUTUAL_OPTIONS]);
98100

99101
const VALID_OPTIONS_WHITELIST = new Set(['ips', ...CLI_MUTUAL_OPTIONS]);
100102

@@ -111,6 +113,7 @@ const VALID_OPTIONS = {
111113
upgrade_options: VALID_OPTIONS_UPGRADE,
112114
notification_options: VALID_OPTIONS_NOTIFICATION,
113115
connection_options: VALID_OPTIONS_CONNECTION,
116+
lifecycle_options: VALID_OPTIONS_LIFECYCLE
114117
};
115118

116119
const OPTION_TYPE = {

0 commit comments

Comments
 (0)