keep frozen apps fresh
Project description
esky: keep frozen apps fresh
Esky is an auto-update framework for frozen Python applications. It provides
a simple API through which apps can find, fetch and install updates, and a
bootstrapping mechanism that keeps the app safe in the face of failed or
partial updates.
Esky is currently capable of freezing apps with py2exe, py2app, cxfreeze and
bbfreeze. Adding support for other freezer programs should be straightforward;
patches will be gratefully accepted.
The main interface is the 'Esky' class, which represents a frozen app. An Esky
must be given the path to the top-level directory of the frozen app, and a
'VersionFinder' object that it will use to search for updates. Typical usage
for an app automatically updating itself would look something like this:
if hasattr(sys,"frozen"):
app = esky.Esky(sys.executable,"http://example.com/downloads/")
app.auto_update()
A simple default VersionFinder is provided that hits a specified URL to get
a list of available versions. More sophisticated implementations will likely
be added in the future, and you're encouraged to develop a custom VersionFinder
subclass to meet your specific needs.
The real trick is freezing your app in a format sutiable for use with esky.
You'll almost certainly want to use the "bdist_esky" distutils command, and
should consult its docstring for full details; the following is an example
of a simple setup.py script using esky:
from esky import bdist_esky
from distutils.core import setup
setup(name="appname",
version="1.2.3",
scripts=["appname/script1.py","appname/gui/script2.pyw"],
options={"bdist_esky":{"includes":["mylib"]}},
)
Invoking this setup script would create an esky for "appname" version 1.2.3:
#> python setup.py bdist_esky
...
...
#> ls dist/
appname-1.2.3.linux-i686.zip
#>
The contents of this zipfile can be extracted to the filesystem to give a
fully working application. If made available online then it can also be found,
downloaded and used as an upgrade by older versions of the application.
When you find you need to move beyond the simple logic of Esky.auto_update()
(e.g. to show feedback in the GUI) then the following properties and methods
are available on the Esky class:
app.version: the current best available version.
app.active_version: the currently-executing version, or None
if the esky isn't for the current app.
app.find_update(): find the best available update, or None
if no updates are available.
app.fetch_version(v): fetch the specified version into local storage.
app.install_version(v): install and activate the specified version.
app.uninstall_version(v): (try to) uninstall the specified version; will
fail if the version is currently in use.
app.cleanup(): (try to) clean up various partly-installed
or old versions lying around the app dir.
app.reinitialize(): re-initialize internal state after changing
the installed version.
If updating an application that is not writable by normal users, esky has the
ability to gain root privileges through the use of a helper program. The
following methods control this behaviour:
app.has_root(): check whether esky currently has root privs.
app.get_root(): escalate to root privs by spawning helper app.
app.drop_root(): kill helper app and drop root privileges
When properly installed, the on-disk layout of an app managed by esky looks
like this:
prog.exe - esky bootstrapping executable
appdata/ - container for all the esky magic
appname-X.Y.platform/ - specific version of the application
prog.exe - executable(s) as produced by freezer module
library.zip - pure-python frozen modules
pythonXY.dll - python DLL
esky-files/ - esky control files
bootstrap/ - files not yet moved into bootstrapping env
bootstrap-manifest.txt - list of files expected in bootstrap env
lockfile.txt - lockfile to block removal of in-use versions
...other deps...
updates/ - work area for fetching/unpacking updates
This is also the layout of the zipfiles produced by bdist_esky. The
"appname-X.Y" directory is simply a frozen app directory with some extra
control information generated by esky.
To install a new version "appname-X.Z", esky performs the following steps:
* extract it into a temporary directory under "updates"
* move all bootstrapping files into "appname-X.Z.platm/esky/bootstrap"
* atomically rename it into the main directory as "appname-X.Z.platform"
* move contents of "appname-X.Z.platform/esky/bootstrap" into the main dir
* remove the "appname-X.Z.platform/esky/bootstrap" directory
To uninstall an existing version "appname-X.Y", esky does the following
* remove files used by only that version from the bootstrap env
* rename its "bootstrap-manifest.txt" file to "bootstrap-manifest-old.txt"
Where such facilities are provided by the operating system, this process is
performed within a filesystem transaction. Nevertheless, the esky bootstrapping
executable is able to detect and recover from a failed update should such an
unfortunate situation arise.
To clean up after failed or partial updates, applications should periodically
call the "cleanup" method on their esky. This removes uninstalled versions
and generally tries to tidy up in the main application directory.
Esky is an auto-update framework for frozen Python applications. It provides
a simple API through which apps can find, fetch and install updates, and a
bootstrapping mechanism that keeps the app safe in the face of failed or
partial updates.
Esky is currently capable of freezing apps with py2exe, py2app, cxfreeze and
bbfreeze. Adding support for other freezer programs should be straightforward;
patches will be gratefully accepted.
The main interface is the 'Esky' class, which represents a frozen app. An Esky
must be given the path to the top-level directory of the frozen app, and a
'VersionFinder' object that it will use to search for updates. Typical usage
for an app automatically updating itself would look something like this:
if hasattr(sys,"frozen"):
app = esky.Esky(sys.executable,"http://example.com/downloads/")
app.auto_update()
A simple default VersionFinder is provided that hits a specified URL to get
a list of available versions. More sophisticated implementations will likely
be added in the future, and you're encouraged to develop a custom VersionFinder
subclass to meet your specific needs.
The real trick is freezing your app in a format sutiable for use with esky.
You'll almost certainly want to use the "bdist_esky" distutils command, and
should consult its docstring for full details; the following is an example
of a simple setup.py script using esky:
from esky import bdist_esky
from distutils.core import setup
setup(name="appname",
version="1.2.3",
scripts=["appname/script1.py","appname/gui/script2.pyw"],
options={"bdist_esky":{"includes":["mylib"]}},
)
Invoking this setup script would create an esky for "appname" version 1.2.3:
#> python setup.py bdist_esky
...
...
#> ls dist/
appname-1.2.3.linux-i686.zip
#>
The contents of this zipfile can be extracted to the filesystem to give a
fully working application. If made available online then it can also be found,
downloaded and used as an upgrade by older versions of the application.
When you find you need to move beyond the simple logic of Esky.auto_update()
(e.g. to show feedback in the GUI) then the following properties and methods
are available on the Esky class:
app.version: the current best available version.
app.active_version: the currently-executing version, or None
if the esky isn't for the current app.
app.find_update(): find the best available update, or None
if no updates are available.
app.fetch_version(v): fetch the specified version into local storage.
app.install_version(v): install and activate the specified version.
app.uninstall_version(v): (try to) uninstall the specified version; will
fail if the version is currently in use.
app.cleanup(): (try to) clean up various partly-installed
or old versions lying around the app dir.
app.reinitialize(): re-initialize internal state after changing
the installed version.
If updating an application that is not writable by normal users, esky has the
ability to gain root privileges through the use of a helper program. The
following methods control this behaviour:
app.has_root(): check whether esky currently has root privs.
app.get_root(): escalate to root privs by spawning helper app.
app.drop_root(): kill helper app and drop root privileges
When properly installed, the on-disk layout of an app managed by esky looks
like this:
prog.exe - esky bootstrapping executable
appdata/ - container for all the esky magic
appname-X.Y.platform/ - specific version of the application
prog.exe - executable(s) as produced by freezer module
library.zip - pure-python frozen modules
pythonXY.dll - python DLL
esky-files/ - esky control files
bootstrap/ - files not yet moved into bootstrapping env
bootstrap-manifest.txt - list of files expected in bootstrap env
lockfile.txt - lockfile to block removal of in-use versions
...other deps...
updates/ - work area for fetching/unpacking updates
This is also the layout of the zipfiles produced by bdist_esky. The
"appname-X.Y" directory is simply a frozen app directory with some extra
control information generated by esky.
To install a new version "appname-X.Z", esky performs the following steps:
* extract it into a temporary directory under "updates"
* move all bootstrapping files into "appname-X.Z.platm/esky/bootstrap"
* atomically rename it into the main directory as "appname-X.Z.platform"
* move contents of "appname-X.Z.platform/esky/bootstrap" into the main dir
* remove the "appname-X.Z.platform/esky/bootstrap" directory
To uninstall an existing version "appname-X.Y", esky does the following
* remove files used by only that version from the bootstrap env
* rename its "bootstrap-manifest.txt" file to "bootstrap-manifest-old.txt"
Where such facilities are provided by the operating system, this process is
performed within a filesystem transaction. Nevertheless, the esky bootstrapping
executable is able to detect and recover from a failed update should such an
unfortunate situation arise.
To clean up after failed or partial updates, applications should periodically
call the "cleanup" method on their esky. This removes uninstalled versions
and generally tries to tidy up in the main application directory.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
esky-0.9.1.tar.gz
(140.9 kB
view details)
Built Distribution
esky-0.9.1.win32.exe
(352.1 kB
view details)
File details
Details for the file esky-0.9.1.tar.gz
.
File metadata
- Download URL: esky-0.9.1.tar.gz
- Upload date:
- Size: 140.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c0565720b8e6bc4ab140e69a24f43661389390b889a04147ef0616a0bb8d78e5 |
|
MD5 | 01eaebf4177e0c5440f14201876c7ff3 |
|
BLAKE2b-256 | a2d439570c0ccd989f058ba0e01012e436d549736e488cde2ee8ce7d0a8a25bf |
File details
Details for the file esky-0.9.1.win32.exe
.
File metadata
- Download URL: esky-0.9.1.win32.exe
- Upload date:
- Size: 352.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 493f835f881649ea870b525934d55fd0672945a205642ce603eeb569bff9651b |
|
MD5 | ffe4f08db1ffd6dddc6e33cb7ce05a32 |
|
BLAKE2b-256 | 55fba425f28c482df2d02b622642073e33106b71b350923eb1460360a8c9d304 |