Add support for writing protobuf text format

This commit is contained in:
Uwe Seimet 2023-11-17 09:08:20 +01:00
parent 3b9fa12ba7
commit 1b9e595705
4 changed files with 65 additions and 27 deletions

View File

@ -20,12 +20,14 @@
#include "scsictl/scsictl_commands.h"
#include "scsictl/scsictl_core.h"
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/text_format.h>
#include <unistd.h>
#include <clocale>
#include <iostream>
#include <fstream>
using namespace std;
using namespace google::protobuf;
using namespace google::protobuf::util;
using namespace piscsi_interface;
using namespace piscsi_util;
@ -37,7 +39,7 @@ void ScsiCtl::Banner(const vector<char *>& args) const
cout << piscsi_util::Banner("(Controller App)")
<< "\nUsage: " << args[0] << " -i ID[:LUN] [-c CMD] [-C FILE] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] "
<< "[-F IMAGE_FOLDER] [-L LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] "
<< "[-C FILENAME:FILESIZE] [-d FILENAME] [-B FILENAME] [-J FILENAME] [-R CURRENT_NAME:NEW_NAME] "
<< "[-C FILENAME:FILESIZE] [-d FILENAME] [-B FILENAME] [-J FILENAME] [-T FILENAME] [-R CURRENT_NAME:NEW_NAME] "
<< "[-x CURRENT_NAME:NEW_NAME] [-z LOCALE] "
<< "[-e] [-E FILENAME] [-D] [-I] [-l] [-m] [o] [-O] [-P] [-s] [-S] [-v] [-V] [-y] [-X]\n"
<< " where ID[:LUN] ID := {0-" << (ControllerManager::GetScsiIdMax() - 1) << "},"
@ -80,6 +82,7 @@ int ScsiCtl::run(const vector<char *>& args) const
string filename;
string filename_json;
string filename_binary;
string filename_text;
string token;
bool list = false;
@ -88,7 +91,7 @@ int ScsiCtl::run(const vector<char *>& args) const
opterr = 1;
int opt;
while ((opt = getopt(static_cast<int>(args.size()), args.data(),
"e::lmos::vDINOSTVXa:b:c:d:f:h:i:n:p:r:t:x:z:B:C:E:F:J:L:P::R:")) != -1) {
"e::lmos::vDINOSTVXa:b:c:d:f:h:i:n:p:r:t:x:z:B:C:E:F:J:L:P::R:Z:")) != -1) {
switch (opt) {
case 'i':
if (const string error = SetIdAndLun(*device, optarg); !error.empty()) {
@ -161,6 +164,14 @@ int ScsiCtl::run(const vector<char *>& args) const
}
break;
case 'B':
filename_binary = optarg;
if (filename_binary.empty()) {
cerr << "Error: Missing filename" << endl;
exit(EXIT_FAILURE);
}
break;
case 'J':
filename_json = optarg;
if (filename_json.empty()) {
@ -169,9 +180,9 @@ int ScsiCtl::run(const vector<char *>& args) const
}
break;
case 'B':
filename_binary = optarg;
if (filename_binary.empty()) {
case 'Z':
filename_text = optarg;
if (filename_text.empty()) {
cerr << "Error: Missing filename" << endl;
exit(EXIT_FAILURE);
}
@ -296,6 +307,9 @@ int ScsiCtl::run(const vector<char *>& args) const
if (!filename_binary.empty()) {
return ExportAsBinary(command, filename_binary);
}
if (!filename_text.empty()) {
return ExportAsText(command, filename_text);
}
SetParam(command, "token", token);
SetParam(command, "locale", locale);
@ -328,6 +342,21 @@ int ScsiCtl::run(const vector<char *>& args) const
return status ? EXIT_SUCCESS : EXIT_FAILURE;
}
int ScsiCtl::ExportAsBinary(const PbCommand &command, const string &filename) const
{
const string binary = command.SerializeAsString();
ofstream out;
out.open(filename, ios::binary);
out << binary;
if (out.fail()) {
cerr << "Error: Can't create protobuf binary file '" << filename << "'" << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int ScsiCtl::ExportAsJson(const PbCommand &command, const string &filename) const
{
string json;
@ -338,22 +367,22 @@ int ScsiCtl::ExportAsJson(const PbCommand &command, const string &filename) cons
ofstream out(filename);
out << json << '\n';
if (out.fail()) {
cerr << "Error: Can't create JSON file '" << filename << "'" << endl;
cerr << "Error: Can't create protobuf JSON file '" << filename << "'" << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int ScsiCtl::ExportAsBinary(const PbCommand &command, const string &filename) const
int ScsiCtl::ExportAsText(const PbCommand &command, const string &filename) const
{
const string binary = command.SerializeAsString();
string text;
TextFormat::PrintToString(command, &text);
ofstream out;
out.open(filename, ios::binary);
out << binary;
ofstream out(filename);
out << text << '\n';
if (out.fail()) {
cerr << "Error: Can't create JSON file '" << filename << "'" << endl;
cerr << "Error: Can't create protobuf text file '" << filename << "'" << endl;
return EXIT_FAILURE;
}

View File

@ -29,6 +29,7 @@ private:
void Banner(const vector<char *>&) const;
int ExportAsJson(const PbCommand&, const string&) const;
int ExportAsBinary(const PbCommand&, const string&) const;
int ExportAsJson(const PbCommand&, const string&) const;
int ExportAsText(const PbCommand&, const string&) const;
};

View File

@ -17,6 +17,7 @@ scsictl \- Sends management commands to the piscsi process
\fB\-T\fR |
\fB\-V\fR |
\fB\-X\fR |
\fB\-Z\fR |
[\fB\-d\fR \fIFILENAME\fR] |
[\fB\-B\fR \fIFILENAME\fR] |
[\fB\-J\fR \fIFILENAME\fR] |
@ -121,10 +122,13 @@ Shut down the piscsi process.
Delete an image file in the default image folder.
.TP
.BR \-B\fI " "\fIFILENAME
Do not send command to piscsi but write it to a binary protobuf file.
Do not send command to piscsi but write it to a protobuf binary file.
.TP
.BR \-J\fI " "\fIFILENAME
Do not send command to piscsi but write it to a JSON protobuf file.
Do not send command to piscsi but write it to a protobuf JSON file.
.TP
.BR \-Z\fI " "\fIFILENAME
Do not send command to piscsi but write it to a protobuf text format file.
.TP
.BR \-x\fI " "\fICURRENT_NAME:NEW_NAME
Copy an image file in the default image folder.

View File

@ -7,7 +7,7 @@ NAME
SYNOPSIS
scsictl -e | -l | -m | -o | -v | -D | -I | -L | -O | -P | -S | -T | -V
| -X | [-d FILENAME] | [-B FILENAME] | [-J FILENAME] | [-C FILE
| -X | -Z | [-d FILENAME] | [-B FILENAME] | [-J FILENAME] | [-C FILE
NAME:FILESIZE] | [-E FILENAME] | [-F IMAGE_FOLDER] | [-R CUR
RENT_NAME:NEW_NAME] | [-c CMD] | [-f FILE|PARAM] | [-g LOG_LEVEL] | [-h
HOST] | [-i ID[:LUN]] | [-n NAME] | [-p PORT] | [-r RESERVED_IDS] | [-s
@ -95,13 +95,17 @@ OPTIONS
Delete an image file in the default image folder.
-B FILENAME
Do not send command to piscsi but write it to a binary protobuf
Do not send command to piscsi but write it to a protobuf binary
file.
-J FILENAME
Do not send command to piscsi but write it to a JSON protobuf
Do not send command to piscsi but write it to a protobuf JSON
file.
-Z FILENAME
Do not send command to piscsi but write it to a protobuf text
format file.
-x CURRENT_NAME:NEW_NAME
Copy an image file in the default image folder.
@ -117,7 +121,7 @@ OPTIONS
d(etach): Detach disk
i(nsert): Insert media (removable media devices only)
e(ject): Eject media (removable media devices only)
p(rotect): Write protect the medium (not for CD-ROMs, which
p(rotect): Write protect the medium (not for CD-ROMs, which
are always read-only)
u(nprotect): Remove write protection from the medium (not for
CD-ROMs, which are always read-only)
@ -126,18 +130,18 @@ OPTIONS
eject, protect and unprotect are idempotent.
-b BLOCK_SIZE
The optional block size, either 512, 1024, 2048 or 4096 bytes.
The optional block size, either 512, 1024, 2048 or 4096 bytes.
The default size is 512 bytes.
-f FILE|PARAM
Device-specific: Either a path to a disk image file, or a param
eter for a non-disk device. See the piscsi(1) man page for per
eter for a non-disk device. See the piscsi(1) man page for per
mitted file types.
-t TYPE
Specifies the device type. This type overrides the type derived
Specifies the device type. This type overrides the type derived
from the file extension of the specified image. See the
piscsi(1) man page for the available device types. For some
piscsi(1) man page for the available device types. For some
types there are shortcuts (only the first letter is required):
hd: SCSI hard disk drive
rm: SCSI removable media drive
@ -149,16 +153,16 @@ OPTIONS
services: Host services device
-n VENDOR:PRODUCT:REVISION
The vendor, product and revision for the device, to be returned
The vendor, product and revision for the device, to be returned
with the INQUIRY data. A complete set of name components must be
provided. VENDOR may have up to 8, PRODUCT up to 16, REVISION up
to 4 characters. Padding with blanks to the maxium length is au
tomatically applied. Once set the name of a device cannot be
tomatically applied. Once set the name of a device cannot be
changed.
-u UNIT
Unit number (0-31). This will default to 0. This option is only
used when there are multiple SCSI devices on a shared SCSI con
Unit number (0-31). This will default to 0. This option is only
used when there are multiple SCSI devices on a shared SCSI con
troller. (This is not common)
EXAMPLES