Verified Commit b0f04648 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

AkonadiControl: expose agent instances of unknown types too

When an Agent type is removed/uninstalled so that after Akonadi restart
no information are available about the type, but agentsrc still contains
references to instances of that type there was no way for the user to
find or fix the problem as AkonadiControl would silently ignore the
instances.

This change makes AkonadiControl to reconstruct a dummy AgentType and
AgentInstance and expose it via DBus as usual so that they at least
in some form show up in the UI and the user can remove the account
or it can be picked up by the automated migration agent.
parent 15a0d3a4
......@@ -5,6 +5,7 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
set(control_SRCS
agenttype.cpp
agentinstance.cpp
agentbrokeninstance.cpp
agentprocessinstance.cpp
agentthreadinstance.cpp
agentmanager.cpp
......
/*
Copyright (c) 2020 Daniel Vrátil <dvratil@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "agentbrokeninstance.h"
using namespace Akonadi;
AgentBrokenInstance::AgentBrokenInstance(const QString &type, AgentManager &manager)
: AgentInstance(manager)
{
setAgentType(type);
statusChanged(2 /* Akonadi::AgentBase::Status::Broken */, {});
onlineChanged(false);
}
bool AgentBrokenInstance::start(const AgentType &)
{
return false;
}
void AgentBrokenInstance::quit()
{
// no-op
}
void AgentBrokenInstance::cleanup()
{
// no-op
}
void AgentBrokenInstance::restartWhenIdle()
{
// no-op
}
void AgentBrokenInstance::configure(qlonglong)
{
// no-op
}
/*
Copyright (c) 2020 Daniel Vrátil <dvratil@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef AGENTBROKENINSTANCE_H
#define AGENTBROKENINSTANCE_H
#include "agentinstance.h"
namespace Akonadi
{
class ProcessControl;
class AgentBrokenInstance : public AgentInstance
{
Q_OBJECT
public:
explicit AgentBrokenInstance(const QString &type, AgentManager &manager);
~AgentBrokenInstance() override = default;
bool start(const AgentType &agentInfo) override;
void quit() override;
void cleanup() override;
void restartWhenIdle() override;
void configure(qlonglong windowId) override;
};
}
#endif
......@@ -24,6 +24,7 @@
#include "agentmanagerinternaladaptor.h"
#include "agentprocessinstance.h"
#include "agentserverinterface.h"
#include "agentbrokeninstance.h"
#include "agentthreadinstance.h"
#include "preprocessor_manager.h"
#include "processcontrol.h"
......@@ -593,12 +594,23 @@ void AgentManager::load()
file.beginGroup(entries[i]);
const QString agentType = file.value(QStringLiteral("AgentType")).toString();
if (!mAgents.contains(agentType)) {
qCWarning(AKONADICONTROL_LOG) << "Reference to unknown agent type" << agentType << "in agentsrc";
const auto typeIter = mAgents.constFind(agentType);
if (typeIter == mAgents.cend() || typeIter->exec.isEmpty()) {
qCWarning(AKONADICONTROL_LOG) << "Reference to unknown agent type" << agentType << "in agentsrc, creating a fake entry.";
if (typeIter == mAgents.cend()) {
AgentType type;
type.identifier = type.name = agentType;
mAgents.insert(type.identifier, type);
}
auto brokenInstance = AgentInstance::Ptr{new Akonadi::AgentBrokenInstance{agentType, *this}};
brokenInstance->setIdentifier(instanceIdentifier);
mAgentInstances.insert(instanceIdentifier, brokenInstance);
file.endGroup();
continue;
}
const AgentType type = mAgents.value(agentType);
const AgentType &type = *typeIter;
// recover if the db has been deleted in the meantime or got otherwise corrupted
if (!knownResources.contains(instanceIdentifier) && type.capabilities.contains(AgentType::CapabilityResource)) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment