1 /*
2    Copyright 2013-2014 EditShare, 2013-2015 Skytechnology sp. z o.o.
3 
4    This file is part of LizardFS.
5 
6    LizardFS is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, version 3.
9 
10    LizardFS is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with LizardFS. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "common/platform.h"
20 #include "admin/list_goals_command.h"
21 
22 #include <iomanip>
23 #include <iostream>
24 #include <vector>
25 
26 #include "admin/escape_porcelain_string.h"
27 #include "protocol/cltoma.h"
28 #include "common/goal.h"
29 #include "protocol/matocl.h"
30 #include "common/serialization_macros.h"
31 #include "common/serialized_goal.h"
32 #include "common/server_connection.h"
33 
name() const34 std::string ListGoalsCommand::name() const {
35 	return "list-goals";
36 }
37 
supportedOptions() const38 LizardFsProbeCommand::SupportedOptions ListGoalsCommand::supportedOptions() const {
39 	return {
40 		{kPorcelainMode, kPorcelainModeDescription},
41 		{"--pretty", "Print nice table"}
42 	};
43 }
44 
usage() const45 void ListGoalsCommand::usage() const {
46 	std::cerr << name() << " <master ip> <master port>\n";
47 	std::cerr << "    List goal definitions.\n";
48 }
49 
run(const Options & options) const50 void ListGoalsCommand::run(const Options& options) const {
51 	if (options.arguments().size() != 2) {
52 		throw WrongUsageException("Expected <master ip> and <master port> for " + name());
53 	}
54 
55 	ServerConnection connection(options.argument(0), options.argument(1));
56 	std::vector<SerializedGoal> serializedGoals;
57 	auto request = cltoma::listGoals::build(true);
58 	auto response = connection.sendAndReceive(request, LIZ_MATOCL_LIST_GOALS);
59 	matocl::listGoals::deserialize(response, serializedGoals);
60 
61 	if (options.isSet(kPorcelainMode)) {
62 		for (const SerializedGoal& goal : serializedGoals) {
63 			std::cout << std::to_string(goal.id) << " "
64 					<< goal.name << " "
65 					<< escapePorcelainString(goal.definition) << std::endl;
66 		}
67 	} else if (options.isSet("--pretty")) {
68 		std::cout << "Goal definitions:" << std::endl;
69 		int maxNameLength = std::max<int>(
70 				std::max_element(
71 					serializedGoals.begin(),
72 					serializedGoals.end(),
73 					[](const SerializedGoal& a, const SerializedGoal& b) {
74 						return a.name.length() < b.name.length();
75 					}
76 				)->name.length(),
77 				sizeof ("Name") - 1
78 			);
79 		int maxDefinitionLength = std::max<int>(
80 				std::max_element(
81 					serializedGoals.begin(),
82 					serializedGoals.end(),
83 					[](const SerializedGoal& a, const SerializedGoal& b) {
84 						return a.definition.length() < b.definition.length();
85 					}
86 				)->definition.length(),
87 				sizeof ("Definition") - 1
88 			);
89 		std::string frame = "----+-" + std::string(maxNameLength, '-')
90 			+ "-+-" + std::string(maxDefinitionLength + 1, '-');
91 		std::cout << frame << std::endl;
92 		std::cout << " Id | " << std::setw(maxNameLength)
93 			<< std::left << "Name" << " | Definition" << std::endl;
94 		std::cout << frame << std::endl;
95 		for (const SerializedGoal& goal : serializedGoals) {
96 			std::cout << std::setw(3) << std::right << std::to_string(goal.id) << " | "
97 					<< std::setw(maxNameLength) << std::left << goal.name << " | "
98 					<< goal.definition << std::endl;
99 		}
100 		std::cout << frame << std::endl;
101 	} else {
102 		std::cout << "Goal definitions:\nId\tName\tDefinition" << std::endl;
103 		for (const SerializedGoal& goal : serializedGoals) {
104 			std::cout << std::to_string(goal.id) << "\t"
105 					<< goal.name << "\t"
106 					<< goal.definition << std::endl;
107 		}
108 	}
109 }
110 
111