Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
ostree_object.h
1 #ifndef SOTA_CLIENT_TOOLS_OSTREE_OBJECT_H_
2 #define SOTA_CLIENT_TOOLS_OSTREE_OBJECT_H_
3 
4 #include <chrono>
5 #include <iostream>
6 #include <sstream>
7 
8 #include <curl/curl.h>
9 #include <boost/filesystem.hpp>
10 #include <boost/intrusive_ptr.hpp>
11 #include "gtest/gtest_prod.h"
12 
13 #include "garage_common.h"
14 #include "treehub_server.h"
15 
16 class OSTreeRepo;
17 class RequestPool;
18 
19 enum class PresenceOnServer { kObjectStateUnknown, kObjectPresent, kObjectMissing, kObjectInProgress };
20 
21 enum class CurrentOp { kOstreeObjectUploading, kOstreeObjectPresenceCheck };
22 
23 /**
24  * Broad categories for server response codes.
25  * There is no category for a permanent failure at the moment: we are unable to
26  * detect a failure that is definitely permanent.
27  */
28 enum class ServerResponse { kNoResponse, kOk, kTemporaryFailure };
29 
30 class OSTreeObject {
31  public:
32  using ptr = boost::intrusive_ptr<OSTreeObject>;
33  OSTreeObject(const OSTreeRepo& repo, const std::string& object_name);
34  OSTreeObject(const OSTreeObject&) = delete;
35  OSTreeObject operator=(const OSTreeObject&) = delete;
36 
37  ~OSTreeObject();
38 
39  /* This object has been uploaded, notify parents. If parent object has no more
40  * children pending upload, add the parent to the upload queue. */
41  void NotifyParents(RequestPool& pool);
42 
43  /* Send a HEAD request to the destination server to check if this object is
44  * present there. */
45  void MakeTestRequest(const TreehubServer& push_target, CURLM* curl_multi_handle);
46 
47  /* Upload this object to the destination server. */
48  void Upload(TreehubServer& push_target, CURLM* curl_multi_handle, RunMode mode);
49 
50  /* Process a completed curl transaction (presence check or upload). */
51  void CurlDone(CURLM* curl_multi_handle, RequestPool& pool);
52 
53  uintmax_t GetSize() { return boost::filesystem::file_size(file_path_); }
54 
55  PresenceOnServer is_on_server() const { return is_on_server_; }
56  CurrentOp operation() const { return current_operation_; }
57  bool children_ready() { return children_.empty(); }
58  void LaunchNotify() { is_on_server_ = PresenceOnServer::kObjectInProgress; }
59  std::chrono::steady_clock::time_point RequestStartTime() const { return request_start_time_; }
60  ServerResponse LastOperationResult() const { return last_operation_result_; }
61 
62  private:
63  using childiter = std::list<OSTreeObject::ptr>::iterator;
64  typedef std::pair<OSTreeObject*, childiter> parentref;
65 
66  /* Add parent to this object. */
67  void AddParent(OSTreeObject* parent, std::list<OSTreeObject::ptr>::iterator parent_it);
68 
69  /* Child object of this object has been uploaded, remove it from the list. */
70  void ChildNotify(std::list<OSTreeObject::ptr>::iterator child_it);
71 
72  /* If the child has is not already on the server, add it to this object's list
73  * of children and add this object as the parent of the new child. */
74  void AppendChild(const OSTreeObject::ptr& child);
75 
76  /* Parse this object for children. */
77  void PopulateChildren();
78 
79  /* Add queries to the queue for any children whose presence on the server is
80  * unknown. */
81  void QueryChildren(RequestPool& pool);
82 
83  std::string Url() const;
84 
85  /* Check for children. If they are all present and this object isn't present,
86  * upload it. If any children are missing, query them. */
87  void CheckChildren(RequestPool& pool, long rescode); // NOLINT(google-runtime-int)
88 
89  /* Handle an error from a presence check. */
90  void PresenceError(RequestPool& pool, int64_t rescode);
91 
92  /* Handle an error from an upload. */
93  void UploadError(RequestPool& pool, int64_t rescode);
94 
95  static size_t curl_handle_write(void* buffer, size_t size, size_t nmemb, void* userp);
96 
97  FRIEND_TEST(OstreeObject, Request);
98  FRIEND_TEST(OstreeObject, UploadDryRun);
99  FRIEND_TEST(OstreeObject, UploadFail);
100  FRIEND_TEST(OstreeObject, UploadSuccess);
101  friend void intrusive_ptr_add_ref(OSTreeObject* /*h*/);
102  friend void intrusive_ptr_release(OSTreeObject* /*h*/);
103  friend std::ostream& operator<<(std::ostream& stream, const OSTreeObject& o);
104 
105  const boost::filesystem::path file_path_; // Full path to the object
106  const std::string object_name_; // OSTree name of the object
107  const OSTreeRepo& repo_;
108  int refcount_; // refcounts and intrusive_ptr are used to simplify
109  // interaction with curl
110  PresenceOnServer is_on_server_;
111  CurrentOp current_operation_{};
112 
113  std::stringstream http_response_;
114  CURL* curl_handle_;
115  FILE* fd_;
116  std::list<parentref> parents_;
117  std::list<OSTreeObject::ptr> children_;
118 
119  std::chrono::steady_clock::time_point request_start_time_;
120  ServerResponse last_operation_result_{ServerResponse::kNoResponse};
121  OstreeObjectType type_{OstreeObjectType::OSTREE_OBJECT_TYPE_UNKNOWN};
122 };
123 
124 OSTreeObject::ptr ostree_object_from_curl(CURL* curlhandle);
125 
126 std::ostream& operator<<(std::ostream& stream, const OSTreeObject::ptr& o);
127 
128 // vim: set tabstop=2 shiftwidth=2 expandtab:
129 #endif // SOTA_CLIENT_TOOLS_OSTREE_OBJECT_H_
OSTreeObject
Definition: ostree_object.h:30
TreehubServer
Definition: treehub_server.h:11
OSTreeRepo
A source repository to read OSTree objects from.
Definition: ostree_repo.h:19
RequestPool
Definition: request_pool.h:12
garage_common.h
OstreeObjectType
OstreeObjectType
Types of OSTree objects, borrowed from libostree/ostree-core.h.
Definition: garage_common.h:34
RunMode
RunMode
Execution mode to run garage tools in.
Definition: garage_common.h:6