5 #include <boost/filesystem.hpp>
6 #include <boost/scope_exit.hpp>
7 #include "logging/logging.h"
10 const OstreeRepoMode kOstreeRepoModeArchive =
11 #if !defined(OSTREE_CHECK_VERSION)
12 OSTREE_REPO_MODE_ARCHIVE_Z2;
13 #elif (OSTREE_CHECK_VERSION(2017, 12))
14 OSTREE_REPO_MODE_ARCHIVE;
16 OSTREE_REPO_MODE_ARCHIVE_Z2;
20 namespace fs = boost::filesystem;
22 namespace ostree_repo_sync {
24 bool ArchiveModeRepo(
const fs::path& repo_dir) {
25 GError* error =
nullptr;
26 GFile* repo_path =
nullptr;
27 OstreeRepo* repo =
nullptr;
29 BOOST_SCOPE_EXIT(&error, &repo_path, &repo) {
30 if (error !=
nullptr) {
33 if (repo_path !=
nullptr) {
34 g_object_unref(repo_path);
36 if (repo !=
nullptr) {
42 repo_path = g_file_new_for_path(repo_dir.c_str());
43 repo = ostree_repo_new(repo_path);
45 gboolean open_succeed = ostree_repo_open(repo,
nullptr, &error);
47 return ((open_succeed != 0) && (ostree_repo_get_mode(repo) == kOstreeRepoModeArchive));
50 bool LocalPullRepo(
const fs::path& src_repo_dir,
const fs::path& dst_repo_dir,
const std::string& ref_hash) {
51 GError* error =
nullptr;
52 GVariant* options =
nullptr;
53 GHashTable* refs =
nullptr;
54 GPtrArray* refs_to_fetch = g_ptr_array_new_with_free_func(g_free);
55 OstreeRepo *src_repo =
nullptr, *dst_repo =
nullptr;
56 GFile *src_repo_path =
nullptr, *dst_repo_path =
nullptr;
58 BOOST_SCOPE_EXIT(&error, &options, &refs, &refs_to_fetch, &src_repo_path, &src_repo, &dst_repo_path,
60 if (error !=
nullptr) {
63 if (options !=
nullptr) {
64 g_variant_unref(options);
66 if (src_repo_path !=
nullptr) {
67 g_object_unref(src_repo_path);
69 if (src_repo !=
nullptr) {
70 g_object_unref(src_repo);
72 if (dst_repo_path !=
nullptr) {
73 g_object_unref(dst_repo_path);
75 if (dst_repo !=
nullptr) {
76 g_object_unref(dst_repo);
78 if (refs !=
nullptr) {
79 g_hash_table_unref(refs);
81 g_ptr_array_unref(refs_to_fetch);
86 src_repo_path = g_file_new_for_path(src_repo_dir.c_str());
87 src_repo = ostree_repo_new(src_repo_path);
88 if (ostree_repo_open(src_repo,
nullptr, &error) == 0) {
89 LOG_ERROR <<
"OSTree sync error: unable to open source repo, " << error->message;
94 dst_repo_path = g_file_new_for_path(dst_repo_dir.c_str());
95 dst_repo = ostree_repo_new(dst_repo_path);
96 if (ostree_repo_create(dst_repo, kOstreeRepoModeArchive,
nullptr, &error) == 0) {
97 LOG_ERROR <<
"OSTree sync error: unable to open destination repo, " << error->message;
106 if (ostree_repo_list_refs(src_repo,
nullptr, &refs,
nullptr, &error) == 0) {
107 LOG_ERROR <<
"OSTree sync error: unable to get refs on source repo, " << error->message;
111 GHashTableIter hashiter;
112 gpointer hkey, hvalue;
114 g_hash_table_iter_init(&hashiter, refs);
115 while (g_hash_table_iter_next(&hashiter, &hkey, &hvalue) != 0) {
116 g_ptr_array_add(refs_to_fetch, g_strdup(static_cast<const char*>(hkey)));
119 g_ptr_array_add(refs_to_fetch,
nullptr);
122 const char*
const refs_to_fetch_list[] = {ref_hash.c_str()};
123 GVariantBuilder builder;
124 g_variant_builder_init(&builder, G_VARIANT_TYPE(
"a{sv}"));
125 g_variant_builder_add(&builder,
"{s@v}",
"flags", g_variant_new_variant(g_variant_new_int32(0)));
126 if (strlen(refs_to_fetch_list[0]) == 0) {
127 g_variant_builder_add(
128 &builder,
"{s@v}",
"refs",
129 g_variant_new_variant(g_variant_new_strv(reinterpret_cast<const char* const*>(refs_to_fetch->pdata), -1)));
131 g_variant_builder_add(&builder,
"{s@v}",
"refs", g_variant_new_variant(g_variant_new_strv(refs_to_fetch_list, 1)));
133 options = g_variant_ref_sink(g_variant_builder_end(&builder));
135 std::string src_repo_url(
"file://");
136 src_repo_url += src_repo_dir.native();
137 if (ostree_repo_pull_with_options(dst_repo, src_repo_url.c_str(), options,
nullptr,
nullptr, &error) == 0) {
138 LOG_ERROR <<
"OSTree sync error: unable to pull repository, " << error->message;
144 fs::path GetOstreeRepoPath(
const fs::path& ostree_sysroot_path) {
return (ostree_sysroot_path /
"ostree" /
"repo"); }