[2016-08-05] How to distribute an executable python module without pip

This will only work on linux, Free BSD, and probably Mac OS. Here is a simplified version of the file tree.

$ tree
├── boerewors
│   ├── command_line.py
│   ├── errors.py
│   ├── helper.py
│   ├── __init__.py
│   └── warmup.py
├── __init__.py
├── __main__.py
├── setup.py
└── tests
    ├── helpers.py
    ├── __init__.py
    └── test_warmup.py

boerewors is a python module that we want to distribute. In case we want to distribute this package to a server without pip and without root privileges we can run this little shell script:

mkdir -p dist
zip -r dist/tmp.zip boerewors -x \*.pyc
zip dist/tmp.zip __main__.py
echo "#!/usr/bin/env python" > dist/warmup
cat dist/tmp.zip >> dist/warmup
chmod +x dist/warmup
rm dist/tmp.zip

This script zips the python module, creates file with a python shebang appends the zip file to it and marks it executable. The entry point of this executable is __main__.py which contains only this lines:

from boerewors.command_line import main

This file can now be copied to the server where we want to execute it. We are not bound to write our script in one file and even have test for development.

[2016-05-17] jenkins and arch linux or systemd

first install jenkins

sudo pacman -S jenkins

then start it (or enable it first)

systemctl start jenkins

lookup the initial password. (show the systemd log files for user jenkins)

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

open the dashboard view http://localhost:8090 in your browser. Do not create a new user as suggested, it will not work. But search for the login button and use the long password you found in the previous logs.

Now you can create a new admin user.

[update: 2016-12-01]

The admin key is not printed in the logs at startup anymore but i keep this as a reference how to retrieve the systemd logs for a process that runs as a specific user.

journalctl -u jenkins

here you find the similar lines

May 17 11:15:46 hwm-arch jenkins[8295]: *************************************************************
May 17 11:15:46 hwm-arch jenkins[8295]: *************************************************************
May 17 11:15:46 hwm-arch jenkins[8295]: *************************************************************
May 17 11:15:46 hwm-arch jenkins[8295]: Jenkins initial setup is required. An admin user has been created and a password generated.
May 17 11:15:46 hwm-arch jenkins[8295]: Please use the following password to proceed to installation:
May 17 11:15:46 hwm-arch jenkins[8295]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
May 17 11:15:46 hwm-arch jenkins[8295]: This may also be found at: /var/lib/jenkins/secrets/initialAdminPassword
May 17 11:15:46 hwm-arch jenkins[8295]: *************************************************************
May 17 11:15:46 hwm-arch jenkins[8295]: *************************************************************
May 17 11:15:46 hwm-arch jenkins[8295]: *************************************************************

[2015-06-30] unlock jolla phone, from permanently locked mode

Put your phone into the Recovery Mode:

  1. Power off your phone, disconnect from all cables
  2. Remove the battery
  3. Hold down the Volume-Down-Button
  4. Insert the battery again
  5. Push the Power-Button
  6. Release all buttons as soon the phone vibrates
  7. Connect your phone with the PC via USB

Now you should have a second network interface, and now you can use telnet to access the recovery menu.


Just select number 4 and enter your device lock code.

     Jolla Recovery v0.3.1      
Welcome to the recovery tool!
The available options are:
1) Reset device to factory state
2) Reboot device
3) Bootloader unlock [Current state: locked]
4) Shell
5) Try btrfs recovery if your device is in bootloop
6) Exit
Type the number of the desired action and press [Enter]: 

If you continue, this may void your warranty. Are you really SURE? [y/N] y
Type your devicelock code and press [ENTER] key:
(please note that the typed numbers won't be shown for security reasons)
[OK] Code accepted.

modify the devicelock settings file

mount /dev/mmcblk0p28 /mnt
sed -i "/nemo\\\devicelock\\\maximum_attempts=/c\nemo\\\devicelock\\\maximum_attempts=-1" /mnt/usr/share/lipstick/devicelock/devicelock_settings.conf

disconnect the phone and reboot it.

I found the info on this zendesk page

[2015-03-24] emerge vlc player in funtoo

When I tried to simply emerge vlc via sudo emerge -a vlc i got the following error:

  The following REQUIRED_USE flag constraints are unsatisfied:
    httpd? ( lua )

  The above constraints are a subset of the following complete expression:
    aalib? ( X ) bidi? ( truetype ) cddb? ( cdda ) dvb? ( dvbpsi ) dxva2? ( avcodec ) ffmpeg? ( avcodec avformat swscale ) fontconfig? ( truetype ) gnutls? ( gcrypt ) httpd? ( lua ) libcaca? ( X ) libtar? ( skins ) libtiger? ( kate ) qt4? ( X !qt5 ) qt5? ( X !qt4 ) sdl? ( X ) skins? ( truetype X exactly-one-of ( qt4 qt5 ) ) vaapi? ( avcodec X ) vlm? ( encode ) xv? ( xcb )

First i had no idea what this lines meant, but it seams that if you want to use httpd you need also lua.

On videolan.org they give an advice for the minimal set of useflags for the vlc ebuild.

I ended up adding two lines to /etc/portage/package.use:

media-video/vlc dvd ffmpeg mpeg mad wxwindows aac dts a52 ogg flac theora oggvorbis matroska freetype bidi xv svga gnutls stream vlm httpd cdda vcd cdio live vaapi -qt4 qt5 avahi lua directfb opus samba sdl sdl-image
media-video/ffmpeg vaapi opus samba sdl -ieee1394

I had a problem to build the lib for firewire which was a depency for ffmpeg. Since I have no firewire device I just droped it and removed the default useflag ieee1394.

[2015-03-12] emerge python3.4 in Funtoo

insert the following line into /etc/make.conf

PYTHON_ABIS="2.7 3.4"

and unmask python 3.4, either with

emerge -auDN @world --autounmask-write

or just edit the /etc/portage/package.unmask and insert the line your self

then update your world

emerge -auDN @world

[Update:] added PYTHON_SINGLE_TARGET to make.conf

[2015-02-20] Delete remote tags with git

I recently needed to do this.

git tag -d 12345

But i realized, that these tags where just deletet locally. Even a push --tags didn't help. But luckily I found this blog post. You need to do this push to force a deletion.

git push origin :refs/tags/12345

[2014-11-28] use at to schedule future tasks

You can use this simple form to schedule future tasks.

echo "git push" | at 12:00

or even on another day.

echo "/etc/init.d/nginx restart" | at 03:00 Nov 25

To view task queue use atq. And atrm <jobnumber> to rm jobs again.

[2014-11-27] Profile python 3 code with KCachegrind

Grab this script and run yours like this:

python3 lsprofcalltree.py <your_script.py>

and analize it with kcachegrind.

kcachegrind <your_script.py.log>

I found the original script at python.org.

[2014-11-26] Porting python 2 code to python 3

I needed to profile a python 3 script of mine. During this process if wanted to use a great helper script but it was not compatible with mine, so i had to port it to python 3. Porting python 2 code to python 3 is really easy, thanks to 2to3. The last time i ported a library all I had to do was to call 2to3 -w and it worked.

This time it didn't worked as smoothly, but it was very easy to change the last bits. The whole process took no longer than 5 minutes.

The first step was to run 2to3.

2to3 -w lsprofcalltree.py

After I tried to run the code, I got two NameError messages.

NameError: name 'execfile' is not defined
NameError: name 'file' is not defined

The file problem was a really easy fix, all I neede to do was replace it with file

@@ -112,12 +112,12 @@ def main(args):
         except SystemExit:
         kg = KCacheGrind(prof)
-        kg.output(file(options.outfile, 'w'))
+        kg.output(open(options.outfile, 'w'))

 if __name__ == '__main__':

The second change was a little bit bigger. Since execfile was inside a string that got evaluatet, 2to3 didn't catch this change. I created an empty new python file with just an execfile statement run 2to3 to see how the new output looked and applied those changes to the new file.

@@ -108,12 +108,12 @@ def main(args):
     prof = cProfile.Profile()
-            prof = prof.run('execfile(%r)' % (sys.argv[0],))
+            prof = prof.run("exec(compile(open(%r).read(), %r, 'exec'))" % (sys.argv[0],sys.argv[0]))
         except SystemExit:
         kg = KCacheGrind(prof)

You can see all the different versions after each step and the final result at github. And the best, it's MIT licensed.

[2014-10-22] welcome new clan member

I am very happy to announce a new gladis clan member.