Squashed commit of the following:

commit 94786aec54
Author: Uwe Seimet <48174652+uweseimet@users.noreply.github.com>
Date:   Tue Dec 21 08:43:21 2021 +0100

    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:

    commit 4ae273ccbd
    Author: akuker <34318535+akuker@users.noreply.github.com>
    Date:   Sun Dec 19 22:30:22 2021 -0600

        Loopback tester pcb (#545)

    commit 46c5c1966f
    Author: akuker <34318535+akuker@users.noreply.github.com>
    Date:   Sun Dec 19 22:29:59 2021 -0600

        RaSCSI Zero version 1.0 (#546)

    commit d09df31d67
    Author: Daniel Markstedt <markstedt@gmail.com>
    Date:   Sun Dec 19 20:25:23 2021 -0800

        Remove redundant code from OLED script (#547)

    commit d8828da690
    Author: akuker <34318535+akuker@users.noreply.github.com>
    Date:   Sun Dec 19 21:02:50 2021 -0600

        Added list of sponsors

    commit bcd7e8396d
    Author: Daniel Markstedt <markstedt@gmail.com>
    Date:   Sun Dec 19 15:51:45 2021 -0800

        Second attempt at properly creating the manpage dir (#542)

    commit c887edfc8c
    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

    commit 801aebfb96
    Author: Daniel Markstedt <markstedt@gmail.com>
    Date:   Sun Dec 19 15:47:22 2021 -0800

        More readable message when downloading a file (#531)

    commit 29cf58288f
    Author: Daniel Markstedt <markstedt@gmail.com>
    Date:   Sun Dec 19 15:47:03 2021 -0800

        Add a warning notice when ejecting removable media (#526)

    commit 7efa895239
    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

    commit 39bc485671
    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

commit 693ade2967
Author: Daniel Markstedt <markstedt@gmail.com>
Date:   Mon Dec 20 12:04:23 2021 -0800

    Bump Macproxy version to 21.12.2 (#550)

commit 958fb95908
Author: akuker <34318535+akuker@users.noreply.github.com>
Date:   Mon Dec 20 12:50:14 2021 -0600

    Adjust bus settle delay to match SCSI standard (#544)

    * Move the GCC v10 compiler flags into makefile instead of easyinstall.sh

    * #504 - Update the bus settle time to match the SCSI standard

    Co-authored-by: RaSCSI User <user@rascsi.com>

commit 200bc7251f
Author: Daniel Markstedt <markstedt@gmail.com>
Date:   Mon Dec 20 06:20:22 2021 -0800

    More helpful error message when IP does not resolve for OLED screen (#541)

    * More helpful error message

    * Remove confusing fallback IP

    * Tweak message

commit 4ae273ccbd
Author: akuker <34318535+akuker@users.noreply.github.com>
Date:   Sun Dec 19 22:30:22 2021 -0600

    Loopback tester pcb (#545)

commit 46c5c1966f
Author: akuker <34318535+akuker@users.noreply.github.com>
Date:   Sun Dec 19 22:29:59 2021 -0600

    RaSCSI Zero version 1.0 (#546)

commit d09df31d67
Author: Daniel Markstedt <markstedt@gmail.com>
Date:   Sun Dec 19 20:25:23 2021 -0800

    Remove redundant code from OLED script (#547)

commit d8828da690
Author: akuker <34318535+akuker@users.noreply.github.com>
Date:   Sun Dec 19 21:02:50 2021 -0600

    Added list of sponsors

commit bcd7e8396d
Author: Daniel Markstedt <markstedt@gmail.com>
Date:   Sun Dec 19 15:51:45 2021 -0800

    Second attempt at properly creating the manpage dir (#542)

commit c887edfc8c
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

commit 801aebfb96
Author: Daniel Markstedt <markstedt@gmail.com>
Date:   Sun Dec 19 15:47:22 2021 -0800

    More readable message when downloading a file (#531)

commit 29cf58288f
Author: Daniel Markstedt <markstedt@gmail.com>
Date:   Sun Dec 19 15:47:03 2021 -0800

    Add a warning notice when ejecting removable media (#526)

commit 7efa895239
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

commit 39bc485671
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
This commit is contained in:
Uwe Seimet 2021-12-21 08:53:30 +01:00
parent f59eeb842e
commit ea3bb8363a
17 changed files with 339 additions and 63 deletions

View File

@ -83,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

View File

@ -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.

View File

@ -83,15 +83,8 @@ function installPackages() {
function compileRaScsi() {
cd "$BASE/src/raspberrypi" || exit 1
# Compiler flags needed for gcc v10 and up
if [[ `gcc --version | awk '/gcc/' | awk -F ' ' '{print $3}' | awk -F '.' '{print $1}'` -ge 10 ]]; then
echo -n "gcc 10 or later detected. Will compile with the following flags: "
COMPILER_FLAGS="-DFMT_HEADER_ONLY"
echo $COMPILER_FLAGS
fi
echo "Compiling with ${CORES:-1} simultaneous cores..."
( make clean && EXTRA_FLAGS="$COMPILER_FLAGS" make -j "${CORES:-1}" all CONNECT_TYPE="${CONNECT_TYPE:-FULLSPEC}" ) </dev/null
( make clean && make -j "${CORES:-1}" all CONNECT_TYPE="${CONNECT_TYPE:-FULLSPEC}" ) </dev/null
}
# install the RaSCSI binaries and modify the service configuration
@ -680,7 +673,7 @@ function installMacproxy {
( sudo apt-get update && sudo apt-get install python3 python3-venv --assume-yes ) </dev/null
MACPROXY_VER="21.12.1"
MACPROXY_VER="21.12.2"
MACPROXY_PATH="$HOME/macproxy-$MACPROXY_VER"
if [ -d "$MACPROXY_PATH" ]; then
echo "The $MACPROXY_PATH directory already exists. Delete it to proceed with the installation."

View File

@ -14,7 +14,7 @@ def get_ip_and_host():
sock.connect(('10.255.255.255', 1))
ip_addr = sock.getsockname()[0]
except Exception:
ip_addr = '127.0.0.1'
ip_addr = False
finally:
sock.close()
return ip_addr, host

View File

@ -161,7 +161,11 @@ def formatted_output():
else:
output.append("No image mounted!")
output.append(f"IP {IP_ADDR} - {HOSTNAME}")
if IP_ADDR:
output.append(f"IP {IP_ADDR} - {HOSTNAME}")
else:
output.append("RaSCSI has no IP address")
output.append("Check network connection")
return output

View File

@ -31,6 +31,16 @@ CXXFLAGS += -std=c++17 -Wno-psabi -iquote . -D_FILE_OFFSET_BITS=64 -MD -MP
CFLAGS += $(EXTRA_FLAGS)
CXXFLAGS += $(EXTRA_FLAGS)
# If we're using GCC version 10 or later, we need to add the FMT_HEADER_ONLY definition
GCCVERSION10 := $(shell expr `gcc -dumpversion` \>= 10)
ifeq "$(GCCVERSION10)" "1"
CFLAGS += -DFMT_HEADER_ONLY
CXXFLAGS += -DFMT_HEADER_ONLY
endif
## CONNECT_TYPE=FULLSPEC : Specify the type of RaSCSI board type
## that you are using. The typical options are
## STANDARD or FULLSPEC. The default is FULLSPEC

View File

@ -840,7 +840,7 @@ int GPIOBUS::CommandHandShake(BYTE *buf)
BOOL ret = WaitSignal(PIN_ACK, TRUE);
// Wait until the signal line stabilizes
SysTimer::SleepNsec(GPIO_DATA_SETTLING);
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
// Get data
*buf = GetDAT();
@ -874,7 +874,7 @@ int GPIOBUS::CommandHandShake(BYTE *buf)
ret = WaitSignal(PIN_ACK, TRUE);
// Wait until the signal line stabilizes
SysTimer::SleepNsec(GPIO_DATA_SETTLING);
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
// Get data
*buf = GetDAT();
@ -930,7 +930,7 @@ int GPIOBUS::ReceiveHandShake(BYTE *buf, int count)
ret = WaitSignal(PIN_ACK, TRUE);
// Wait until the signal line stabilizes
SysTimer::SleepNsec(GPIO_DATA_SETTLING);
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
// Get data
*buf = GetDAT();
@ -973,7 +973,7 @@ int GPIOBUS::ReceiveHandShake(BYTE *buf, int count)
}
// Wait until the signal line stabilizes
SysTimer::SleepNsec(GPIO_DATA_SETTLING);
SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS);
// Get data
*buf = GetDAT();

View File

@ -433,7 +433,6 @@
// Constant declarations (bus control timing)
//
//---------------------------------------------------------------------------
#define GPIO_DATA_SETTLING 100 // Data bus stabilization time (ns)
// SCSI Bus timings taken from:
// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html
#define SCSI_DELAY_ARBITRATION_DELAY_NS 2400

View File

@ -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)
}
}
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: {
LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str());
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, "folder_pattern"),
GetParam(command, "file_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, "folder_pattern"), GetParam(command, "file_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.

View File

@ -72,7 +72,7 @@ enum PbOperation {
// "file_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)
@ -111,7 +111,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;
@ -121,7 +121,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;
@ -162,19 +162,54 @@ enum PbOperation {
// Parameters:
// "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
@ -327,7 +362,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
@ -350,6 +385,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;
}
}
@ -371,4 +408,6 @@ message PbServerInfo {
PbReservedIdsInfo reserved_ids_info = 7;
// The attached devices
PbDevicesInfo devices_info = 8;
// The operation meta data
PbOperationInfo operation_info = 9;
}

View File

@ -304,6 +304,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);
@ -363,3 +364,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;
}

View File

@ -40,6 +40,7 @@ public:
PbNetworkInterfacesInfo *GetNetworkInterfacesInfo(PbResult&);
PbMappingInfo *GetMappingInfo(PbResult&);
PbLogLevelInfo *GetLogLevelInfo(PbResult&, const string&);
PbOperationInfo *GetOperationInfo(PbResult&);
private:
@ -54,4 +55,7 @@ private:
void GetDeviceTypeProperties(PbDeviceTypesInfo&, PbDeviceType);
void GetAvailableImages(PbImageFilesInfo&, const string&, const string&, const string&, const string&, int);
void GetAvailableImages(PbResult& result, PbServerInfo&, const string&, const string&, int);
void CreateOperation(PbOperationInfo *, PbOperationMetaData *, const PbOperation&, const string&);
PbOperationParameter *AddOperationParameter(PbOperationMetaData *, const string&, const string&,
const string& = "", bool = false);
};

View File

@ -118,8 +118,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;
@ -259,6 +259,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) {
@ -436,6 +440,10 @@ int main(int argc, char* argv[])
rasctl_commands.CommandMappingInfo();
break;
case OPERATION_INFO:
rasctl_commands.CommandOperationInfo();
break;
default:
rasctl_commands.SendCommand();
break;

View File

@ -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());
}

View File

@ -42,6 +42,7 @@ public:
void CommandLogLevelInfo();
void CommandReservedIdsInfo();
void CommandMappingInfo();
void CommandOperationInfo();
private:

View File

@ -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;
}
}
}

View File

@ -30,4 +30,5 @@ public:
void DisplayImageFiles(const PbImageFilesInfo&);
void DisplayNetworkInterfaces(const PbNetworkInterfacesInfo&);
void DisplayMappingInfo(const PbMappingInfo&);
void DisplayOperationInfo(const PbOperationInfo&);
};