lua_funcs.txt 13.8 KB
Newer Older
1 2 3 4 5
Lua injections
==============

We inject several functions into the lua global environment. Since
there's no good place to document them (like .h files for C code),
6
they are listed here.
7 8 9 10

Logging
-------

11
log(level, depth, msg, msg, msg, ...)::
12 13 14 15 16 17 18
  This is a low-level function used for logging. It should not be used
  directly by lua code. The messages are just strings that are
  concatenated together before outputting. The level is one of:
  - DIE
  - ERROR
  - WARN
  - DBG
Karel Koci's avatar
Karel Koci committed
19
  - TRACE
20 21 22 23
  The depth argument specifies how many functions on the top of the stack
  are to be disregarded when printing the source file, line number and
  function name to the logs. 0 means the function directly calling log,
  1 is its caller, etc.
24 25 26
ERROR(msg, msg, ...)::
WARN(msg, msg, ...)::
DBG(msg, msg, ...)::
Karel Koci's avatar
Karel Koci committed
27
TRACE(msg, msg, ...)::
28 29 30 31 32
  These output a message to the logs with a given level. The messages
  are concatenated together.
DIE(msg, msg, ...)::
  In addition to outputting the message on the ``DIE`` level, it also
  terminates the application with error exit code.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
update_state(state)::
  Dump the message for given state into `/tmp/update-state/state`.
  Allowed states are as follow:
  - `LS_INIT`: Initial state (`initialize`)
  - `LS_CONF`: Running configuration scripts (`configuration`)
  - `LS_PLAN`: Generating plan (`planning`)
  - `LS_DOWN`: Downloading needed packages (`downloading`)
  - `LS_PREUPD`: Running updater's preupdate hooks (`preupdate-hooks`)
  - `LS_UNPACK`: Unpacking downloaded packages (`unpacking`)
  - `LS_CHECK`: Checking for files collisions and more (`checking`)
  - `LS_INST`: Running preinst scripts and merging files to filesystem (`install`)
  - `LS_POST`: Running postinst scripts (`post-install`)
  - `LS_REM`: Removing leftover files (`removals`)
  - `LS_CLEANUP`: Cleaning up control files (`cleanup`)
  - `LS_POSTUPD`: Running updater's postupdate hooks (`postupdate-hooks`)
  - `LS_EXIT`: Updater exit (`exit`)
  - `LS_FAIL`: Detected failure, exiting. (`failure`)
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
Cleanup
-------

It's common to have code that requires cleanup. But ensuring that cleanup is
really called is tedious task. But thanks to atexit function and common DIE
function we can ensure that cleanup functions will be called. We defined function
to register, unregister and call cleanup function.

cleanup_register(function)::
  This registers given function as to be called when cleanup is requested.

cleanup_unregister(function)::
  This removes previously registered function from list of functions to be called
  for cleanup. This is done without calling given function.

cleanup_run(function)::
  This runs previously registered function and removes it from list of functions
  to be called for cleanup.

Note: This is for simplicity not implemented completely in C but lua functions
handlers is implemented in Lua it self. But we can't have that completely detached
as we have to ensure that order of cleanup holds even if Lua and C calls are mixed
together.

Following functions are defined for internal use of cleanup functionality only.
But they are not documented outside of the code usage so here they are:

cleanup_register_handle(index)::
  This function registers new cleanup for Lua. It expect index identifying this
  cleanup in global table of cleanup functions. It is used to register lua cleanup
  function handle to C cleanups. Exact Lua function is stored in Lua table and
  only index identifying given cleanup is passed to C.

cleanup_unregister_handle(index)::
  This function unregisters existing cleanup for Lua. It expect index identifying
  this cleanup in global table of cleanup functions. It reverse function or
  `cleanup_register_handle`.

89 90 91
Subprocesses
------------

92
Family of functions `subproc*` defined in `subprocess.h` are exported to lua
93
in form of functions `subprocess`.
94 95

Function `subprocess` is defined as follows:
96
`subprocess(type, message, timeout, callback, command ...)`
97

98
* `type` is identification used to specify what type of subprocess it's. Allowed
99
  predefined constants are as follows:
100 101
  - `LST_PKG_SCRIPT` Any script provided by package (pre/post inst/rm)
  - `LST_HOOK` Hook script executed on some updater state
102

103
* `message` is string describing what this subprocess is to user. It's human
104 105
  readable description of executed command.

106
* `timeout` is time in seconds after which subprocess will be automatically
107 108
  killed.

109 110 111 112
* `callback` is optional function that would be called in subprocess just before
  It executes given command. If you don't want to specify it then you can pass nil
  Or you can just drop it out (in that case command is expeted on this argument
  Place). This functions should has no arguments and shouldn't return anything.
113

114
* `command` is any arbitrary number of string arguments that are passed as command
115 116 117 118 119 120
  and its additional arguments.

This function returns exit code of executed subprocess as first argument. And
output of this process as second argument. (Output includes both stdout and
stderr).

121 122 123 124
Note::
  There is some problem with printing from lua to stdout in callback on some
  platforms.

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
Asynchronous events
-------------------

Some of the functions from ``events.h`` are exposed to lua code, with
minor modifications.

Currently, it is possible to run external commands with the
`run_command` function. The code would look like this:

  function terminated(exit_code, killed, stdout, stderr)
    -- The command terminated
  end

  function postfork()
    -- Run after fork in the child ‒ set up the environment
  end

  local id = run_command(terminated, postfork, input, term_timeout, kill_timeout, command, param, param)

  events_wait(id)

The functionality is very similar to the C functions, with these
differences:

* It doesn't take the `events` parameter, one global `events`
  structure per interpreter is used.
* The callbacks don't take the `data` or `wait_id` parameters, since
  lua has closures and passing information into the callbacks is easy.
* Lua naturally supports strings with embedded zero bytes, therefore
  there are no lengths of the inputs or outputs.
* The `exit_code` in the callback is not the raw integer from the
  system call, but decoded to the exit code of the process or signal
  number that terminated it.
* `killed` is a string, one of:
  - `TERMINATED`
  - `TERMED`
  - `KILLED`
  - `SIGNAL_OTHER`
* The events_wait take any number of ip parameters instead of an
  array.

The `postfork` and `input` parameters may be nil. The `term_timeout`
and `kill_timeout` take -1 to mean no timeout.

There may be any number of the `param` parameters, which are passed to
the command.

Currently, there's no way to cancel running command from lua, since
that would make the wrapper code needlessly complex (while there seems
to be no need to cancel them currently).
175

176 177 178 179 180 181 182
For calling standard shell utility, or in fact every busybox function,
`run_util` is provided. It is same as `run_command` except it accepts
as `command` parameter one of supported busybox function names. So you
pass for example `rm` instead of `/bin/rm`. This is preferred way of
calling them, because when busybox is embedded then we don't rely on
system utilities and so it should be more reliable.

183 184 185 186 187 188 189 190 191 192
The other event is `download`:

  function callback(status, content)
    if status == 200 then
      print("Downloaded: " .. content)
    else
      print("Download failed (" .. content .. ")")
    end
  end

193
  local id = download(callback, "https://example.org/file", "/path/to/cert", "/path/to/crl", true)
194 195 196 197 198 199

  events_wait(id)

The example is mostly self-explanatory and again, this acts very
similar to the C version.

200 201 202 203 204 205 206 207
Filesystem manipulation
-----------------------

mkdtemp([directory])::
  It creates a temporary directory. If directory is provided, it is
  created as a subdirectory of the given directory, otherwise it is
  created inside `/tmp`. It returns path to the new directory, or
  `nil` and an error message.
208 209 210 211 212 213

chdir(directory)::
  Change the current working directory to the one provided.

getcwd()::
  Get the current working directory.
214 215 216 217 218 219 220

mkdir(directory)::
  Create a directory. All the parent directories must already exist.
  The directory itself shall not exist. It throws on error.

move(old, new)::
  Move a file from the old location to the new. It tries to cope with
221
  paths on different devices.
222 223

ls(directory)::
224 225 226 227 228 229 230 231 232 233 234
  Return a table with file names under the given directory (acts like
  shell's `ls -a`, omitting the `.` and `..` entries). Value of
  each is the type of the file there, which may be:
  b;; A block device
  c;; A character device
  d;; A directory
  f;; A named pipe
  l;; A symbolic link
  r;; A regular file
  s;; A unix-domain socket
  ?;; Failed to determine the type
235

236
stat(path)::
237 238 239
  Statistics about the given file. If the file does not exist, it
  returns nothing. Otherwise, the file type is returned (see the types
  of `ls`). The second result is the permissions of the file, in the
240 241 242 243
  imitation of shell's `ls -l`, like `rwxr-x---`.

lstat(path)::
  Same as `stat` except the `lstat` behaviour is preferred.
244 245
  (eg. provides info about symbolic link if it is a link, instead of
  the target).
246

247 248 249 250
sync()::
  Writes everything to a permanent storage (equivalent to the shell's
  `sync` command).

Michal 'vorner' Vaner's avatar
Michal 'vorner' Vaner committed
251 252 253 254 255 256 257
locks.acquire(path)::
  Lock a file with the `lockf` call. Fail if the lock is already held
  by other process. Create the file as needed. Return a lock object as
  a result. It has release() method, to release the lock. The lock is
  also released when the object is garbage collected, but there's no
  guarantee how soon it may be.

258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
Journal manipulation
--------------------

All the journal manipulation is located in the `journal` module. This
is about the lua interface. For the on-disk format, look at the
`journal` document.

The location of the journal can be set by the `path` variable inside
the module (it exists mostly for testing purposes).

There are several constants for the journal record types:

 `START`:: Automatically inserted at the beginning of journal.
 `FINISH`:: Automatically inserted when the journal is closed.
 `UNPACKED`:: Packages are unpacked and ready to be installed.
 `CHECKED`:: Pre-installation checks (like collision checks) are
   successfully performed.
 `MOVED`:: The files are moved into place.
 `SCRIPTS`:: All the post/pre-* scripts were run.
 `CLEANED`:: Cleanup of temporary files is successful.

There are following functions:

  fresh():: Open a new journal. It fails if there's a journal file
    already.
  recover():: Open a previous journal. It returns table with the
284
    content of the journal. If there is no journal nil is returned.
285 286 287 288 289 290 291 292 293 294 295 296 297 298
  finish([keep]):: Close the journal. If the keep is set to true,
    it keeps the journal in place, otherwise it is deleted. The idea
    is that the application would close the journal when it succeeds,
    but would leave it there in case of interrupted operation, so
    usually nothing is set, the flag is for testing purposes.
  write(type, ...):: Write a journal record of the given type (see
    above). Any other parameters are stored as parameters. Data
    structures must not contain meta tables and functions.
  opened():: Returns if the journal is opened. This is for testing
    purposes.

The format of journal returned by recover is a table with records.
Each record contains `type` ‒ one of the types above, and `params` ‒
table with all the parameters stored with the record.
299

300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
Pisocat
-------

Picosat can be used trough module `picosat`. Here is briefly described
its interface as it can be used from Lua. For more information about
usage see Picosat documentation in its source file.

You can create picosat instance by calling `picosat.new` function.
It returns object with following methods:

  var(count):: Creates given number of new variables and returns them.
    If no argument is given, it returns one new variable.
  clause(var, ...):: Adds clause. Arguments `var` are variables
    previously created with `var` method. Appending minus before variable
    adds boolean negation.
  assume(var):: Adds assumption about value `val` for next satisfiable
    check. Appending minus before `var` assumes false, not appending it
    assumes true.
  satisfiable():: Checks if clauses are satisfiable with given
    assumptions. Returns true or false accordingly.
  max_satisfiable():: Generates maximal satisfiable subset of assumptions.
321 322 323
    Can be called only after `satisfiable`. Returns set of all assumptions
    that can be assumed at the same time. Note that this reassumes previous
    assumptions, so they are again valid for next `satisfiable` call.
324 325 326 327 328 329

After calling `satisfiable` you can access assigned values by indexing
object with variable you are interested in. It returns true or false.
It can also return nil if variable was added after `satisfiable` method
call.

330 331 332 333 334 335 336 337 338 339 340 341
Others
------

There are some other functions.

DataDumper(variable)::
  A function that converts (almost any) variable to a string
  containing a lua chunk. The chunk, when run, returns equivalent
  value as passed. Simply stated, this serializes data into lua code.
  It is a third-party code from
  `http://lua-users.org/wiki/DataDumper`. Note that some data
  (userdata, for example) can't be represented this way.
342 343 344 345

setenv(name, value)::
  Set the environment variable with the given name to the given value.
  Errors in case of failure, otherwise returns nothing.
346

347
reexec(args,...)::
348 349 350
  Try to run the program from the beginning, preserving the command
  line arguments and working directory. It depends on being set up
  properly at the start of the program.
351 352
  As arguments you can specify additional arguments that will be appended
  at the end of original ones.
353 354 355 356 357

uri_internal_get(name)::
  Function to access embedded files using `internal:` uri. Argument `name`
  is name of requested embedded file. Returns file content. If there is
  no file under given name, error is raised.
358 359 360 361

system_reboot(stick)::
  Reboots system. Argument `stick` if set to true results in that this
  newer returns.
362 363 364

get_updater_version()::
  Returns string containing updater's version.