[Sheepdog] [PATCH v2, with sign-off] collie: add --raw option for machine-readable output
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Sun Jun 19 18:10:19 CEST 2011
At Sat, 18 Jun 2011 17:04:05 +0100,
Chris Webb wrote:
>
> This option modifies the info and list displays to make them easier to parse
> reliably from C and shell scripts, separating each column with a single
> space character. We also display times in seconds since the epoch, print
> sizes in raw bytes rather than using units of MB, GB, TB, etc., and escape
> whitespace characters and backslashes in VDI names with a leading backslash
> escape.
>
> Signed-off-by: Chris Webb <chris at arachsys.com>
> ---
> collie/collie.c | 97 +++++++++++++++++++++++++++++++++++++++----------------
> 1 files changed, 69 insertions(+), 28 deletions(-)
Applied, thanks!
Kazutaka
>
> diff --git a/collie/collie.c b/collie/collie.c
> index 3b91f84..759d4c0 100644
> --- a/collie/collie.c
> +++ b/collie/collie.c
> @@ -8,6 +8,7 @@
> * You should have received a copy of the GNU General Public License
> * along with this program. If not, see <http://www.gnu.org/licenses/>.
> */
> +#include <ctype.h>
> #include <errno.h>
> #include <getopt.h>
> #include <inttypes.h>
> @@ -35,6 +36,7 @@ static char program_name[] = "collie";
> static const char *sdhost = "localhost";
> static int sdport = SD_LISTEN_PORT;
> static int highlight = 1;
> +static int raw_output = 0;
>
> #define TEXT_NORMAL "\033[0m"
> #define TEXT_BOLD "\033[1m"
> @@ -42,9 +44,10 @@ static int highlight = 1;
> #define COMMON_LONG_OPTIONS \
> {"address", required_argument, NULL, 'a'}, \
> {"port", required_argument, NULL, 'p'}, \
> + {"raw", no_argument, NULL, 'r'}, \
> {"help", no_argument, NULL, 'h'}, \
>
> -#define COMMON_SHORT_OPTIONS "a:p:h"
> +#define COMMON_SHORT_OPTIONS "a:p:hr"
>
> static void usage(int status)
> {
> @@ -62,6 +65,8 @@ Command syntax:\n\
> Common parameters:\n\
> -a, --address specify the daemon address (default: localhost)\n\
> -p, --port specify the daemon port\n\
> + -r, --raw raw output mode: omit headers, separate fields with\n\
> + single spaces and print all sizes in decimal bytes\n\
> -h, --help display this help and exit\n\
> ");
> }
> @@ -84,12 +89,17 @@ static char *size_to_str(uint64_t _size, char *str, int str_size)
> {
> const char *units[] = {"MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
> int i = 0;
> - double size = (double)_size;
> + double size;
>
> + if (raw_output) {
> + snprintf(str, str_size, "%" PRIu64, _size);
> + return str;
> + }
> +
> + size = (double)_size;
> size /= 1024 * 1024;
> while (i < ARRAY_SIZE(units) && size >= 1024) {
> i++;
> -
> size /= 1024;
> }
>
> @@ -360,16 +370,19 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid,
> {
> int idx;
> uint64_t my_objs, cow_objs;
> - char vdi_size_str[8], my_objs_str[8], cow_objs_str[8];
> + char vdi_size_str[16], my_objs_str[16], cow_objs_str[16];
> time_t ti;
> struct tm tm;
> char dbuf[128];
>
> ti = i->ctime >> 32;
> - localtime_r(&ti, &tm);
> -
> - strftime(dbuf, sizeof(dbuf),
> - "%Y-%m-%d %H:%M", &tm);
> + if (raw_output) {
> + snprintf(dbuf, sizeof(dbuf), "%" PRIu64, (uint64_t) ti);
> + } else {
> + localtime_r(&ti, &tm);
> + strftime(dbuf, sizeof(dbuf),
> + "%Y-%m-%d %H:%M", &tm);
> + }
>
> my_objs = 0;
> cow_objs = 0;
> @@ -387,9 +400,20 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid,
> size_to_str(cow_objs * SD_DATA_OBJ_SIZE, cow_objs_str, sizeof(cow_objs_str));
>
> if (!data || strcmp(name, data) == 0) {
> - printf("%c %-8s %5d %7s %7s %7s %s %7" PRIx32 "\n",
> - is_current(i) ? ' ' : 's', name, snapid,
> - vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
> + if (raw_output) {
> + printf("%c ", is_current(i) ? '=' : 's');
> + while (*name) {
> + if (isspace(*name) || *name == '\\')
> + putchar('\\');
> + putchar(*name++);
> + }
> + printf(" %d %s %s %s %s %" PRIx32 "\n", snapid,
> + vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
> + } else {
> + printf("%c %-8s %5d %7s %7s %7s %s %7" PRIx32 "\n",
> + is_current(i) ? ' ' : 's', name, snapid,
> + vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
> + }
> }
> }
>
> @@ -598,8 +622,10 @@ static int node_list(int argc, char **argv)
> {
> int i;
>
> - printf(" Idx - Host:Port Number of vnodes\n");
> - printf("------------------------------------------------\n");
> + if (!raw_output) {
> + printf(" Idx - Host:Port Number of vnodes\n");
> + printf("------------------------------------------------\n");
> + }
> for (i = 0; i < nr_nodes; i++) {
> char data[128];
>
> @@ -609,11 +635,13 @@ static int node_list(int argc, char **argv)
> if (i == master_idx) {
> if (highlight)
> printf(TEXT_BOLD);
> - printf("* %4d - %-20s\t%d\n", i, data, node_list_entries[i].nr_vnodes);
> + printf(raw_output ? "* %d %s %d\n" : "* %4d - %-20s\t%d\n",
> + i, data, node_list_entries[i].nr_vnodes);
> if (highlight)
> printf(TEXT_NORMAL);
> } else
> - printf(" %4d - %-20s\t%d\n", i, data, node_list_entries[i].nr_vnodes);
> + printf(raw_output ? "- %d %s %d\n" : " %4d - %-20s\t%d\n",
> + i, data, node_list_entries[i].nr_vnodes);
> }
>
> return EXIT_SUCCESS;
> @@ -625,7 +653,8 @@ static int node_info(int argc, char **argv)
> uint64_t total_size = 0, total_avail = 0, total_vdi_size = 0;
> char total_str[8], avail_str[8], vdi_size_str[8];
>
> - printf("Id\tSize\tUsed\tUse%%\n");
> + if (!raw_output)
> + printf("Id\tSize\tUsed\tUse%%\n");
>
> for (i = 0; i < nr_nodes; i++) {
> char name[128];
> @@ -655,7 +684,8 @@ static int node_info(int argc, char **argv)
> size_to_str(rsp->store_size - rsp->store_free, free_str,
> sizeof(free_str));
> if (!ret && rsp->result == SD_RES_SUCCESS) {
> - printf("%2d\t%s\t%s\t%3d%%\n", i, store_str, free_str,
> + printf(raw_output ? "%d %s %s %d%%\n" : "%2d\t%s\t%s\t%3d%%\n",
> + i, store_str, free_str,
> (int)(((double)(rsp->store_size - rsp->store_free) / rsp->store_size) * 100));
> success++;
> }
> @@ -664,8 +694,6 @@ static int node_info(int argc, char **argv)
> total_avail += rsp->store_free;
> }
>
> - printf("\n");
> -
> if (success == 0) {
> fprintf(stderr, "cannot get information from any nodes\n");
> return EXIT_SYSFAIL;
> @@ -676,7 +704,8 @@ static int node_info(int argc, char **argv)
> size_to_str(total_size, total_str, sizeof(total_str));
> size_to_str(total_size - total_avail, avail_str, sizeof(avail_str));
> size_to_str(total_vdi_size, vdi_size_str, sizeof(vdi_size_str));
> - printf("Total\t%s\t%s\t%3d%%, total virtual VDI Size\t%s\n",
> + printf(raw_output ? "Total %s %s %d%% %s\n"
> + : "\nTotal\t%s\t%s\t%3d%%, total virtual VDI Size\t%s\n",
> total_str, avail_str,
> (int)(((double)(total_size - total_avail) / total_size) * 100),
> vdi_size_str);
> @@ -692,8 +721,10 @@ static struct subcommand node_cmd[] = {
>
> static int vdi_list(int argc, char **argv)
> {
> - printf(" name id size used shared creation time vdi id\n");
> - printf("------------------------------------------------------------------\n");
> + if (!raw_output) {
> + printf(" name id size used shared creation time vdi id\n");
> + printf("------------------------------------------------------------------\n");
> + }
>
> parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL);
> return EXIT_SUCCESS;
> @@ -1143,13 +1174,16 @@ static int cluster_info(int argc, char **argv)
> if (ret != 0)
> return EXIT_SYSFAIL;
>
> + if (!raw_output)
> + printf("Cluster status: ");
> if (rsp->result == SD_RES_SUCCESS)
> printf("running\n");
> else
> printf("%s\n", sd_strerror(rsp->result));
>
> - printf("\n");
> - printf("Ctime Epoch Nodes\n");
> + if (!raw_output)
> + printf("\nCreation time Epoch Nodes\n");
> +
> nr_logs = rsp->data_length / sizeof(struct epoch_log);
> for (i = 0; i < nr_logs; i++) {
> int j;
> @@ -1157,10 +1191,14 @@ static int cluster_info(int argc, char **argv)
> struct sheepdog_node_list_entry *entry;
>
> ti = logs[i].ctime >> 32;
> - localtime_r(&ti, &tm);
> - strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm);
> + if (raw_output) {
> + snprintf(time_str, sizeof(time_str), "%" PRIu64, (uint64_t) ti);
> + } else {
> + localtime_r(&ti, &tm);
> + strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm);
> + }
>
> - printf("%s %6d", time_str, logs[i].epoch);
> + printf(raw_output ? "%s %d" : "%s %6d", time_str, logs[i].epoch);
> printf(" [");
> for (j = 0; j < logs[i].nr_nodes; j++) {
> entry = logs[i].nodes + j;
> @@ -1300,6 +1338,9 @@ int main(int argc, char **argv)
> case 'p':
> sdport = atoi(optarg);
> break;
> + case 'r':
> + raw_output = 1;
> + break;
> case 'h':
> if (command_help)
> command_help();
> @@ -1316,7 +1357,7 @@ int main(int argc, char **argv)
> }
> }
>
> - if (!isatty(STDOUT_FILENO))
> + if (!isatty(STDOUT_FILENO) || raw_output)
> highlight = 0;
>
> if (flags & SUBCMD_FLAG_NEED_NODELIST) {
> --
> 1.7.4.1
>
> --
> sheepdog mailing list
> sheepdog at lists.wpkg.org
> http://lists.wpkg.org/mailman/listinfo/sheepdog
More information about the sheepdog
mailing list