/usr/share/gtk-doc/html/PackageKit/introduction-ideas-transactions.html is in packagekit-docs 0.8.17-4ubuntu6~gcc5.4ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>PackageKit Reference Manual: Transactions</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="index.html" title="PackageKit Reference Manual">
<link rel="up" href="concepts.html" title="Important Concepts">
<link rel="prev" href="introduction-cancellation.html" title="Cancellation">
<link rel="next" href="introduction-ideas-transactionid.html" title="Transaction IDs">
<meta name="generator" content="GTK-Doc V1.20 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="10"><tr valign="middle">
<td width="100%" align="left" class="shortcuts"></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
<td><a accesskey="u" href="concepts.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
<td><a accesskey="p" href="introduction-cancellation.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
<td><a accesskey="n" href="introduction-ideas-transactionid.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
</tr></table>
<div class="sect1">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="introduction-ideas-transactions"></a>Transactions</h2></div></div></div>
<p>
PackageKit does not ask the user questions when the transaction is running.
It also supports a fire-and-forget method invocation, which means that transactions will
have one calling method, and have many signals going back to the caller.
</p>
<p>
Each transaction is a new path on the <code class="literal">org.freedesktop.PackageKit</code>
service, and to create a path you have to call <code class="literal">CreateTransaction</code> on the base
interface which creates the new DBUS path, and returns the new path for you to connect to.
In the libpackagekit binding, <code class="literal">PkControl</code> handles the base interface,
whilst <code class="literal">PkClient</code> handles all the transaction interface stuff.
The <code class="literal">org.freedesktop.PackageKit.Transaction</code> interface can be used
on the newly created path, but only used once.
New methods require a new transaction path (i.e. another call to <code class="literal">CreateTransaction</code>)
which is synchronous and thus very fast.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-success"></a>Transaction example: Success</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-success"></a><img src="pk-transactions-success.png" align="middle">
</div>
<p>
A typical successful transaction would emit many signals such as
<code class="literal">::Progress()</code>, <code class="literal">::Package()</code> and
<code class="literal">::StatusChanged()</code>.
These are used to inform the client application of the current state,
so widgets such as icons or description text can be updated.
</p>
<p>
These different signals are needed for a few different reasons:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"><p>
<code class="literal">::StatusChanged()</code>: The global state of the
transaction, which will be useful for some GUIs.
Examples include downloading or installing, and this is designed
to be a 40,000ft view of what is happening.
</p></li>
<li class="listitem"><p>
<code class="literal">::Package()</code>: Used to either return a result
(e.g. returning results of the <code class="literal">SearchName()</code> method)
or to return progress about a _specific_ package.
For instance, when doing <code class="literal">UpdatePackages()</code>, sending
<code class="literal">::Package(downloading)</code> and then
<code class="literal">::Package(installing)</code> for each package as processed
in the transaction allows a GUI to position the cursor on the worked
on package and show the correct icon for that package.
</p></li>
<li class="listitem"><p>
<code class="literal">::ErrorCode()</code>: to show an error to the user about
the transaction, which can be cleaned up before sending
<code class="literal">::Finished()</code>.
</p></li>
<li class="listitem"><p>
<code class="literal">::Finished()</code>: to show the transaction has
finished, and others can be scheduled.
</p></li>
</ul></div>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-failure"></a>Transaction example: Failure</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-failure"></a><img src="pk-transactions-failure.png" align="middle">
</div>
<p>
This is the typical transaction failure case when there is no network available.
The user is not given the chance to requeue the transaction as it is a fatal error.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-trusted"></a>Transaction example: Trusted</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-trusted"></a><img src="pk-transactions-trusted.png" align="middle">
</div>
<p>
In this non-trivial example, a local file install is being attempted.
First the <code class="literal">InstallFile</code> is called with the <code class="literal">only_trusted</code>
flag set.
This will fail if the package does not have a valid GPG key, and ordinarily the transaction
would fail. What the client can do, e.g. using <code class="literal">libpackagekit</code>, is
to re-request the <code class="literal">InstallFile</code> with <code class="literal">non-trusted</code>.
This will use a different PolicyKit authentication, and allow the file to succeed.
</p>
<p>
So why do we bother calling <code class="literal">only_trusted</code> in the first place?
Well, the only_trusted PolicyKit role can be saved in the gnome-keyring, or could be
set to the users password as the GPG key is already only_trusted by the user.
The <code class="literal">non-trusted</code> action would likely ask for the administrator password,
and not allowed to be saved. This gives the user the benifit of installing only_trusted local
files without a password (common case) but requiring something stronger for untrusted or
unsigned files.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-auto-untrusted"></a>Transaction example: Auto Untrusted</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-auto-untrusted"></a><img src="pk-transactions-auto-untrusted.png" align="middle">
</div>
<p>
If <code class="literal">SimulateInstallPackage</code> or
<code class="literal">SimulateInstallFile</code> is used then the client
may receive a <code class="literal">INFO_UNTRUSTED</code> package.
</p>
<p>
This is used to inform the client that the action would require
the untrusted authentication type, which means the client does
not attempt to do <code class="literal">SimulateInstallPackage(only_trusted=TRUE)</code>
and only does <code class="literal">SimulateInstallPackage(only_trusted=FALSE)</code>.
This ensures the user has to only authenticate once for the
transaction as the <code class="literal">only_trusted=TRUE</code> action
may also require a password.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-sig-install"></a>Transaction example: Package signature install</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-sig-install"></a><img src="pk-transactions-sig-install.png" align="middle">
</div>
<p>
If the package is signed, and a valid GPG signature is available, then we need to ask the
user to import the key, and re-run the transaction.
This is done as three transactions, as other transactions may be queued and have a higher
priority, and to make sure that the transaction object is not reused.
</p>
<p>
Keep in mind that PackageKit can only be running one transaction at any
one time.
If we had designed the PackageKit API to block and wait for user input,
then no other transactions could be run whilst we are waiting for the user.
</p>
<p>
This is best explained using an example:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"><p>User clicks "install vmware" followed by "confirm".</p></li>
<li class="listitem"><p>User walks away from the computer and takes a nap</p></li>
<li class="listitem"><p>System upgrade is scheduled (300Mb of updates)</p></li>
</ul></div>
<p>
The vmware package is downloaded, but cannot be installed until a EULA
is agreed to.
If we pause the transaction then we never apply the updates automatically
and the computer is not kept up to date.
The user would have to wait a substantial amount of time waiting for
the updates to download when returning from his nap after clicking "I agree"
to the vmware EULA.
</p>
<p>
In the current system where transactions cannot block, the first
transaction downloads vmware, and then it finishes, and puts up a UI
for the user to click.
In the meantime the second transaction (the update) is scheduled,
downloaded and installed, and then finishes.
The user returns, clicks "okay" and a third transaction is created that
accepts the eula, and a forth that actually installs vmware.
</p>
<p>
It seems complicated, but it's essential to make sure none of the
callbacks block and stop other transactions from happening.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-download"></a>Transaction example: Download</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-download"></a><img src="pk-transactions-download.png" align="middle">
</div>
<p>
When the <code class="literal">DownloadPackages()</code> method is called on a number
of packages, then these are downloaded by the daemon into a temporary
directory.
This directory can only be written by the <code class="literal">packagekitd</code>
user (usually root) but can be read by all users.
The files are not downloaded into any specific directory, instead a
random one is created in <code class="literal">/var/cache/PackageKit/downloads</code>.
The reason for this intermediate step is that the
<code class="literal">DownloadPackages()</code> method does not take a destination
directory as the dameon is running as a different user to the user,
and in a different SELinux context.
</p>
<p>
To preserve the SELinux attributes and the correct user and group ownership
of the newly created files, the client (running in the user session) has
to copy the files from the temporary directory into the chosen destination
directory.
NOTE: this copy step is optional but recommended, as the files will remain in
the temporary directory until the daemon is times out and is restarted.
As the client does not know (intentionally) the temporary directory or the
filenames of the packages that are created, the <code class="literal">::Files()</code>
signal is emitted with the full path of the downloaded files.
It is expected the <code class="literal">package_id</code> parameter of
<code class="literal">::Files()</code> will be blank, although this is not mandated.
</p>
<p>
Multiple <code class="literal">::Files()</code> signals can be sent by the dameon,
as the download operation may be pipelined, and the client should honour
every signal by copying each file.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-set-locale"></a>Transaction example: Setting the locale</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-set-locale"></a><img src="pk-transactions-set-locale.png" align="middle">
</div>
<p>
The PackageKit backend may support native localisation, which we should support if the
translations exist.
In the prior examples the <code class="literal">SetLocale()</code> method has been left out for brevity.
If you are using the raw DBUS methods to access PackageKit, you will also need to make
a call to <code class="literal">SetLocale()</code> so the daemon knows what locale to assign the
transaction.
If you are using libpackagekit to schedule transactions, then the locale will be set
automatically in the <code class="literal">PkControl</code> GObject, and you do not need to call
<code class="literal">pk_client_set_locale()</code> manually.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="introduction-ideas-transactions-repair"></a>Transaction example: Repair</h3></div></div></div>
<div class="mediaobject" align="center">
<a name="pk-transactions-repair"></a><img src="pk-transactions-repair-required.png" align="middle">
</div>
<p>
If the package management system is damaged, a repair may be required.
This is not automatically done befor each transaction as the user
may have to verify destructive package actions or make manual changes to
configuration files.
</p>
<p>
This transaction sequence is not common and is not supported on
many backends.
It may be completely implemented in the frontend or not at all.
</p>
</div>
</div>
<div class="footer">
<hr>
Generated by GTK-Doc V1.20</div>
</body>
</html>
|