The Lua OS Manual (v. 0.13)

Written by Stefan Reich, Nov 12 2011.
Version covered: Lua OS 0.13
Lua OS homepage: LuaOS.net
Online version: LuaOS.net/docs/manual.php
Author contact: webmaster@LuaOS.net

Table of contents

1. What is Lua OS?

1.1. About Lua OS

Lua OS is an operating system for IBM PC-compatible computers.

Lua OS consists of two parts:

Lua OS's legacy area is based on Debian Linux (Knoppix 6.4, to be precise).

Thanks go to Klaus Knopper for creating Knoppix. However, Klaus: You should replace your forum moderator (on knoppix.net) who makes your forum almost unusable.

1.2. Hardware requirements

1.3. Multi-user support

1.3.1. Live-CD

The Lua OS Live-CD is supposed to run in a single-user mode. Technically, two users are known to the system: "knoppix", the main user; and "root", the super user. The system logs in to user "knoppix" automatically. For administrative purposes, you can switch to "root" by typing "su" in a terminal, or by using "sudo". Many tasks switch to root automatically if necessary. No password is required to become "root".

1.3.2. Installed

Lua OS can be installed to disk in two modes: single-user or multi-user. You will ask for the mode you want when running the installer.

In single-user mode, the installed Lua OS operates exactly like the Lua OS Live-CD.

During installation in multi-user mode, you will be asked for details about the main user you'd like to create. In this mode, Lua OS will not log you in automatically after booting, but present a log in prompt. Also, you will be in text mode after logging in.

In multi-user mode, type startx to switch to the graphical environment.

1.4. Language selection

Currently, there is a single switch to change both keyboard layout and the language of system messages etc.

Lua OS may start in German or English mode by default, depending on where it is shipped. We'll hand out a heap of German Live-CDs on local campuses. Lua OS images on the web are usually English.

Whatever version you got: You can choose your language when booting Lua OS. The Live-CD will offer you a menu: type "en" for English or "de" for German.

When Lua OS is already installed, switching the language is a little more difficult. You can edit the command line when booting. Or edit menu.lst and rewrite grub. We'll quite certainly offer a tool for this in the future.

2. How to do all the stuff you want to do with an operating system

It follows: A loose collection of keywords, applications and so on.

2.1. Debian software

All Debian packages should be installable in Lua OS over the usual means (apt-get).

If, for any software, there is a choice of a KDE or GNOME version: Choose GNOME - because GNOME is already installed in Lua OS.

2.2. Flash player (for YouTube etc.)

The Flash plugin is already installed in the Lua OS default web browser (Iceweasel), so you can access YouTube right away. And xhamster.com. And everything else you love.

2.3. VirtualBox

To install VirtualBox, open a terminal and type:

sudo apt-get install virtualbox-ose

Yeah, that's all. You'll find VirtualBox in the start menu afterwards.

It appears that the version of VirtualBox you will receive is not the latest one, but a bit older. (They'll update the Debian package in a while I assume.) That version of VirtualBox works fine for me anyway - I use it to master Lua OS CDs.

2.4. VLC (video+audio player)

Lua OS comes with VLC preinstalled. As far as we know, VLC plays everything.

If, in a future version, VLC is not there, just type:

sudo apt-get install vlc

(in a terminal).

2.5. Audio player

There are many audio players for Linux. We recommend Exaile which is said to be similar to Amarok which is a popular player for KDE. To install Exaile, type:

sudo apt-get install exaile

2.6. Firefox

...is called Iceweasel in Lua OS (in case you looked for a "Firefox" in vain).

Why? Ask Klaus Knopper, he came up with that. :]

2.7. BitTorrent (Transmission)

Transmission works really well for all your BitTorrent needs:
sudo apt-get install transmission

2.8. Double-clicking

Just a little hint: You should be a little careful with the mouse button in Lua OS - if you're coming from the Windows world. Often, things require just a single click. Icons in the file manager are an example. One click and they launch. Double-clicking can make them launch twice. Yeah, it's a little stupid. Computers are like that. We could and probably should improve that in the future.

Oh, and sometimes, my touch pad doesn't respond to double-tapping. I have to use the actual button. Don't know if that is specific to my notebook or a general thing.

2.9. Suspend to disk

If you run Windows in parallel to Lua OS: Don't use "Suspend to disk" and then start Lua OS. It tends to fucks up your partitions. Unfortunately it's something that cannot easily be fixed either (every Linux has this problem).

"Suspend to disk" in Lua OS could theoretically be enabled; the function is still considered experimental in Linux though. And frankly, I haven't gotten it to work yet around here. Drop me a note if you have some ideas on how to do this.

2.10. Fonts, installing them

I don't know if there is an easier way, but what I did for this is copy the .ttf file to /usr/share/fonts/truetype (on the terminal, as root). After that, the font was usable in GIMP.

2.11. OpenOffice / LibreOffice

Unfortunately, "apt-get install libreoffice" didn't work for me (with an older version of Lua OS anyway, should test this with 0.13).

However, manual installation worked. I downloaded the version for Debian systems from libreoffice.org and followed the instructions. (Unpacking the archive and running dpkg twice.)

Also, downloading the Debian package from openoffice.org and installing all the files with "dpkg -i *.deb */*.deb" worked too.

2.12. Printing

To keep the Lua OS CD small, I removed printing support from it. But it can be added again.

To do this, run "sudo apt-get install cups" (CUPS is the Unix printing system).

Then, go to start menu, Preferences, Printer settings. The CUPS page will open in Iceweasel.

Click "Add printer". Log in as root. To do this, root needs a password. I had to set that manually (su, then passwd). Yeah, we'll improve this in the next release. Now I could select my printer (Brother HL-2030). One last hurdle: There was a choice of different implementations. The first one (CUPS) did not work. The second one (Foomatic) worked. Linux is funny like that sometimes. But now I have the printed page in my hands. Printed from Lua OS!

2.13. IUP (GUI library for Lua)

This is a nice and useful GUI library for Lua. I installed it in Lua OS like this:

  1. Download iup-3.5_Linux26_lib.tar.gz
  2. Unpack in a temp directory
  3. Go to that directory in the terminal
  4. sudo ./install
  5. sudo ./config_lua_module
  6. sudo apt-get install libmotif4
  7. sudo ln -s /usr/lib/libXm.so.4 /usr/lib/libXm.so.3

That was all. It seems to work, although iup.Message produces a mysteriously unclosable dialog box. iup.Alarm works fine though. Some further testing might be appropriate.

2.14. Audio editor/convertor (Audacity)

sudo apt-get install audacity

Seems to work great. OGG export works fine.

MP3 export does not work yet, on my box anyway. It asks for libmp3lame.so.0 but apt-get does not seem to want to install libmp3lame0 for some reason.

3. Lua OS Next-Gen

To be written.

4. Safe Lua

4.1. About Safe Lua

Safe Lua, the language used to program for Lua OS, is a variant of Lua.

This document describes Lua OS / Safe Lua 0.13.

4.2. Concepts: Sandboxes and cages

Lua OS nests programs in two levels. The outermost structure is called a cage. Currently, only one cage exists in a system. Support for multiple cages is planned for later releases. (This will then also enable physical multitasking.)

Within every cage, there are a number of sandboxes. Each sandbox

4.3. Cage definition syntax

A cage is defined by a fragment of Lua code (basically just a table). In order to parse the definition, the code is run in a sandbox with no powers, yielding a table. (The result of this is called a cage definition in 'table form'.)

A cage definition looks like this:

    Cage {
      Sandbox {
        code = [[
          print "Endless loops are not scary!"
          while true do end
        ]]
      },
      Sandbox {
        script = "myscript.slua",
        pdata = "somedata",
        softtimeout = 100000
      },
      Sandbox {
        script = "mycagemanager.slua",
        magic = {"socket", "cageManagement"},
        system = true
      }
      timeout = 1000000 -- cage-wide time limit for all sandboxes
    }

(The keywords Cage and Sandbox are just syntactic sugar.)

Here's what the various fields mean:

timeout and softtimeout may appear both on the sandbox and on the cage level (sandbox level takes precedence, although we might change that).

4.4. Safe Lua Syntax

Safe Lua's syntax is identical to Lua's syntax.

4.5. Safe Lua API

Some parts of the standard Lua API are also present in Safe Lua. Additionally, there is a new set of functions and objects.

4.6. Definition: Persistable data

The term 'persistable data' refers to types of data that can be persisted to disk.

Persistable data is:

4.7. Definition: Exchangeable data

'Exchangeable data' is data that can be passed as arguments and return values in cross-sandbox method/function calls.

Exchangeable data is:

An object is distinguished from a table by the presence of a metatable. When crossing a sandbox barrier, tables are copied and objects are transformed into a reference to the object. (The object itself remains in the original sandbox.)

To create an object, the function object() is provided which creates an empty table with an empty metatable.

4.8. Lua Standard API

The following global Lua variables are currently accessible in Safe Lua:

  print
  error
  string
  tostring
  table
  ipairs
  pairs
  type
  tonumber
  rawget
  pcall (reimplemented to uphold Lua OS security requirements)
  require (this is experimental and only works with the parameter 'lib_util')

We expect to have a proper security audit at some point and then make a qualified decision about which parts of the Lua library we deem safe.

4.9. Safe Lua Extended API

For the following, keep in mind that Safe Lua code always runs in a sandbox. By default, a sandbox has limited power, but they can be extended by explicitly asking for additional powers.

4.9.1. Utility functions

tostr(data)
Converts data to a string and returns the string. Prints tables nicely. Can be used to convert exchangeable data to executable Lua code.
dump(data)
Converts data to a string (using tostr) and prints it.
include(script)
Includes another script (relative to the current dir, which is a very foggy notion at this point). This will have to be defined more properly in a future version.
object()
Returns a new object (an empty table with an empty metatable). Preferrable to {} because the resulting structure will be recognized as an object by safecomm. (A Lua table without a metatable will not be regarded an object by safecomm.)
breathe()
Yields control to allow other sandboxes to do things, but returns to execution of this sandbox as soon as possible (call this every now and then when you do long-running calculations to keep cooperative multitasking smooth & afloat)
elems(list)
Iterator on all items in a list. Use like this: for elem in elems(list) do...
use(powers)
A shorthand for safelua.requestExtension(). powers is a string with the names of all powers you'd like to request, e.g. "socket json io". Each power object will be assigned to a global variable of the same name. If one of the powers is not available, an error is produced and the script is halted. So the call
  use("socket json io")
is equivalent to:
  socket = safelua.requestExtension("socket")
  json = safelua.requestExtension("json")
  io = safelua.requestExtension("io")

4.9.2. Global variables

_pdata
Contains the contents of the field pdata (persistence data) given in the sandbox definition - or nil if no persistence data is available.

4.9.3. safelua

This globally accessible object provides the following functions.

safelua.requestExtension(name)
Requests a 'magic power' from the OS. The power is identified by name (a string). If the wish is granted, an object is returned providing the desired abilities. If it is denied, an error is thrown. (Currently, errors can not be caught in Safe Lua, but we will change that in a future release.)

Currently defined superpowers are: "socket" and "cageManagement".
safelua.onShutdown(f)
Registers a shutdown handler for this sandbox (a function with no arguments). The shutdown handler is called prior to shutting down the sandbox. Usually, this is only necessary for sandboxes with extended powers (those that hold references to sockets or other system resources). Most sandboxes don't need that as they will stay in the 'safe' (unextended) realm.
safelua.exit()
Exit from the current sandbox (stop the script)
safelua.yield()
Pause execution of this script for a moment and allow other scripts to do some work. If you are doing long-running computations, this method should be called at strategic points. If your script is event-based, you usually won't need it though.

The semantics of safelua.yield() are still a bit under discussion. The question is when script execution is resumed. A script may want to perform more computation as soon as possible; or only resume when there is any event (from the message system or an external resource).

Currently, safelua.yield() assumes that you have more work to do and are just taking a breath to avoid blocking the system or hitting a soft timeout (a timeout on the length of computations between yields).
safelua.setPersistenceHandler(handler)
Enables persistence for this sandbox.

A persistence handler is a zero-argument function returning some exchangeable data. (Returning nil is OK too.) A sandbox is considered persistable if and only if a persistence handler is defined, so if you want persistence, it is crucial to define a persistence handler even if you have no data to be persisted.

When recreating the sandbox later (on the same machine or another one), the persisted data is returned to the script in the global variable _pdata.

If persisting is currently not possible for any reason, the persistence handler may throw an error.
safelua.sandboxId()
Returns the id (a string) of the current sandbox.
safelua.exitSoon()
Exits the sandbox. As the qualifier "soon" indicates, handling of events currently in flight is completed and then the sandbox is actually shutdown. This is typically a better and cleaner way to shutdown a sandbox than actually interrupting execution in the middle of everything. (Although there will probably also be a function for that in a future release.)
safelua.osVersion()
Returns the version of Lua OS the script is running in (a string), for example: "Lua OS 0.10".

4.9.4. safecomm

This globally accessible object provides services for communication between sandboxes.

safecomm.send{recipient, cmd [, data]}
(Note the curly brackets.) Send a message to another sandbox. recipient (a string) is either a sandbox id or a channel. cmd is the command to send (an arbitrary string). data is a list of named or unnamed items to be added to the message. Multiple items can be put in directly, without extra curly braces. (All items must be exchangeable data.)

send places the message in the recipient's (or the recipients') event queues and then returns immediately. If you want to wait for an answer, use safecomm.invoke.
safecomm.invoke{recipient, cmd [,data]}
(Note the curly brackets.) Like safecomm.send, but blocks (sleeps) until an answer is received which is then returned to you.
safecomm.handler(handler)
Register a message handler. A sandbox can have multiple message handlers. Whenever a message is received, all the message handlers are run on it.

A message handler is a function taking three arguments: sender (sandbox id), command (string) and data (a table with exchangeable data). It does not return any value.
safecomm.removeHandler(handler)
Remove a message handler from the list.
safecomm.listenOn(channel)
Registers this sandbox as a listener on a given channel. A channel is identified by a string. When a message is sent to a channel by any sandbox, all listeners for that channel in the same cage receive this message.
safecomm.yield(result, exitAfterEvents)
An extended yield function. You will usually only need this if you work with sockets. result is: nil (=I still have stuff to do anyway), true (=sleep and only wake up for incoming messages) or a list of sockets that you are waiting on.
safecomm.daemon()
Keeps this sandbox alive, waiting for messages. Same as: safecomm.yield(true)
safecomm.answer(sender, data, answer)
Send an answer. sender and data are the parameters from the original message. (The data field will contain an id identifying the original mesage.) answer is some exchangeable data that constitutes the answer you'd like to send.
safecomm.registerService(name, object)
Registers a (local) object as a service implementation. Services are announced cage-wide and are identified by name. If two sandboxes register an implementation for the same service, currently the latter implementation replaces the former. This might be handled more flexibly in the future.
safecomm.connectToService(name)
Connect to a service. Returns the implementation object if one is found, ready to use (with transparent sandbox tunnelling on method calls). If no implementation is found, connectToService returns nil.

4.9.5. Cage management

Access to cage management (if permitted for the current sandbox) is enabled by calling:

  cageManagement = safelua.requestExtension("cageManagement")

The object then provides the following functions:

cageManagement:sandboxIds()
Returns a list containing the ids of all sandboxes in the cage.
cageManagement:getInfo(id)
Returns an array with information about a sandbox. (TODO: Describe what information that is...)
cageManagement:startSandbox(def)
Create a new sandbox, add it to the cage and run it. def is the sandbox definition in table form.
cageManagement:deleteSandbox(id)
Delete the sandbox with the given id. The shutdown handler is called for cleanup if one was defined.
cageManagement:sandboxCode(id)
Return the text of the script running in a sandbox.
cageManagement:sandboxOutput(id)
Return all text that was printed by the sandbox. (All output is captured and stored automatically.)

 

4.10. Not covered here yet: the Lua servers (GUI, files etc.)