CernVM-FS  2.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
swissknife_lease.cc
Go to the documentation of this file.
1 
5 #include "swissknife_lease.h"
6 
7 #include <algorithm>
8 #include <vector>
9 
10 #include "gateway_util.h"
11 #include "logging.h"
12 #include "swissknife_lease_curl.h"
13 #include "swissknife_lease_json.h"
14 #include "util/posix.h"
15 #include "util/string.h"
16 
17 namespace {
18 
20  if (p.action != "acquire" && p.action != "drop") {
21  return false;
22  }
23 
24  return true;
25 }
26 
27 } // namespace
28 
29 namespace swissknife {
30 
31 enum LeaseError {
40 };
41 
43 
45  ParameterList r;
46  r.push_back(Parameter::Mandatory('u', "repo service url"));
47  r.push_back(Parameter::Mandatory('a', "action (acquire or drop)"));
48  r.push_back(Parameter::Mandatory('k', "key file"));
49  r.push_back(Parameter::Mandatory('p', "lease path"));
50  return r;
51 }
52 
54  Parameters params;
55 
56  params.repo_service_url = *(args.find('u')->second);
57  params.action = *(args.find('a')->second);
58  params.key_file = *(args.find('k')->second);
59 
60  params.lease_path = *(args.find('p')->second);
61  std::vector<std::string> tokens = SplitString(params.lease_path, '/');
62  const std::string lease_fqdn = tokens.front();
63 
64  if (!CheckParams(params)) {
65  return kLeaseParamError;
66  }
67 
68  // Initialize curl
69  if (curl_global_init(CURL_GLOBAL_ALL)) {
70  return kLeaseCurlInitError;
71  }
72 
73  std::string key_id;
74  std::string secret;
75  if (!gateway::ReadKeys(params.key_file, &key_id, &secret)) {
76  LogCvmfs(kLogCvmfs, kLogStderr, "Error reading key file %s.",
77  params.key_file.c_str());
78  return kLeaseKeyParseError;
79  }
80 
82  if (params.action == "acquire") {
83  CurlBuffer buffer;
84  if (MakeAcquireRequest(key_id, secret, params.lease_path,
85  params.repo_service_url, &buffer)) {
86  std::string session_token;
87  LeaseReply rep = ParseAcquireReply(buffer, &session_token);
88  switch (rep) {
89  case kLeaseReplySuccess:
90  {
91  const std::string token_file_name =
92  "/var/spool/cvmfs/" + lease_fqdn + "/session_token";
93 
94  if (!SafeWriteToFile(session_token, token_file_name, 0600)) {
95  LogCvmfs(kLogCvmfs, kLogStderr, "Error opening file: %s",
96  std::strerror(errno));
97  ret = kLeaseFileOpenError;
98  }
99  }
100  break;
101  case kLeaseReplyBusy:
102  return kLeaseBusy;
103  break;
104  case kLeaseReplyFailure:
105  default:
106  return kLeaseFailure;
107  }
108  } else {
109  ret = kLeaseCurlReqError;
110  }
111  } else if (params.action == "drop") {
112  // Try to read session token from repository scratch directory
113  std::string session_token;
114  std::string token_file_name =
115  "/var/spool/cvmfs/" + lease_fqdn + "/session_token";
116  FILE* token_file = std::fopen(token_file_name.c_str(), "r");
117  if (token_file) {
118  GetLineFile(token_file, &session_token);
119  LogCvmfs(kLogCvmfs, kLogDebug, "Read session token from file: %s",
120  session_token.c_str());
121 
122  CurlBuffer buffer;
123  if (MakeEndRequest("DELETE", key_id, secret, session_token,
124  params.repo_service_url, "", &buffer)) {
125  if (kLeaseReplySuccess == ParseDropReply(buffer)) {
126  std::fclose(token_file);
127  if (unlink(token_file_name.c_str())) {
129  "Warning - Could not delete session token file.");
130  }
131  return kLeaseSuccess;
132  } else {
133  LogCvmfs(kLogCvmfs, kLogStderr, "Could not drop active lease");
134  ret = kLeaseFailure;
135  }
136  } else {
137  LogCvmfs(kLogCvmfs, kLogStderr, "Error making DELETE request");
138  ret = kLeaseCurlReqError;
139  }
140 
141  std::fclose(token_file);
142  } else {
143  LogCvmfs(kLogCvmfs, kLogStderr, "Error reading session token from file");
144  ret = kLeaseFileOpenError;
145  }
146  }
147 
148  return ret;
149 }
150 
151 } // namespace swissknife
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
bool MakeEndRequest(const std::string &method, const std::string &key_id, const std::string &secret, const std::string &session_token, const std::string &repo_service_url, const std::string &request_payload, CurlBuffer *reply)
vector< string > SplitString(const string &str, const char delim, const unsigned max_chunks)
Definition: string.cc:288
virtual int Main(const ArgumentList &args)
std::vector< Parameter > ParameterList
Definition: swissknife.h:71
bool SafeWriteToFile(const std::string &content, const std::string &path, int mode)
Definition: posix.cc:2027
bool GetLineFile(FILE *f, std::string *line)
Definition: string.cc:379
bool CheckParams(const swissknife::CommandLease::Parameters &p)
static Parameter Mandatory(const char key, const std::string &desc)
Definition: swissknife.h:38
bool ReadKeys(const std::string &key_file_name, std::string *key_id, std::string *secret)
Definition: gateway_util.cc:37
virtual ParameterList GetParams() const
static void MakeAcquireRequest(const gateway::GatewayKey &key, const std::string &repo_path, const std::string &repo_service_url, int llvl, CurlBuffer *buffer)
std::map< char, SharedPtr< std::string > > ArgumentList
Definition: swissknife.h:72
static LeaseReply ParseDropReply(const CurlBuffer &buffer, int llvl)
static LeaseReply ParseAcquireReply(const CurlBuffer &buffer, std::string *session_token, int llvl)