Skip to content

Commit

Permalink
fix: ostree config doesn't have the correct update
Browse files Browse the repository at this point in the history
When adding and removing a repository, ostree's repo config isn't updated.
  • Loading branch information
ice909 committed Feb 27, 2025
1 parent 860c7b4 commit 8f04db4
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 69 deletions.
4 changes: 2 additions & 2 deletions libs/linglong/src/linglong/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1857,8 +1857,8 @@ int Cli::repo(CLI::App *app)
}

// remove last slash
if (options.repoOptions.repoUrl.back() == '/') {
options.repoOptions.repoUrl.pop_back();
if (url.back() == '/') {
url.pop_back();
}
}

Expand Down
153 changes: 86 additions & 67 deletions libs/linglong/src/linglong/repo/ostree_repo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include <system_error>

Check warning on line 53 in libs/linglong/src/linglong/repo/ostree_repo.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <system_error> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <thread>

Check warning on line 54 in libs/linglong/src/linglong/repo/ostree_repo.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <thread> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <unordered_map>

Check warning on line 55 in libs/linglong/src/linglong/repo/ostree_repo.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <unordered_map> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <unordered_set>

Check warning on line 56 in libs/linglong/src/linglong/repo/ostree_repo.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <unordered_set> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <utility>

Check warning on line 57 in libs/linglong/src/linglong/repo/ostree_repo.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <utility> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <vector>

Check warning on line 58 in libs/linglong/src/linglong/repo/ostree_repo.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <vector> not found. Please note: Cppcheck does not need standard library headers to get proper results.

Expand Down Expand Up @@ -357,46 +358,76 @@ utils::error::Result<QString> commitDirToRepo(std::vector<GFile *> dirs,
return commit;
}

utils::error::Result<void> updateOstreeRepoConfig(OstreeRepo *repo,
const QString &remoteName,
const QString &url,
const QString &parent = "") noexcept
utils::error::Result<void>
updateOstreeRepoConfig(OstreeRepo *repo,
const linglong::api::types::v1::RepoConfigV2 &config,
const QString &parent = "") noexcept
{
LINGLONG_TRACE("update configuration");

g_autoptr(GVariant) options = NULL;
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
g_variant_builder_add(&builder, "{sv}", "gpg-verify", g_variant_new_boolean(FALSE));
// NOTE:
// libcurl 8.2.1 has a http2 bug https://github.com/curl/curl/issues/11859
// We disable http2 for now.
g_variant_builder_add(&builder, "{sv}", "http2", g_variant_new_boolean(FALSE));
options = g_variant_ref_sink(g_variant_builder_end(&builder));

g_autoptr(GError) gErr = nullptr;
if (ostree_repo_remote_change(repo,
nullptr,
OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS,
remoteName.toUtf8(),
nullptr,
nullptr,
nullptr,
&gErr)
== FALSE) {
return LINGLONG_ERR("ostree_repo_remote_change", gErr);

g_auto(GStrv) remoteNames = ostree_repo_remote_list(repo, nullptr);
if (!remoteNames) {
return LINGLONG_ERR("ostree_repo_remote_list Failed to get remote list");
}

if (ostree_repo_remote_change(repo,
nullptr,
OSTREE_REPO_REMOTE_CHANGE_ADD,
remoteName.toUtf8(),
(url + "/repos/" + remoteName).toUtf8(),
options,
nullptr,
&gErr)
== FALSE) {
return LINGLONG_ERR("ostree_repo_remote_change", gErr);
std::unordered_set<std::string> validRemotes;
for (const auto &repoCfg : config.repos) {
validRemotes.insert(repoCfg.alias.value_or(repoCfg.name));
}

for (auto remoteName = remoteNames; *remoteName != nullptr; remoteName++) {
if (validRemotes.find(*remoteName) == validRemotes.end()) {
if (ostree_repo_remote_change(repo,
nullptr,
OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS,
*remoteName,
nullptr,
nullptr,
nullptr,
&gErr)
== FALSE) {
return LINGLONG_ERR("ostree_repo_remote_change", gErr);
}
}
}

for (const auto &repoCfg : config.repos) {
const std::string &remoteUrl = repoCfg.url + "/repos/" + repoCfg.name;
g_autoptr(GVariant) options = NULL;
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
g_variant_builder_add(&builder, "{sv}", "gpg-verify", g_variant_new_boolean(FALSE));
// NOTE:
// libcurl 8.2.1 has a http2 bug https://github.com/curl/curl/issues/11859
// We disable http2 for now.
g_variant_builder_add(&builder, "{sv}", "http2", g_variant_new_boolean(FALSE));
options = g_variant_ref_sink(g_variant_builder_end(&builder));

if (ostree_repo_remote_change(repo,
nullptr,
OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS,
repoCfg.alias.value_or(repoCfg.name).c_str(),
nullptr,
nullptr,
nullptr,
&gErr)
== FALSE) {
return LINGLONG_ERR("ostree_repo_remote_change", gErr);
}

if (ostree_repo_remote_change(repo,
nullptr,
OSTREE_REPO_REMOTE_CHANGE_ADD,
repoCfg.alias.value_or(repoCfg.name).c_str(),
remoteUrl.c_str(),
options,
nullptr,
&gErr)
== FALSE) {
return LINGLONG_ERR("ostree_repo_remote_change", gErr);
}
}

GKeyFile *configKeyFile = ostree_repo_get_config(repo);
Expand All @@ -417,10 +448,10 @@ utils::error::Result<void> updateOstreeRepoConfig(OstreeRepo *repo,
return LINGLONG_OK;
}

utils::error::Result<OstreeRepo *> createOstreeRepo(const QDir &location,
const QString &remoteName,
const QString &url,
const QString &parent = "") noexcept
utils::error::Result<OstreeRepo *>
createOstreeRepo(const QDir &location,
const linglong::api::types::v1::RepoConfigV2 &config,
const QString &parent = "") noexcept
{
LINGLONG_TRACE("create linglong repository at " + location.absolutePath());

Expand All @@ -439,7 +470,7 @@ utils::error::Result<OstreeRepo *> createOstreeRepo(const QDir &location,
return LINGLONG_ERR("ostree_repo_create", gErr);
}

auto result = updateOstreeRepoConfig(ostreeRepo, remoteName, url, parent);
auto result = updateOstreeRepoConfig(ostreeRepo, config, parent);

if (!result) {
return LINGLONG_ERR(result);
Expand Down Expand Up @@ -721,10 +752,7 @@ OSTreeRepo::OSTreeRepo(const QDir &path,

LINGLONG_TRACE("init ostree-based linglong repository");

const auto defaultRepo = getDefaultRepo(this->cfg);
auto result = createOstreeRepo(this->ostreeRepoDir().absolutePath(),
QString::fromStdString(defaultRepo.name),
QString::fromStdString(defaultRepo.url));
auto result = createOstreeRepo(this->ostreeRepoDir().absolutePath(), this->cfg);
if (!result) {
qCritical() << LINGLONG_ERRV(result);
qFatal("abort");
Expand Down Expand Up @@ -760,15 +788,9 @@ OSTreeRepo::updateConfig(const api::types::v1::RepoConfigV2 &newCfg) noexcept
}

utils::Transaction transaction;
const auto newRepo = getDefaultRepo(newCfg);
result = updateOstreeRepoConfig(this->ostreeRepo.get(),
QString::fromStdString(newRepo.name),
QString::fromStdString(newRepo.url));
result = updateOstreeRepoConfig(this->ostreeRepo.get(), newCfg);
transaction.addRollBack([this]() noexcept {
const auto defaultRepo = getDefaultRepo(this->cfg);
auto result = updateOstreeRepoConfig(this->ostreeRepo.get(),
QString::fromStdString(defaultRepo.name),
QString::fromStdString(defaultRepo.url));
auto result = updateOstreeRepoConfig(this->ostreeRepo.get(), this->cfg);
if (!result) {
qCritical() << result.error();
Q_ASSERT(false);
Expand All @@ -780,6 +802,7 @@ OSTreeRepo::updateConfig(const api::types::v1::RepoConfigV2 &newCfg) noexcept

transaction.commit();

const auto newRepo = getDefaultRepo(newCfg);
this->m_clientFactory.setServer(QString::fromStdString(newRepo.url));
this->cfg = newCfg;

Expand All @@ -803,18 +826,12 @@ utils::error::Result<void> OSTreeRepo::setConfig(const api::types::v1::RepoConfi
Q_ASSERT(false);
}
});
const auto newRepo = getDefaultRepo(cfg);
result = updateOstreeRepoConfig(this->ostreeRepo.get(),
QString::fromStdString(newRepo.name),
QString::fromStdString(newRepo.url));
result = updateOstreeRepoConfig(this->ostreeRepo.get(), cfg);
if (!result) {
return LINGLONG_ERR(result);
}
transaction.addRollBack([this]() noexcept {
const auto defaultRepo = getDefaultRepo(this->cfg);
auto result = updateOstreeRepoConfig(this->ostreeRepo.get(),
QString::fromStdString(defaultRepo.name),
QString::fromStdString(defaultRepo.url));
auto result = updateOstreeRepoConfig(this->ostreeRepo.get(), this->cfg);
if (!result) {
qCritical() << result.error();
Q_ASSERT(false);
Expand All @@ -825,6 +842,7 @@ utils::error::Result<void> OSTreeRepo::setConfig(const api::types::v1::RepoConfi
return LINGLONG_ERR(ret);
}

const auto newRepo = getDefaultRepo(cfg);
this->m_clientFactory.setServer(newRepo.url);
this->cfg = cfg;

Expand Down Expand Up @@ -1145,12 +1163,13 @@ void OSTreeRepo::pull(service::PackageTask &taskContext,
g_autoptr(GVariant) pull_options = g_variant_ref_sink(g_variant_builder_end(&builder));
// 这里不能使用g_main_context_push_thread_default,因为会阻塞Qt的事件循环
const auto defaultRepo = getDefaultRepo(this->cfg);
auto status = ostree_repo_pull_with_options(this->ostreeRepo.get(),
defaultRepo.name.c_str(),
pull_options,
progress,
cancellable,
&gErr);
auto status =
ostree_repo_pull_with_options(this->ostreeRepo.get(),
defaultRepo.alias.value_or(defaultRepo.name).c_str(),
pull_options,
progress,
cancellable,
&gErr);
ostree_async_progress_finish(progress);
auto shouldFallback = false;
if (status == FALSE) {
Expand Down Expand Up @@ -1188,7 +1207,7 @@ void OSTreeRepo::pull(service::PackageTask &taskContext,
g_autoptr(GVariant) pull_options = g_variant_ref_sink(g_variant_builder_end(&builder));

status = ostree_repo_pull_with_options(this->ostreeRepo.get(),
defaultRepo.name.c_str(),
defaultRepo.alias.value_or(defaultRepo.name).c_str(),
pull_options,
progress,
cancellable,
Expand Down Expand Up @@ -1225,7 +1244,7 @@ void OSTreeRepo::pull(service::PackageTask &taskContext,

item.commit = commit;
item.info = *info;
item.repo = defaultRepo.name;
item.repo = defaultRepo.alias.value_or(defaultRepo.name);

auto layerDir = this->ensureEmptyLayerDir(item.commit);
if (!layerDir) {
Expand Down

0 comments on commit 8f04db4

Please sign in to comment.