Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
ostree_http_repo.cc
1 #include "ostree_http_repo.h"
2 
3 #include <fcntl.h>
4 
5 #include <string>
6 
7 #include <boost/property_tree/ini_parser.hpp>
8 
9 #include "logging/logging.h"
10 #include "utilities/utils.h"
11 
12 namespace pt = boost::property_tree;
13 
14 bool OSTreeHttpRepo::LooksValid() const {
15  if (FetchObject("config")) {
16  pt::ptree config;
17  try {
18  pt::read_ini((root_ / "config").string(), config);
19  if (config.get<std::string>("core.mode") != "archive-z2") {
20  LOG_WARNING << "OSTree repo is not in archive-z2 format";
21  return false;
22  }
23  return true;
24 
25  } catch (const pt::ini_parser_error &error) {
26  LOG_WARNING << "Couldn't parse OSTree config file: " << (root_ / "config").string();
27  return false;
28  } catch (const pt::ptree_error &error) {
29  LOG_WARNING << "Could not find core.mode in OSTree config file";
30  return false;
31  }
32  } else {
33  return false;
34  }
35 }
36 
37 OSTreeRef OSTreeHttpRepo::GetRef(const std::string &refname) const { return OSTreeRef(*server_, refname); }
38 
39 bool OSTreeHttpRepo::FetchObject(const boost::filesystem::path &path) const {
40  CURLcode err = CURLE_OK;
41  CurlEasyWrapper easy_handle;
42  curlEasySetoptWrapper(easy_handle.get(), CURLOPT_VERBOSE, get_curlopt_verbose());
43  server_->InjectIntoCurl(path.string(), easy_handle.get());
44  curlEasySetoptWrapper(easy_handle.get(), CURLOPT_WRITEFUNCTION, &OSTreeHttpRepo::curl_handle_write);
45  boost::filesystem::create_directories((root_ / path).parent_path());
46  std::string filename = (root_ / path).string();
47  int fp = open(filename.c_str(), O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
48  if (fp == -1) {
49  LOG_ERROR << "Failed to open file: " << filename;
50  return false;
51  }
52  curlEasySetoptWrapper(easy_handle.get(), CURLOPT_WRITEDATA, &fp);
53  curlEasySetoptWrapper(easy_handle.get(), CURLOPT_FAILONERROR, true);
54  err = curl_easy_perform(easy_handle.get());
55  close(fp);
56 
57  if (err == CURLE_HTTP_RETURNED_ERROR) {
58  // http error (error code >= 400)
59  // verbose mode will display the details
60  remove((root_ / path).c_str());
61  return false;
62  } else if (err != CURLE_OK) {
63  // other unexpected error
64  char *last_url = nullptr;
65  curl_easy_getinfo(easy_handle.get(), CURLINFO_EFFECTIVE_URL, &last_url);
66  LOG_ERROR << "Failed to get object:" << curl_easy_strerror(err);
67  if (last_url != nullptr) {
68  LOG_ERROR << "Url: " << last_url;
69  }
70  remove((root_ / path).c_str());
71  return false;
72  }
73 
74  return true;
75 }
76 
77 size_t OSTreeHttpRepo::curl_handle_write(void *buffer, size_t size, size_t nmemb, void *userp) {
78  return static_cast<size_t>(write(*static_cast<int *>(userp), buffer, nmemb * size));
79 }
80 
81 // vim: set tabstop=2 shiftwidth=2 expandtab:
CurlEasyWrapper
Definition: utils.h:167
OSTreeRef
Definition: ostree_ref.h:13