mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 23:29:39 +00:00
Added support for operation meta data, code cleanup (#534)
* Added messages * Comment update * Interface update * Support for localized descriptions * Sort operations * Completed meta data * rasctl -s returns operation meta data * Manpage update * Type update * Comment update * Description updates * Comment update * Added convenience method * Added convenience method * Code cleanup * Comment update * Display permitted values * For completeness sake added permitted boolean values * Added support for default value * Removed redundant message field * Description update * Description upddate * Squashed commit of the following: commit 8171c6ea27982c736c30c0db69a7fdde07ee10ce Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:43:14 2021 +0100 The data type is implicit commit fb01dc9d82e8ff7456b05a0cb9d08069adacc64c Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:37:49 2021 +0100 Renaming commit 057dbf1aca7be3f7e76a5ff89a582a276b6d3089 Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:29:54 2021 +0100 Comment update commit 5f699aad2f835f72accdb445d1e59f094aeb108f Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:24:25 2021 +0100 Signature update commit cbcf8b09f9d1ba7b82f816269bcfe91d9f00eb6e Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:22:45 2021 +0100 Signature update commit a8148ef802ca809e5a305d2caa69856c9033d932 Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:16:46 2021 +0100 Comment update commit ce685a92d4827e131d80d10ecd56e2b3baf173f8 Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 12:15:46 2021 +0100 Use map instead of list commit 454c0438f3589904f5dbe5253963dd200ea416dd Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 10:47:36 2021 +0100 Updated size check commit b386dbba4b0262f4f6f02aecb2a1daeffd41f4a2 Author: Uwe Seimet <Uwe.Seimet@seimet.de> Date: Sat Dec 18 01:23:43 2021 +0100 Initial improvements * Default value update * Comment update * Comment update * Map operations by ordinal * Added safeguard against unknown operations * Added cast * Data type update * Sort map by operation name * Renaming * Code cleanup * Comment update * Renaming * Comment update * Description updates * Fixed typo * Added operation * Logging update * Interface comment update * Fixed typo * Aded operation parameters * Updated handling of mandatory parameters * Updated assertion handling * Added missing condition * Removed duplicate cod3 * Code cleanup * Logging update * Removed duplicate code * Code cleanup * Squashed commit of the following: commit4ae273ccbd
Author: akuker <34318535+akuker@users.noreply.github.com> Date: Sun Dec 19 22:30:22 2021 -0600 Loopback tester pcb (#545) commit46c5c1966f
Author: akuker <34318535+akuker@users.noreply.github.com> Date: Sun Dec 19 22:29:59 2021 -0600 RaSCSI Zero version 1.0 (#546) commitd09df31d67
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 20:25:23 2021 -0800 Remove redundant code from OLED script (#547) commitd8828da690
Author: akuker <34318535+akuker@users.noreply.github.com> Date: Sun Dec 19 21:02:50 2021 -0600 Added list of sponsors commitbcd7e8396d
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 15:51:45 2021 -0800 Second attempt at properly creating the manpage dir (#542) commitc887edfc8c
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 15:50:03 2021 -0800 Remove special elevated privileges for the Web Interface (#536) * Use the pi_shutdown method to restart the rascsi service * Use the pi_shutdown method to restart the rascsi service * Remove modifications to sudoers no longer needed * Introduce sleeps attempting to connect to socket; reduce overall number of retries * Remove systemd helped methods and the functionality that depends on it * Attempts to speed up splash code * Remove unneccessary verbosity * Attempt to optimize service definition commit801aebfb96
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 15:47:22 2021 -0800 More readable message when downloading a file (#531) commit29cf58288f
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 15:47:03 2021 -0800 Add a warning notice when ejecting removable media (#526) commit7efa895239
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 15:46:22 2021 -0800 Unzip zipfiles before storing to iso (#525) * Unzip zipfiles before storing to iso * Add helptext * Skip unzip for MacZip format * Should not be an fstring commit39bc485671
Author: Daniel Markstedt <markstedt@gmail.com> Date: Sun Dec 19 15:28:22 2021 -0800 Add pip3 to global dependencies; remove duplicates from monitor_rascs… (#523) * Add pip3 to global dependencies; remove duplicates from monitor_rascsi dependencies * Cleanup * Shutdown functionality is only available if started with root permissions * Only restrict shutdown parameters, not everything if not root * Updated operation count check
This commit is contained in:
parent
693ade2967
commit
94786aec54
@ -6,6 +6,7 @@ rasctl \- Sends management commands to the rascsi process
|
||||
\fB\-e\fR |
|
||||
\fB\-l\fR |
|
||||
\fB\-m\fR |
|
||||
\fB\-o\fR |
|
||||
\fB\-s\fR |
|
||||
\fB\-v\fR |
|
||||
\fB\-D\fR |
|
||||
@ -82,6 +83,9 @@ List all of the devices that are currently being emulated by RaSCSI, as well as
|
||||
.BR \-m\fI
|
||||
List all file extensions recognized by RaSCSI and the device types they map to.
|
||||
.TP
|
||||
.BR \-o\fI
|
||||
Display operation meta data information.
|
||||
.TP
|
||||
.BR \-R\fI " "\fICURRENT_NAME:NEW_NAME
|
||||
Rename an image file in the default image folder.
|
||||
.TP
|
||||
|
@ -6,8 +6,8 @@ NAME
|
||||
rasctl - Sends management commands to the rascsi process
|
||||
|
||||
SYNOPSIS
|
||||
rasctl -e | -l | -m | -s | -v | -D | -I | -L | -O | -P | -T | -V | -X |
|
||||
[-C FILENAME:FILESIZE] [-E FILENAME] [-F IMAGE_FOLDER] [-R CUR‐
|
||||
rasctl -e | -l | -m | -o | -s | -v | -D | -I | -L | -O | -P | -T | -V |
|
||||
-X | [-C FILENAME:FILESIZE] [-E FILENAME] [-F IMAGE_FOLDER] [-R CUR‐
|
||||
RENT_NAME:NEW_NAME] [-c CMD] [-f FILE|PARAM] [-g LOG_LEVEL] [-h HOST]
|
||||
[-i ID [-n NAME] [-p PORT] [-r RESERVED_IDS] [-t TYPE] [-u UNIT] [-x
|
||||
CURRENT_NAME:NEW_NAME]
|
||||
@ -62,6 +62,8 @@ OPTIONS
|
||||
-m List all file extensions recognized by RaSCSI and the device
|
||||
types they map to.
|
||||
|
||||
-o Display operation meta data information.
|
||||
|
||||
-R CURRENT_NAME:NEW_NAME
|
||||
Rename an image file in the default image folder.
|
||||
|
||||
|
@ -484,6 +484,8 @@ bool SetLogLevel(const string& log_level)
|
||||
|
||||
current_log_level = log_level;
|
||||
|
||||
LOGINFO("Set log level to '%s'", current_log_level.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1431,10 +1433,19 @@ static void *MonThread(void *param)
|
||||
}
|
||||
}
|
||||
|
||||
switch(command.operation()) {
|
||||
case LOG_LEVEL: {
|
||||
if (!PbOperation_IsValid(command.operation())) {
|
||||
LOGTRACE("Received unknown command %d", command.operation());
|
||||
|
||||
ReturnStatus(fd, false, "Unknown command", UNKNOWN_OPERATION);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
|
||||
switch(command.operation()) {
|
||||
case LOG_LEVEL: {
|
||||
string log_level = GetParam(command, "level");
|
||||
bool status = SetLogLevel(log_level);
|
||||
if (!status) {
|
||||
@ -1447,8 +1458,6 @@ static void *MonThread(void *param)
|
||||
}
|
||||
|
||||
case DEFAULT_FOLDER: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
string folder = GetParam(command, "folder");
|
||||
if (folder.empty()) {
|
||||
ReturnStatus(fd, false, "Can't set default image folder: Missing folder name");
|
||||
@ -1465,28 +1474,18 @@ static void *MonThread(void *param)
|
||||
}
|
||||
|
||||
case DEVICES_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
rascsi_response.GetDevicesInfo(result, command, devices, UnitNum);
|
||||
SerializeMessage(fd, result);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_TYPES_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_device_types_info(rascsi_response.GetDeviceTypesInfo(result, command));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_server_info(rascsi_response.GetServerInfo(
|
||||
result, devices, reserved_ids, current_log_level, GetParam(command, "filename_pattern"),
|
||||
scan_depth));
|
||||
@ -1495,27 +1494,18 @@ static void *MonThread(void *param)
|
||||
}
|
||||
|
||||
case VERSION_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_version_info(rascsi_response.GetVersionInfo(result));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOG_LEVEL_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_log_level_info(rascsi_response.GetLogLevelInfo(result, current_log_level));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case DEFAULT_IMAGE_FILES_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_image_files_info(rascsi_response.GetAvailableImages(result,
|
||||
GetParam(command, "filename_pattern"), scan_depth));
|
||||
SerializeMessage(fd, result);
|
||||
@ -1523,14 +1513,11 @@ static void *MonThread(void *param)
|
||||
}
|
||||
|
||||
case IMAGE_FILE_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
string filename = GetParam(command, "file");
|
||||
if (filename.empty()) {
|
||||
ReturnStatus(fd, false, "Can't get image file info: Missing filename");
|
||||
}
|
||||
else {
|
||||
PbResult result;
|
||||
PbImageFile* image_file = new PbImageFile();
|
||||
bool status = rascsi_response.GetImageFile(image_file, filename);
|
||||
if (status) {
|
||||
@ -1546,35 +1533,30 @@ static void *MonThread(void *param)
|
||||
}
|
||||
|
||||
case NETWORK_INTERFACES_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_network_interfaces_info(rascsi_response.GetNetworkInterfacesInfo(result));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case MAPPING_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
PbResult result;
|
||||
result.set_allocated_mapping_info(rascsi_response.GetMappingInfo(result));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case RESERVED_IDS_INFO: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
case OPERATION_INFO: {
|
||||
result.set_allocated_operation_info(rascsi_response.GetOperationInfo(result));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
PbResult result;
|
||||
case RESERVED_IDS_INFO: {
|
||||
result.set_allocated_reserved_ids_info(rascsi_response.GetReservedIds(result, reserved_ids));
|
||||
SerializeMessage(fd, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case SHUT_DOWN: {
|
||||
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
|
||||
|
||||
ShutDown(fd, GetParam(command, "mode"));
|
||||
break;
|
||||
}
|
||||
@ -1613,6 +1595,10 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
// Get temporary operation info, in order to trigger an assertion on startup if the operation list is incomplete
|
||||
PbResult pb_operation_info_result;
|
||||
rascsi_response.GetOperationInfo(pb_operation_info_result);
|
||||
|
||||
int actid;
|
||||
BUS::phase_t phase;
|
||||
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
||||
|
@ -71,7 +71,7 @@ enum PbOperation {
|
||||
// "filename_pattern": Optional filter, only filenames containing the case-insensitive pattern are returned
|
||||
SERVER_INFO = 10;
|
||||
|
||||
// Get rascsi version information (PbVersionInfo)
|
||||
// Get rascsi server version (PbVersionInfo)
|
||||
VERSION_INFO = 11;
|
||||
|
||||
// Get information on attached devices (PbDevicesInfo)
|
||||
@ -109,7 +109,7 @@ enum PbOperation {
|
||||
// "folder": The path of the default folder, relative to the user's home folder if relative.
|
||||
DEFAULT_FOLDER = 20;
|
||||
|
||||
// Set a new log level.
|
||||
// Set the log level.
|
||||
// Parameters:
|
||||
// "level": The new log level
|
||||
LOG_LEVEL = 21;
|
||||
@ -119,7 +119,7 @@ enum PbOperation {
|
||||
// "ids": A comma-separated list of IDs to reserve, or an empty string in order not to reserve any ID.
|
||||
RESERVE_IDS = 22;
|
||||
|
||||
// Shut down the rascsi process
|
||||
// Shut down the rascsi process or shut down/reboot the Raspberry Pi
|
||||
// Parameters:
|
||||
// "mode": The shutdown mode, one of "rascsi", "system", "reboot"
|
||||
SHUT_DOWN = 23;
|
||||
@ -161,18 +161,53 @@ enum PbOperation {
|
||||
// "file": The filename, relative to the default image folder. It must not contain a slash.
|
||||
UNPROTECT_IMAGE = 29;
|
||||
|
||||
// Check whether an authentication token is valid. A client can use this in operation in order to
|
||||
// Check whether an authentication token is valid. A client can use this operation in order to
|
||||
// find out whether rascsi authentication is enable or to use rascsi authentication for securing
|
||||
// client-internal operations.
|
||||
CHECK_AUTHENTICATION = 30;
|
||||
|
||||
// Get operation meta data (PbOperationInfo)
|
||||
OPERATION_INFO = 31;
|
||||
}
|
||||
|
||||
// rascsi special purpose error codes for cases where a textual error message is not sufficient
|
||||
// The operation parameter meta data. The parameter data type is provided by the protobuf API.
|
||||
message PbOperationParameter {
|
||||
string name = 1;
|
||||
// Optional short localized description, key is the lower case locale (e.g. en, de).
|
||||
// Falling back to "en" is recommended if a description for a particular language is missing.
|
||||
map<string, string> description = 2;
|
||||
// There is no specific set of permitted values if empty
|
||||
repeated string permitted_values = 3;
|
||||
// Optional default value
|
||||
string default_value = 4;
|
||||
// True if this parameter is mandatory
|
||||
bool is_mandatory = 5;
|
||||
}
|
||||
|
||||
// The list of parameters supported by an operation
|
||||
message PbOperationMetaData {
|
||||
// The operation name at the time the server-side protobuf code was generated.
|
||||
string server_side_name = 1;
|
||||
// Optional short localized description, key is the lower case locale (e.g. en, de).
|
||||
// Falling back to "en" is recommended if a description for a particular language is missing.
|
||||
map<string, string> description = 2;
|
||||
repeated PbOperationParameter parameters = 3;
|
||||
}
|
||||
|
||||
// Mapping of operations to their ordinals
|
||||
message PbOperationInfo {
|
||||
map<int32, PbOperationMetaData> operations = 1;
|
||||
}
|
||||
|
||||
// rascsi special purpose error codes for cases where a textual error message may not be not sufficient.
|
||||
// The client may react on this code, e.g. by prompting the user for an authentication token.
|
||||
enum PbErrorCode {
|
||||
// No error code available
|
||||
NO_ERROR_CODE = 0;
|
||||
// The client sent an operation code not supported by this server
|
||||
UNKNOWN_OPERATION = 1;
|
||||
// Authentication/Authorization error
|
||||
UNAUTHORIZED = 1;
|
||||
UNAUTHORIZED = 2;
|
||||
}
|
||||
|
||||
// The supported file extensions mapped to their respective device types
|
||||
@ -325,7 +360,7 @@ message PbResult {
|
||||
// An optional error or information message, depending on the status. A string without trailing CR/LF.
|
||||
string msg = 2;
|
||||
// An optional error code. Only to be used in cases where textual information is not sufficient.
|
||||
PbErrorCode error_code = 13;
|
||||
PbErrorCode error_code = 14;
|
||||
// Optional additional result data
|
||||
oneof result {
|
||||
// The result of a SERVER_INFO command
|
||||
@ -348,6 +383,8 @@ message PbResult {
|
||||
PbMappingInfo mapping_info = 11;
|
||||
// The result of a RESERVED_IDS_INFO command
|
||||
PbReservedIdsInfo reserved_ids_info = 12;
|
||||
// The result of an OPERATION_INFO command
|
||||
PbOperationInfo operation_info = 13;
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,4 +406,6 @@ message PbServerInfo {
|
||||
PbReservedIdsInfo reserved_ids_info = 7;
|
||||
// The attached devices
|
||||
PbDevicesInfo devices_info = 8;
|
||||
// The operation meta data
|
||||
PbOperationInfo operation_info = 9;
|
||||
}
|
||||
|
@ -295,6 +295,7 @@ PbServerInfo *RascsiResponse::GetServerInfo(PbResult& result, const vector<Devic
|
||||
server_info->set_allocated_mapping_info(GetMappingInfo(result));
|
||||
GetDevices(*server_info, devices);
|
||||
server_info->set_allocated_reserved_ids_info(GetReservedIds(result, reserved_ids));
|
||||
server_info->set_allocated_operation_info(GetOperationInfo(result));
|
||||
|
||||
result.set_status(true);
|
||||
|
||||
@ -354,3 +355,161 @@ PbMappingInfo *RascsiResponse::GetMappingInfo(PbResult& result)
|
||||
|
||||
return mapping_info;
|
||||
}
|
||||
|
||||
PbOperationInfo *RascsiResponse::GetOperationInfo(PbResult& result)
|
||||
{
|
||||
PbOperationInfo *operation_info = new PbOperationInfo();
|
||||
|
||||
PbOperationMetaData *meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "name", "Image file name in case of a mass storage device");
|
||||
AddOperationParameter(meta_data, "interfaces", "Comma-separated prioritized network interface list");
|
||||
CreateOperation(operation_info, meta_data, ATTACH, "Attach device, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, DETACH, "Detach device, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, DETACH_ALL, "Detach all devices");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, START, "Start device, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, STOP, "Stop device, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "file", "Image file name", "", true);
|
||||
CreateOperation(operation_info, meta_data, INSERT, "Insert medium, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, EJECT, "Eject medium, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, PROTECT, "Protect medium, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, UNPROTECT, "Unprotect medium, device-specific parameters are required");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "filename_pattern", "Pattern for filtering image file names");
|
||||
CreateOperation(operation_info, meta_data, SERVER_INFO, "Get rascsi server information");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, VERSION_INFO, "Get rascsi server version");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, DEVICES_INFO, "Get information on attached devices");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, DEVICE_TYPES_INFO, "Get device properties by device type");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "filename_pattern", "Pattern for filtering image file names");
|
||||
CreateOperation(operation_info, meta_data, DEFAULT_IMAGE_FILES_INFO, "Get information on available image files");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "file", "Image file name", "", true);
|
||||
CreateOperation(operation_info, meta_data, IMAGE_FILE_INFO, "Get information on image file");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, LOG_LEVEL_INFO, "Get log level information");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, NETWORK_INTERFACES_INFO, "Get the available network interfaces");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, MAPPING_INFO, "Get mapping of extensions to device types");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, RESERVED_IDS_INFO, "Get list of reserved device IDs");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "folder", "Default image file folder name", "", true);
|
||||
CreateOperation(operation_info, meta_data, DEFAULT_FOLDER, "Set default image file folder");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "level", "New log level", "", true);
|
||||
CreateOperation(operation_info, meta_data, LOG_LEVEL, "Set log level");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "ids", "Comma-separated device ID list", "", true);
|
||||
CreateOperation(operation_info, meta_data, RESERVE_IDS, "Reserve device IDs");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
PbOperationParameter *parameter = AddOperationParameter(meta_data, "mode", "Shutdown mode", "", true);
|
||||
parameter->add_permitted_values("rascsi");
|
||||
// System shutdown/reboot requires root permissions
|
||||
if (!getuid()) {
|
||||
parameter->add_permitted_values("system");
|
||||
parameter->add_permitted_values("reboot");
|
||||
}
|
||||
CreateOperation(operation_info, meta_data, SHUT_DOWN, "Shut down or reboot");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "file", "Image file name", "", true);
|
||||
AddOperationParameter(meta_data, "size", "Image file size in bytes", "", true);
|
||||
parameter = AddOperationParameter(meta_data, "read_only", "Read-only flag", "false");
|
||||
parameter->add_permitted_values("true");
|
||||
parameter->add_permitted_values("false");
|
||||
CreateOperation(operation_info, meta_data, CREATE_IMAGE, "Create an image file");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "file", "Image file name", "", true);
|
||||
CreateOperation(operation_info, meta_data, DELETE_IMAGE, "Delete image file");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "from", "Source image file name", "", true);
|
||||
AddOperationParameter(meta_data, "to", "Destination image file name", "", true);
|
||||
CreateOperation(operation_info, meta_data, RENAME_IMAGE, "Rename image file");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "from", "Source image file name image file name", "", true);
|
||||
AddOperationParameter(meta_data, "to", "Destination image file name", "", true);
|
||||
parameter = AddOperationParameter(meta_data, "read_only", "Read-only flag", "false");
|
||||
parameter->add_permitted_values("true");
|
||||
parameter->add_permitted_values("false");
|
||||
CreateOperation(operation_info, meta_data, COPY_IMAGE, "Copy image file");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "file", "Image file name", "", true);
|
||||
CreateOperation(operation_info, meta_data, PROTECT_IMAGE, "Write-protect image file");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "file", "Image file name", "", true);
|
||||
CreateOperation(operation_info, meta_data, UNPROTECT_IMAGE, "Make image file writable");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
AddOperationParameter(meta_data, "token", "Authentication token to be checked", "", true);
|
||||
CreateOperation(operation_info, meta_data, CHECK_AUTHENTICATION, "Check whether an authentication token is valid");
|
||||
|
||||
meta_data = new PbOperationMetaData();
|
||||
CreateOperation(operation_info, meta_data, OPERATION_INFO, "Get operation meta data");
|
||||
|
||||
// Ensure that the complete set of operations is covered
|
||||
assert(operation_info->operations_size() == PbOperation_ARRAYSIZE - 1);
|
||||
|
||||
result.set_status(true);
|
||||
|
||||
return operation_info;
|
||||
}
|
||||
|
||||
void RascsiResponse::CreateOperation(PbOperationInfo *operation_info, PbOperationMetaData *meta_data,
|
||||
const PbOperation& operation, const string& description)
|
||||
{
|
||||
meta_data->set_server_side_name(PbOperation_Name(operation));
|
||||
(*meta_data->mutable_description())["en"] = description;
|
||||
int ordinal = PbOperation_descriptor()->FindValueByName(PbOperation_Name(operation))->index();
|
||||
(*operation_info->mutable_operations())[ordinal] = *meta_data;
|
||||
}
|
||||
|
||||
PbOperationParameter *RascsiResponse::AddOperationParameter(PbOperationMetaData *meta_data, const string& name,
|
||||
const string& description, const string& default_value, bool is_mandatory)
|
||||
{
|
||||
PbOperationParameter *parameter = meta_data->add_parameters();
|
||||
parameter->set_name(name);
|
||||
(*parameter->mutable_description())["en"] = description;
|
||||
parameter->set_default_value(default_value);
|
||||
parameter->set_is_mandatory(is_mandatory);
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
PbNetworkInterfacesInfo *GetNetworkInterfacesInfo(PbResult&);
|
||||
PbMappingInfo *GetMappingInfo(PbResult&);
|
||||
PbLogLevelInfo *GetLogLevelInfo(PbResult&, const string&);
|
||||
PbOperationInfo *GetOperationInfo(PbResult&);
|
||||
|
||||
private:
|
||||
|
||||
@ -53,4 +54,7 @@ private:
|
||||
void GetDeviceTypeProperties(PbDeviceTypesInfo&, PbDeviceType);
|
||||
void GetAvailableImages(PbImageFilesInfo&, const string&, const string&, const string&, int);
|
||||
void GetAvailableImages(PbResult& result, PbServerInfo&, const string&, int);
|
||||
void CreateOperation(PbOperationInfo *, PbOperationMetaData *, const PbOperation&, const string&);
|
||||
PbOperationParameter *AddOperationParameter(PbOperationMetaData *, const string&, const string&,
|
||||
const string& = "", bool = false);
|
||||
};
|
||||
|
@ -101,8 +101,8 @@ int main(int argc, char* argv[])
|
||||
cerr << "version " << rascsi_get_version_string() << " (" << __DATE__ << ", " << __TIME__ << ")" << endl;
|
||||
cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-C FILE] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] ";
|
||||
cerr << "[-F IMAGE_FOLDER] [-L LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] ";
|
||||
cerr << "[-C FILENAME:FILESIZE] [-d FILENAME] [-w FILENAME] [-P TOKEN] [-R CURRENT_NAME:NEW_NAME] [-x CURRENT_NAME:NEW_NAME] ";
|
||||
cerr << "[-e] [-E FILENAME] [-D] [-I] [-l] [-L] [-m] [-O] [-s] [-v] [-V] [-y] [-X]" << endl;
|
||||
cerr << "[-C FILENAME:FILESIZE] [-d FILENAME] [-w FILENAME] [-R CURRENT_NAME:NEW_NAME] [-x CURRENT_NAME:NEW_NAME] ";
|
||||
cerr << "[-e] [-E FILENAME] [-D] [-I] [-l] [-L] [-m] [o] [-O] [-s] [-v] [-V] [-y] [-X]" << endl;
|
||||
cerr << " where ID := {0-7}" << endl;
|
||||
cerr << " UNIT := {0-31}, default is 0" << endl;
|
||||
cerr << " CMD := {attach|detach|insert|eject|protect|unprotect|show}" << endl;
|
||||
@ -139,7 +139,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
opterr = 1;
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "elmsvDINOTVXa:b:c:d:f:h:i:n:p:r:t:u:x:C:E:F:L:R:P::")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "elmosvDINOTVXa:b:c:d:f:h:i:n:p:r:t:u:x:C:E:F:L:R:P::")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i': {
|
||||
int id;
|
||||
@ -239,6 +239,10 @@ int main(int argc, char* argv[])
|
||||
command.set_operation(LOG_LEVEL_INFO);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
command.set_operation(OPERATION_INFO);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
device->set_type(ParseType(optarg));
|
||||
if (device->type() == UNDEFINED) {
|
||||
@ -416,6 +420,10 @@ int main(int argc, char* argv[])
|
||||
rasctl_commands.CommandMappingInfo();
|
||||
break;
|
||||
|
||||
case OPERATION_INFO:
|
||||
rasctl_commands.CommandOperationInfo();
|
||||
break;
|
||||
|
||||
default:
|
||||
rasctl_commands.SendCommand();
|
||||
break;
|
||||
|
@ -222,6 +222,7 @@ void RasctlCommands::CommandServerInfo()
|
||||
rasctl_display.DisplayNetworkInterfaces(server_info.network_interfaces_info());
|
||||
rasctl_display.DisplayDeviceTypesInfo(server_info.device_types_info());
|
||||
rasctl_display.DisplayReservedIdsInfo(server_info.reserved_ids_info());
|
||||
rasctl_display.DisplayOperationInfo(server_info.operation_info());
|
||||
|
||||
if (server_info.devices_info().devices_size()) {
|
||||
list<PbDevice> sorted_devices = { server_info.devices_info().devices().begin(), server_info.devices_info().devices().end() };
|
||||
@ -278,3 +279,10 @@ void RasctlCommands::CommandMappingInfo()
|
||||
|
||||
rasctl_display.DisplayMappingInfo(result.mapping_info());
|
||||
}
|
||||
|
||||
void RasctlCommands::CommandOperationInfo()
|
||||
{
|
||||
SendCommand();
|
||||
|
||||
rasctl_display.DisplayOperationInfo(result.operation_info());
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
void CommandLogLevelInfo();
|
||||
void CommandReservedIdsInfo();
|
||||
void CommandMappingInfo();
|
||||
void CommandOperationInfo();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -273,3 +273,62 @@ void RasctlDisplay::DisplayMappingInfo(const PbMappingInfo& mapping_info)
|
||||
cout << " " << mapping.first << "->" << PbDeviceType_Name(mapping.second) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void RasctlDisplay::DisplayOperationInfo(const PbOperationInfo& operation_info)
|
||||
{
|
||||
const map<int, PbOperationMetaData> operations = { operation_info.operations().begin(), operation_info.operations().end() };
|
||||
|
||||
// Copies result into a map sorted by operation name
|
||||
const PbOperationMetaData *unknown_operation = new PbOperationMetaData();
|
||||
map<string, PbOperationMetaData> sorted_operations;
|
||||
for (const auto& operation : operations) {
|
||||
if (PbOperation_IsValid(static_cast<PbOperation>(operation.first))) {
|
||||
sorted_operations[PbOperation_Name(static_cast<PbOperation>(operation.first))] = operation.second;
|
||||
}
|
||||
else {
|
||||
// If the server-side operation is unknown for the client use the server-provided operation name
|
||||
// No further operation information is available in this case
|
||||
sorted_operations[operation.second.server_side_name()] = *unknown_operation;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "Remote operations supported by rascsi and their parameters:" << endl;
|
||||
for (const auto& operation : sorted_operations) {
|
||||
if (!operation.second.server_side_name().empty()) {
|
||||
cout << " " << operation.first;
|
||||
if (!operation.second.description().empty()) {
|
||||
cout << " (" << operation.second.description().at("en") << ")";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
for (const auto& parameter : operation.second.parameters()) {
|
||||
cout << " " << parameter.name() << ": "
|
||||
<< (parameter.is_mandatory() ? "mandatory" : "optional");
|
||||
if (!parameter.description().empty()) {
|
||||
cout << " (" << parameter.description().at("en") << ")";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
if (parameter.permitted_values_size()) {
|
||||
cout << " Permitted values: ";
|
||||
bool isFirst = true;
|
||||
for (const auto& permitted_value : parameter.permitted_values()) {
|
||||
if (!isFirst) {
|
||||
cout << ", ";
|
||||
}
|
||||
isFirst = false;
|
||||
cout << permitted_value;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if (!parameter.default_value().empty()) {
|
||||
cout << " Default value: " << parameter.default_value() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << " " << operation.first << " (Unknown server-side operation)" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,4 +30,5 @@ public:
|
||||
void DisplayImageFiles(const PbImageFilesInfo&);
|
||||
void DisplayNetworkInterfaces(const PbNetworkInterfacesInfo&);
|
||||
void DisplayMappingInfo(const PbMappingInfo&);
|
||||
void DisplayOperationInfo(const PbOperationInfo&);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user