A docker based workflow for working on beaker

While working with beaker‘s code base, I often feel the need to run my tests for a patch/feature and continue to work on with different things while they run, including running other tests testing something different. Currently this is not possible since we start off with a clean database on every test run and simultaneous runs would obviously make one run step on another’s feet.

I finally have an initial docker based prototype for making this possible.

Fedora 20 Scientific Released

Fedora 20 is now released, which also means the newest release of Fedora Scientific along with other spins are also available.

Download

You can download the spin images from here.

What’s new in Fedora Scientific

The notable additions in this release are:

  • Sage, along with Sage notebook.
  • SymPy, the Python library for Symbolic mathematics
  • The Python 3 versions for scipy, numpy, matplotlib libraries and IPython (including IPython notebook)
  • Commons math, a Java library for numerical computing

The Fedora 20 release notes are here.

Fedora Scientific Documentation

I started work on some documentation for Fedora Scientific about a month or so back. It is far from what I want it to be, but you can see the current version here. The first goal that I have in mind is to document all the major scientific tools and libraries that are shipped with Fedora Scientific. By document, I imply links to the official project resources and guides. The second goal is to actually add original content and make it a guide book for Fedora Scientific which may be used as an entry point for Open Source Scientific Computing. Once the guide has taken some shape, an RPM package can be created and distributed with Fedora Scientific so that the entire documentation is available for offline perusal.

Contributing

The Fedora Scientific documentation is an excellent starting point if you are looking to make a contribution to Fedora Scientific. You can view the project here.

If you have some toy/throwaway scripts that makes use of one of the libraries/tools, you may want to contribute it to the
“tests” here. They will help sanity check these libraries and tools during the development of upcoming Fedora Scientific releases.

Discussions and support

Please join the Fedora scitech mailing list.

Suggetions and ideas? Please leave a comment.

poweroff, halt, reboot and systemctl

On Fedora (and perhaps other Linux distros using systemd) you will see that the poweroff, reboot and halt commands are all symlinks to systemctl:

> ls -l /sbin/poweroff /sbin/halt /sbin/reboot 
lrwxrwxrwx. 1 root root 16 Oct  1 11:04 /sbin/halt -> ../bin/systemctl
lrwxrwxrwx. 1 root root 16 Oct  1 11:04 /sbin/poweroff -> ../bin/systemctl
lrwxrwxrwx. 1 root root 16 Oct  1 11:04 /sbin/reboot -> ../bin/systemctl

So, how does it all work? The answer lies in this code block from systemctl.c:

..
5556        if (program_invocation_short_name) {                                                                                                                                              
5557                                                                                                                                                                                          
5558                if (strstr(program_invocation_short_name, "halt")) {                                                                                                                      
5559                        arg_action = ACTION_HALT;                                                                                                                                         
5560                        return halt_parse_argv(argc, argv);                                                                                                                               
5561                } else if (strstr(program_invocation_short_name, "poweroff")) {                                                                                                           
5562                        arg_action = ACTION_POWEROFF;                                                                                                                                     
5563                        return halt_parse_argv(argc, argv);                                                                                                                               
5564                } else if (strstr(program_invocation_short_name, "reboot")) {                                                                                                             
5565                        if (kexec_loaded())                                    
..

program_invocation_short_name
program_invocation_short_name is a variable (GNU extension) which contains the name used to invoke a program. The short indicates that if you call your program as /bin/myprogram, it is set to ‘myprogram’. There is also a program_invocation_name variable consisting of the entire path. Here is a demo:


/*myprogram.c*/

# include <stdio.h>

extern char *program_invocation_short_name;
extern char *program_invocation_name;

int main(int argc, char **argv)
{
  printf("%s \n", program_invocation_short_name);
  printf("%s \n", program_invocation_name);
  return 0;
}

Assume that the executable for the above program is created as myprogram, execute the program from a directory which is one level up from where it resides. For example, in my case, myprogram is in $HOME/work and I am executing it from $HOME:

> ./work/myprogram 
myprogram 
./work/myprogram 

You can see the difference between the values of the two variables. Note that any command line arguments passed are not included in any of the variables.

Back to systemctl

Okay, so now we know that when we execute the poweroff command (for example), program_invocation_short_name is set to poweroff and this check matches:

if (strstr(program_invocation_short_name, "poweroff")) 
..

and then the actual action of powering down the system takes place. Also note that how the halt_parse_argv function is called with the parameters argc and argv so that when you invoke the poweroff command with a switch such as --help, it is passed appropriately to halt_parse_argv:

5194        static const struct option options[] = {                                                                                                                                          
5195                { "help",      no_argument,       NULL, ARG_HELP    },                                                                                                                    
..
..
5218                case ARG_HELP:                                                                                                                                                            
5219                        return halt_help(); 

Fooling around

Considering that systemctl uses strstr to match the command it was invoked as, it allows for some fooling around. Create a symlink mypoweroff to /bin/systemctl and then execute it as follows:

> ln -s /bin/systemctl mypoweroff
> ./mypoweroff --help
mypoweroff [OPTIONS...]

Power off the system.

     --help      Show this help
     --halt      Halt the machine
  -p --poweroff  Switch off the machine
     --reboot    Reboot the machine
  -f --force     Force immediate halt/power-off/reboot
  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
  -d --no-wtmp   Don't write wtmp record
     --no-wall   Don't send wall message before halt/power-off/reboot

This symlink is for all purpose going to act like the poweroff command since systemctl basically checks whether ‘poweroff’ is a substring of the invoked command.

To learn more, see systemctl.c

Related

Few months back, I had demoed invoking a similar behaviour in programs where a program behaves differently based on how you invoke it using argv[0] here. I didn’t know of the GNU extensions back then.

Managing IPython notebook server via systemd: Part-I

If you are using IPython notebook on a Linux distribution which uses systemd as it’s process manager (such as Fedora Linux, Arch Linux) , you may find this post useful. I will describe a fairly basic configuration to manage (start/stop/restart) IPython notebook server using systemd.

Creating the Systemd unit file

First, we will create the systemd unit file. As root user, create a new file /usr/lib/systemd/system/ipython-notebook.service and copy the following contents into it:

[Unit]
Description=IPython notebook

[Service]
Type=simple
PIDFile=/var/run/ipython-notebook.pid
ExecStart=/usr/bin/ipython notebook --no-browser --pylab=inline
User=ipynb
Group=ipynb
WorkingDirectory=/home/ipynb/notebooks

[Install]
WantedBy=multi-user.target

Note that due to the naming of our unit file, the service will run as ipython-notebook. To completely understand the above unit file, you will need to read up a little of the topic. You may find my earlier post useful which also has links to systemd resources. Three things deserve explanation though:

The line, ExecStart=/usr/bin/ipython notebook --no-browser --pylab=inline specifies the command to start the IPython notebook server. This should be familiar to someone who uses it.

The lines, User=ipynb and Group=ipynb specify that we are going to run this process as user/group ipynb (we create them in the next step).

The line WorkingDirectory=/home/ipynb/notebooks specify that the notebooks will be stored/server in/from /home/ipynb/notebooks

Setting up the user

As root, create the user ipynb:

# useradd ipynb

Next, as ipynb, create a sub-directory, notebooks:


# su - ipynb
[ipynb@localhost ~]$ mkdir notebooks
[ipynb@localhost ~]$ exit

Starting IPython notebook

We are all set now to start IPython notebook. As the root user, reload all the systemd unit files, enable the ipython-notebook service so that it starts on boot, and then start the service:


# systemctl daemon-reload
# systemctl enable ipython-notebook
ln -s '/usr/lib/systemd/system/ipython-notebook.service' '/etc/systemd/system/multi-user.target.wants/ipython-notebook.service'
# systemctl start ipython-notebook

If you check the status of the service, it should show the following:

# systemctl status ipython-notebook
ipython-notebook.service - IPython notebook
Loaded: loaded (/usr/lib/systemd/system/ipython-notebook.service; enabled)
Active: active (running) since Sun 2013-09-22 22:39:59 EST; 23min ago
Main PID: 3671 (ipython)
CGroup: name=systemd:/system/ipython-notebook.service
├─3671 /usr/bin/python /usr/bin/ipython notebook --no-browser --pylab=inline
└─3695 /usr/bin/python -c from IPython.zmq.ipkernel import main; main() -f /home/ipynb/.ipython/profile_default/security/kernel-6dd8b338-e779-4e67-bf25-1cd238...

Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] Serving notebooks from /home/ipynb/notebooks
Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] The IPython Notebook is running at: http://127.0.0.1:8888/
Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] Use Control-C to stop this server and shut down all kernels.
Sep 22 22:40:21 localhost ipython[3671]: [NotebookApp] Using MathJax from CDN: http://cdn.mathjax.org/mathjax/latest/MathJax.js
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Kernel started: 6dd8b338-e779-4e67-bf25-1cd23884cf5a
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Connecting to: tcp://127.0.0.1:51666
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Connecting to: tcp://127.0.0.1:52244
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Connecting to: tcp://127.0.0.1:44667
Sep 22 22:40:22 localhost ipython[3671]: [IPKernelApp] To connect another client to this kernel, use:
Sep 22 22:40:22 localhost ipython[3671]: [IPKernelApp] --existing kernel-6dd8b338-e779-4e67-bf25-1cd23884cf5a.json

You should now be able to access IPython notebook as you would normally do. Finally, you can stop the server as follows:


# systemctl stop ipython-notebook

The logs are redirected to /var/log/messages:


Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] Created profile dir: u'/home/ipynb/.ipython/profile_default'
Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] Serving notebooks from /home/ipynb/notebooks
Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] The IPython Notebook is running at: http://127.0.0.1:8888/
Sep 22 22:39:59 localhost ipython[3671]: [NotebookApp] Use Control-C to stop this server and shut down all kernels.
Sep 22 22:40:21 localhost ipython[3671]: [NotebookApp] Using MathJax from CDN: http://cdn.mathjax.org/mathjax/latest/MathJax.js
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Kernel started: 6dd8b338-e779-4e67-bf25-1cd23884cf5a
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Connecting to: tcp://127.0.0.1:51666
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Connecting to: tcp://127.0.0.1:52244
Sep 22 22:40:22 localhost ipython[3671]: [NotebookApp] Connecting to: tcp://127.0.0.1:44667
Sep 22 23:05:35 localhost ipython[3671]: [NotebookApp] received signal 15, stopping
Sep 22 23:05:35 localhost ipython[3671]: [NotebookApp] Shutting down kernels
Sep 22 23:05:35 localhost ipython[3671]: [NotebookApp] Kernel shutdown: 6dd8b338-e779-4e67-bf25-1cd23884cf5a

For me, the biggest reason to do this is that I do not have to start the IPython notebook server everytime on system startup manually, since I know it will be running when I need to use it. I plan to explore managing custom profiles next and also think more about a few other things.

Fedora Scientific Spin Update

The Fedora Scientific 20 Spin will have a number of new packages: notably, it will now include the Python 3 tool chain for the Python libraries for scientific/numerical computing. If you are interested to check it out, download a nightly from here.

Testing the applications/libraries

It took me 3 releases to figure out – or rather, sit down to do it. Anyway, here it is now. I have created a Wiki page where I want to list scripts/other ways to sanity test the various packages/applications that are being shipped. I believe it will help in two ways:

  • Often, the entire functionality of a tool/library is split into more than one package and hence pulling in only the main package is no guarantee that the tool/library/application will work.
  • We may also be able to catch genuine bugs/faults in the packages being shipped. (Think of things like missing shared library dependency, etc)

So, please add whatever you can to the wiki page. Just simple ways to see if the application/library actually works.

My plan is to collect whatever I/we gather there into a git repository somewhere and run it prior to/during releases to see everything is working as expected.

Links

  • Download a nightly compose from here (The usual warning against testing in-progress Fedora releases apply)
  • Add scripts/tests to the wiki page here

If you find a problem, leave a comment here, or add to the wiki page.

Note

You may see that the nightlies are failing, but this should be fixed soon (See this bug). You can still download a TC5 build from here which has all the packages that are going to be shipped, except for sagemath.

Once again, thanks are due to the packagers actually packaging all this software that makes Fedora Scientific possible.