5 #include <boost/filesystem.hpp> 6 #include <boost/scope_exit.hpp> 8 #include "logging/logging.h" 11 const OstreeRepoMode kOstreeRepoModeArchive =
12 #if !defined(OSTREE_CHECK_VERSION) 13 OSTREE_REPO_MODE_ARCHIVE_Z2;
14 #elif (OSTREE_CHECK_VERSION(2017, 12)) 15 OSTREE_REPO_MODE_ARCHIVE;
17 OSTREE_REPO_MODE_ARCHIVE_Z2;
25 bool ArchiveModeRepo(
const fs::path& repo_dir) {
26 GError* error =
nullptr;
27 GFile* repo_path =
nullptr;
28 OstreeRepo* repo =
nullptr;
30 BOOST_SCOPE_EXIT(&error, &repo_path, &repo) {
31 if (error !=
nullptr) {
34 if (repo_path !=
nullptr) {
35 g_object_unref(repo_path);
37 if (repo !=
nullptr) {
43 repo_path = g_file_new_for_path(repo_dir.c_str());
44 repo = ostree_repo_new(repo_path);
46 gboolean open_succeed = ostree_repo_open(repo,
nullptr, &error);
48 return ((open_succeed != 0) && (ostree_repo_get_mode(repo) == kOstreeRepoModeArchive));
51 bool LocalPullRepo(
const fs::path& src_repo_dir,
const fs::path& dst_repo_dir,
const std::string& ref_hash) {
52 GError* error =
nullptr;
53 GVariant* options =
nullptr;
54 GHashTable* refs =
nullptr;
55 GPtrArray* refs_to_fetch = g_ptr_array_new_with_free_func(g_free);
56 OstreeRepo* src_repo =
nullptr;
57 OstreeRepo* dst_repo =
nullptr;
58 GFile* src_repo_path =
nullptr;
59 GFile* dst_repo_path =
nullptr;
61 BOOST_SCOPE_EXIT(&error, &options, &refs, &refs_to_fetch, &src_repo_path, &src_repo, &dst_repo_path,
63 if (error !=
nullptr) {
66 if (options !=
nullptr) {
67 g_variant_unref(options);
69 if (src_repo_path !=
nullptr) {
70 g_object_unref(src_repo_path);
72 if (src_repo !=
nullptr) {
73 g_object_unref(src_repo);
75 if (dst_repo_path !=
nullptr) {
76 g_object_unref(dst_repo_path);
78 if (dst_repo !=
nullptr) {
79 g_object_unref(dst_repo);
81 if (refs !=
nullptr) {
82 g_hash_table_unref(refs);
84 g_ptr_array_unref(refs_to_fetch);
89 src_repo_path = g_file_new_for_path(src_repo_dir.c_str());
90 src_repo = ostree_repo_new(src_repo_path);
91 if (ostree_repo_open(src_repo,
nullptr, &error) == 0) {
92 LOG_ERROR <<
"OSTree sync error: unable to open source repo, " << error->message;
97 dst_repo_path = g_file_new_for_path(dst_repo_dir.c_str());
98 dst_repo = ostree_repo_new(dst_repo_path);
99 if (ostree_repo_create(dst_repo, kOstreeRepoModeArchive,
nullptr, &error) == 0) {
100 LOG_ERROR <<
"OSTree sync error: unable to open destination repo, " << error->message;
109 if (ostree_repo_list_refs(src_repo,
nullptr, &refs,
nullptr, &error) == 0) {
110 LOG_ERROR <<
"OSTree sync error: unable to get refs on source repo, " << error->message;
114 GHashTableIter hashiter;
118 g_hash_table_iter_init(&hashiter, refs);
119 while (g_hash_table_iter_next(&hashiter, &hkey, &hvalue) != 0) {
120 g_ptr_array_add(refs_to_fetch, g_strdup(static_cast<const char*>(hkey)));
123 g_ptr_array_add(refs_to_fetch,
nullptr);
126 const char*
const refs_to_fetch_list[] = {ref_hash.c_str()};
127 GVariantBuilder builder;
128 g_variant_builder_init(&builder, G_VARIANT_TYPE(
"a{sv}"));
129 g_variant_builder_add(&builder,
"{s@v}",
"flags", g_variant_new_variant(g_variant_new_int32(0)));
130 if (strlen(refs_to_fetch_list[0]) == 0) {
131 g_variant_builder_add(
132 &builder,
"{s@v}",
"refs",
133 g_variant_new_variant(g_variant_new_strv(reinterpret_cast<const char* const*>(refs_to_fetch->pdata), -1)));
135 g_variant_builder_add(&builder,
"{s@v}",
"refs", g_variant_new_variant(g_variant_new_strv(refs_to_fetch_list, 1)));
137 options = g_variant_ref_sink(g_variant_builder_end(&builder));
139 std::string src_repo_url(
"file://");
140 src_repo_url += src_repo_dir.native();
141 if (ostree_repo_pull_with_options(dst_repo, src_repo_url.c_str(), options,
nullptr,
nullptr, &error) == 0) {
142 LOG_ERROR <<
"OSTree sync error: unable to pull repository, " << error->message;
148 fs::path GetOstreeRepoPath(
const fs::path& ostree_sysroot_path) {
return (ostree_sysroot_path /
"ostree" /
"repo"); }