BDaemonClient: Add support for creating activation transactions

* BActivationTransaction:
  - Remove non-trivial constructor.
  - Remove package list parameters from SetTo().
  - Add AddPackageTo{Dea,A}ctivate().
* BDaemonClient:
  - Add CreateTransaction(). It creates a transaction directory and
    initializes a BActivationTransaction. Packages to de-/activate have
    to be added afterwards.
  - Add BCommitTransactionResult::FullErrorMessage().
This commit is contained in:
Ingo Weinhold 2013-04-20 21:24:28 +02:00
parent 69a53ac5b4
commit 6a1430716c
4 changed files with 142 additions and 41 deletions

View File

@ -20,20 +20,13 @@ namespace BPrivate {
class BActivationTransaction {
public:
BActivationTransaction();
BActivationTransaction(
BPackageInstallationLocation location,
int64 changeCount,
const BString& directoryName,
const BStringList& packagesToActivate,
const BStringList& packagesToDeactivate);
~BActivationTransaction();
status_t InitCheck() const;
status_t SetTo(BPackageInstallationLocation location,
int64 changeCount,
const BString& directoryName,
const BStringList& packagesToActivate,
const BStringList& packagesToDeactivate);
const BString& directoryName);
status_t InitCheck() const;
BPackageInstallationLocation Location() const;
void SetLocation(
@ -47,12 +40,14 @@ public:
const BString& directoryName);
const BStringList& PackagesToActivate() const;
void SetPackagesToActivate(
bool SetPackagesToActivate(
const BStringList& packages);
bool AddPackageToActivate(const BString& package);
const BStringList& PackagesToDeactivate() const;
void SetPackagesToDeactivate(
bool SetPackagesToDeactivate(
const BStringList& packages);
bool AddPackageToDeactivate(const BString& package);
private:
BPackageInstallationLocation fLocation;

View File

@ -16,6 +16,9 @@
#include <package/DaemonDefs.h>
class BDirectory;
namespace BPackageKit {
@ -44,6 +47,11 @@ public:
const BActivationTransaction& transaction,
BCommitTransactionResult& _result);
status_t CreateTransaction(
BPackageInstallationLocation location,
BActivationTransaction& _transaction,
BDirectory& _transactionDirectory);
private:
status_t _InitMessenger();
status_t _ExtractPackageInfoSet(const BMessage& message,
@ -81,6 +89,8 @@ public:
const BString& ErrorPackage() const;
// may be empty, even on error
BString FullErrorMessage() const;
const BString& OldStateDirectory() const;
private:

View File

@ -25,20 +25,6 @@ BActivationTransaction::BActivationTransaction()
}
BActivationTransaction::BActivationTransaction(
BPackageInstallationLocation location, int64 changeCount,
const BString& directoryName, const BStringList& packagesToActivate,
const BStringList& packagesToDeactivate)
:
fLocation(location),
fChangeCount(changeCount),
fTransactionDirectoryName(directoryName),
fPackagesToActivate(packagesToActivate),
fPackagesToDeactivate(packagesToDeactivate)
{
}
BActivationTransaction::~BActivationTransaction()
{
}
@ -57,27 +43,18 @@ BActivationTransaction::InitCheck() const
status_t
BActivationTransaction::SetTo(BPackageInstallationLocation location,
int64 changeCount, const BString& directoryName,
const BStringList& packagesToActivate,
const BStringList& packagesToDeactivate)
int64 changeCount, const BString& directoryName)
{
if (location < 0 || location >= B_PACKAGE_INSTALLATION_LOCATION_ENUM_COUNT
|| directoryName.IsEmpty()
|| (packagesToActivate.IsEmpty() && packagesToDeactivate.IsEmpty())) {
|| directoryName.IsEmpty()) {
return B_BAD_VALUE;
}
fLocation = location;
fChangeCount = changeCount;
fTransactionDirectoryName = directoryName;
fPackagesToActivate = packagesToActivate;
fPackagesToDeactivate = packagesToDeactivate;
if (fPackagesToActivate.CountStrings() != packagesToActivate.CountStrings()
|| fPackagesToDeactivate.CountStrings()
!= packagesToDeactivate.CountStrings()) {
return B_NO_MEMORY;
}
fPackagesToActivate.MakeEmpty();
fPackagesToDeactivate.MakeEmpty();
return B_OK;
}
@ -133,10 +110,18 @@ BActivationTransaction::PackagesToActivate() const
}
void
bool
BActivationTransaction::SetPackagesToActivate(const BStringList& packages)
{
fPackagesToActivate = packages;
return fPackagesToActivate.CountStrings() == packages.CountStrings();
}
bool
BActivationTransaction::AddPackageToActivate(const BString& package)
{
return fPackagesToActivate.Add(package);
}
@ -147,10 +132,18 @@ BActivationTransaction::PackagesToDeactivate() const
}
void
bool
BActivationTransaction::SetPackagesToDeactivate(const BStringList& packages)
{
fPackagesToDeactivate = packages;
return fPackagesToDeactivate.CountStrings() == packages.CountStrings();
}
bool
BActivationTransaction::AddPackageToDeactivate(const BString& package)
{
return fPackagesToDeactivate.Add(package);
}

View File

@ -9,10 +9,15 @@
#include <package/DaemonClient.h>
#include <time.h>
#include <Directory.h>
#include <Entry.h>
#include <package/InstallationLocationInfo.h>
#include <package/PackageInfo.h>
#include <package/ActivationTransaction.h>
#include <package/PackagesDirectoryDefs.h>
namespace BPackageKit {
@ -103,6 +108,60 @@ BDaemonClient::CommitTransaction(const BActivationTransaction& transaction,
}
status_t
BDaemonClient::CreateTransaction(BPackageInstallationLocation location,
BActivationTransaction& _transaction, BDirectory& _transactionDirectory)
{
// get an info for the location
BInstallationLocationInfo info;
status_t error = GetInstallationLocationInfo(location, info);
if (error != B_OK)
return error;
// open admin directory
entry_ref entryRef;
entryRef.device = info.PackagesDirectoryRef().device;
entryRef.directory = info.PackagesDirectoryRef().node;
error = entryRef.set_name(PACKAGES_DIRECTORY_ADMIN_DIRECTORY);
if (error != B_OK)
return error;
BDirectory adminDirectory;
error = adminDirectory.SetTo(&entryRef);
if (error != B_OK)
return error;
// create a transaction directory
int uniqueId = 1;
BString directoryName;
for (;; uniqueId++) {
directoryName.SetToFormat("transaction-%d", uniqueId);
if (directoryName.IsEmpty())
return B_NO_MEMORY;
error = adminDirectory.CreateDirectory(directoryName,
&_transactionDirectory);
if (error == B_OK)
break;
if (error != B_FILE_EXISTS)
return error;
}
// init the transaction
error = _transaction.SetTo(location, info.ChangeCount(), directoryName);
if (error != B_OK) {
BEntry entry;
_transactionDirectory.GetEntry(&entry);
_transactionDirectory.Unset();
if (entry.InitCheck() == B_OK)
entry.Remove();
return error;
}
return B_OK;
}
status_t
BDaemonClient::_InitMessenger()
{
@ -273,6 +332,50 @@ BDaemonClient::BCommitTransactionResult::ErrorPackage() const
}
BString
BDaemonClient::BCommitTransactionResult::FullErrorMessage() const
{
if (fError == 0)
return "no error";
const char* errorString;
if (fError > 0) {
switch ((BDaemonError)fError) {
case B_DAEMON_CHANGE_COUNT_MISMATCH:
errorString = "transaction out of date";
break;
case B_DAEMON_BAD_REQUEST:
errorString = "invalid transaction";
break;
case B_DAEMON_NO_SUCH_PACKAGE:
errorString = "no such package";
break;
case B_DAEMON_PACKAGE_ALREADY_EXISTS:
errorString = "package already exists";
break;
case B_DAEMON_OK:
default:
errorString = "unknown error";
break;
}
} else
errorString = strerror(fError);
BString result;
if (!fErrorMessage.IsEmpty()) {
result = fErrorMessage;
result << ": ";
}
result << errorString;
if (!fErrorPackage.IsEmpty())
result << ", package: \"" << fErrorPackage << '"';
return result;
}
const BString&
BDaemonClient::BCommitTransactionResult::OldStateDirectory() const
{