ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Urlader/README
Revision: 1.5
Committed: Sun Jun 17 13:11:25 2012 UTC (11 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-1_01, HEAD
Changes since 1.4: +5 -5 lines
Log Message:
1.01

File Contents

# Content
1 NAME
2 Urlader - installer-less single-file independent executables
3
4 SYNOPSIS
5 use Urlader;
6
7 DESCRIPTION
8 Urlader (that's german for "bootloader" btw.) was created out of
9 frustration over PAR always being horribly slow, again not working,
10 again not being flexible enough for simple things such as software
11 upgrades, and again causing mysterious missing file issues on various
12 platforms.
13
14 That doesn't mean this module replaces PAR, in fact, you should stay
15 with PAR for many reasons right now, user-friendlyness is one of them.
16
17 However, if you want to make single-file distributions out of your perl
18 programs (or python, or C or whatever), and you are prepared to fiddle a
19 LOT, this module might provide a faster and more versatile deployment
20 technique then PAR. Well, if it ever gets finished.
21
22 Also, *nothing in this module is considered very stable yet*, and it's
23 far from feature-complete.
24
25 Having said all that, Urlader basically provides three services:
26
27 A simple archiver that packs a directory tree into a single file.
28 A small C program that works on windows and unix, which unpacks an
29 attached archive and runs a program (perl, python, whatever...).
30 A perl module support module (*this one*), that can be used to query the
31 runtime environment, find out where to install updates and so on.
32
33 EXAMPLE
34 How can it be used to provide single-file executables?
35
36 So simple, create a directory with everything that's needed, e.g.:
37
38 # find bintree
39 bintree/perl
40 bintree/libperl.so.5.10
41 bintree/run
42 bintree/pm/Guard.pm
43 bintree/pm/auto/Guard/Guard.so
44 bintree/pm/XSLoader.pm
45 bintree/pm/DynaLoader.pm
46 bintree/pm/Config.pm
47 bintree/pm/strict.pm
48 bintree/pm/vars.pm
49 bintree/pm/warnings.pm
50
51 # cat bintree/run
52 @INC = ("pm", "."); # "." works around buggy AutoLoader
53 use Guard;
54 guard { warn "hello, world!\n" }; # just to show off
55 exit 0; # tell the urlader that everything was fine
56
57 Then pack it:
58
59 # wget http://urlader.schmorp.de/prebuilt/1.0/linux-x86
60 # urlader-util --urlader linux-x86 --pack myprog ver1_000 bintree \
61 LD_LIBRARY_PATH=. ./perl run \
62 >myprog
63 # chmod 755 myprog
64
65 The packing step takes a binary loader and appends all the files in the
66 directory tree, plus some meta information.
67
68 The resulting file is an executable that, when run, will unpack all the
69 files and run the embedded program.
70
71 CONCEPTS
72 urlader
73 A small (hopefully) and relatively portable (hopefully) binary that
74 is prepended to a pack file to make it executable.
75
76 You can build it yourself from sources (see prebuilt/Makefile in the
77 distribution) or use one of the precompiled ones at:
78
79 http://urlader.schmorp.de/prebuilt/1.0/
80
81 The README there has further information on the binaries provided.
82
83 exe_id
84 A string that uniquely identifies your program - all branches of it.
85 It must consist of the characters "A-Za-z0-9_-" only and should be a
86 valid directory name on all systems you want to deploy on.
87
88 exe_ver
89 A string the uniquely identifies the contents of the archive, i.e.
90 the version. It has the same restrictions as the "exe_id", and
91 should be fixed-length, as Urlader assumes lexicographically higher
92 versions are newer, and thus preferable.
93
94 pack file (archive)
95 This contains the "exe_id", the "exe_ver", a number of environment
96 variable assignments, the program name to execute, the initial
97 arguments it receives, and finally, a list of files (with contents
98 :) and directories.
99
100 override
101 When the urlader starts, it first finds out what "exe_id" is
102 embedded in it. It then looks for an override file for this id
103 ($URLADER_EXE_DIR/override) and verifies that it is for the same
104 "exe_id", and the version is newer. If this is the case, then it
105 will unpack and run the override file instead of unpacking the files
106 attched to itself.
107
108 This way one can implement software upgrades - download a new
109 executable, write it safely to disk and move it to the override
110 path.
111
112 ENVIRONMENT VARIABLES
113 The urlader sets and maintains the following environment variables, in
114 addition to any variables specified on the commandline. The values in
115 parentheses are typical (but not gauranteed) values for unix - on
116 windows, ~/.urlader is replaced by %AppData%/urlader.
117
118 URLADER_VERSION (1.0)
119 Set to the version of the urlader binary itself. All versions with
120 the same major number should be compatible to older versions with
121 the same major number.
122
123 URLADER_DATADIR (~/.urlader)
124 The data directory used to store whatever urlader needs to store.
125
126 URLADER_CURRDIR
127 This is set to the full path of the current working directory where
128 the urlader was started. Atfer unpacking, the urlader changes to the
129 "URLADER_EXECDIR", so any relative paths should be resolved via this
130 path.
131
132 URLADER_EXEPATH
133 This is set to the path of the urlader executable itself, usually
134 relative to $URLADER_CURRDIR.
135
136 URLADER_EXE_ID
137 This stores the executable id of the pack file attached to the
138 urlader.
139
140 URLADER_EXE_VER
141 This is the executable version of the pack file attached to the
142 urlader, or the override, whichever was newer. Or in other words,
143 this is the version of the application running at the moment.
144
145 URLADER_EXE_DIR (~/.urlader/$URLADER_EXE_ID>
146 The directory where urlader stores files related to the executable
147 with the given id.
148
149 URLADER_EXECDIR (~/.urlader/$URLADER_EXE_ID/i-$URLADER_EXE_VER)
150 The directory where the files from the pack file are unpacked and
151 the program is being run. Also the working directory of the program
152 when it is run.
153
154 URLADER_OVERRIDE (empty or override)
155 The override file used, if any, relative to $URLADER_EXECDIR. This
156 is either missing, when no override was used, or the string
157 override, as thta is currently the only override file urlader is
158 looking for.
159
160 FUNCTIONS AND VARIABLES IN THIS MODULE
161 $Urlader::URLADER_VERSION
162 Set to the urlader version ("URLADER_VERSION") when the program is
163 running form within urlader, undef otherwise.
164
165 $Urlader::DATADIR, $Urlader::EXE_ID, $Urlader::EXE_VER,
166 $Urlader::EXE_DIR, $Urlader::EXECDIR
167 Contain the same value as the environment variable of the (almost)
168 same name. You should prefer these, though, as these might even be
169 set to correct values when not running form within an urlader
170 environment.
171
172 Urlader::set_exe_info $exe_id, $exe_ver
173 Sets up the paths and variables as if running the given executable
174 and version from within urlader.
175
176 $lock = Urlader::lock $path, $exclusive, $wait
177 Tries to acquire a lock on the given path (which must specify a file
178 which will be created if necessary). If $exclusive is true, then it
179 tries to acquire an exclusive lock, otherwise the lock will be
180 shared. If $wait is true, then it will wait until the lock can be
181 acquired, otherwise it only attempts to acquire it and returns
182 immediately if it can't.
183
184 If successful it returns a lock object - the lock will be given up
185 when the lock object is destroyed or when the process exits (even on
186 a crash) and has a good chance of working on network drives as well.
187
188 If the lock could not be acquired, "undef" is returned.
189
190 This function is provided to assist applications that want to clean
191 up old versions, see "TIPS AND TRICKS", below.
192
193 TIPS AND TRICKS
194 Gathering files
195 Gathering all the files needed for distribution can be a big
196 problem. Right now, Urlader does not assist you in this task in any
197 way, however, just like perl source stripping, it is planned to
198 unbundle the relevant technology from staticperl
199 (<http://staticperl.plan9.de>) for use with this module.
200
201 You could always use par to find all library files, unpack the
202 bundle and add perl, libperl and other support libraries (e.g.
203 libgcc_s).
204
205 Software update
206 Updating the software can be done by downloading a new packfile
207 (with the same "exe_id" but a higher "exe_ver" - this can simply be
208 the executable you create when making a release) and replacing the
209 override file in the $URLADER_EXE_DIR.
210
211 When looking for updates, you should include $URLADER_VERSION,
212 $URLADER_EXE_ID and $URLADER_EXE_VER - the first two must be
213 identical for update and currently running program, while the last
214 one should be lexicographically higher.
215
216 Replacing the override file can be done like this:
217
218 rename "new-override.tmp", "$Urlader::EXE_DIR/override"
219 or die "could not replace override";
220
221 This can fail on windows when another urlader currently reads it,
222 but should work on all platforms even when other urlader programs
223 execute concurrently.
224
225 Cleaning up old directories
226 Urlader only packs executables once and then caches them in the
227 $URLADER_EXECDIR. After upgrades there will be old versions in there
228 that are not being used anymore. Or are they?
229
230 Each instance directory (i-*) in the $URLADER_EXE_DIR) has an
231 associated lock file (i-*.lck) - while urlader executes an app it
232 keeps a shared lock on this file.
233
234 To detect whether a version is in use or not, you must try to
235 acquire an exclusive lock, i.e.:
236
237 my $lock = Urlader::lock "~/.urlader/myexe/i-ver01.lck", 1, 0;
238 if (!$lock) {
239 # instance dir is not in use and can be safely deleted
240 }
241
242 If an older urlader wants to use an instance that was deleted or is
243 currently being deleted it will wait until it's gone and simply
244 recreate it, so while less efficient, deleting instance directories
245 should always be safe.
246
247 The lockfile itself can be deleted as long as you have an exclusive
248 lock on it (if your platform allows this).
249
250 A real world project
251 The only real world project using this that I know of at the moment
252 is the deliantra client (http://www.deliantra.net for more info).
253
254 It uses some scary scripts to build the client and some dependnet
255 modules (build.*), to gather perl source files into a distribution
256 tree, shared objects and system shared libraries (some of which have
257 to be patched or, due to the horrible dll hell on OS X, even
258 renamed), called "gatherer", and a script called "gendist" to build
259 executable distributions.
260
261 These can be found at
262 <http://cvs.schmorp.de/deliantra/Deliantra-Client/util/>, but
263 looking at them can lead to premature blindless.
264
265 Shared Libraries
266 It is often desirable to package shared libraries - for example the
267 Deliantra client packages SD>, Berkely DB, Pango and amny other
268 libraries that are unlikely to be available on the target system.
269
270 This usually requires some fiddling (see below), and additionally
271 some environment variables to be set.
272
273 For example, on ELF systems you usually want LD_LIBRARY_PATH=. and
274 on OS X, you want DYLD_LIBRARY_PATH=. (these are effectively the
275 default on windows).
276
277 These can most easily be specified when building the packfile:
278
279 urlader-util ... LD_LIBRARY_PATH=. ./perl run
280
281 Portability: RPATH
282 Often perl is linked against a shared libperl.so - and might be so
283 using an rpath. Perl extensikns likewise might use an rpath, which
284 means the binary will mostly ignore LD_LIBRARY_PATH, which leads to
285 trouble.
286
287 There is an utility called chrpath, whose -d option can remove the
288 rpath from binaries, shared library and shared objects.
289
290 Portability: OS X DLL HELL
291 OS X has the most severe form of DLL hell I have seen - if you link
292 against system libraries, which is practically unavoidable, you get
293 libraries of well-known names (e.g. libjpeg) that have nothing to do
294 with what you normally expect libjpeg to be, and there is no way to
295 get your version of libjpeg into your program.
296
297 Moreover, even if apple ships well-known libraries (e.g. libiconv),
298 they often ship patched versions which have a different ABI or even
299 API then the real releases.
300
301 The only way aorund this I found was to change all library names in
302 my releases (libjpeg.dylib becomes libdeliantra-jpeg.dylin and so
303 on), by patching the paths in the share dlibraries and shared
304 objects. install-name-tool (with -id and -change) works in many
305 cases, but often paths are embedded indirectly, so you might have to
306 use a *dirty* string replacement.
307
308 SECURITY CONSIDERATIONS
309 The urlader executable itself does not support setuig/setgid operation,
310 or running with elevated privileges - it does no input sanitisation, and
311 is trivially exploitable.
312
313 AUTHOR
314 Marc Lehmann <schmorp@schmorp.de>
315 http://home.schmorp.de/
316