Jenkins System Properties

I started doing much more work with jenkins lately and experiencing the void of solutions to some issues I am facing, I decided to start posting them here.

So today we are going to load some system properties on jenkins startup.

Jenkins allows Groovy hook scripts to be set up that are run early during startup or if jenkins experiences boot failure. Since these scripts use the same JVM as jenkins, we can set up a script that set up system properties directly or load from file.

Setup is simple, put jenkins.properties to your $JENKINS_HOME and create init.groovy.d there too. Put the following groovy file under init.groovy.d:

load-properties.groovy

import jenkins.model.Jenkins
import java.util.logging.LogManager

def logger = LogManager.getLogManager().getLogger("")

/* JENKINS_HOME environment variable is not reliable */
def jenkinsHome = Jenkins.instance.getRootDir().absolutePath

def propertiesFile = new File("${jenkinsHome}/jenkins.properties")

if (propertiesFile.exists()) {
    logger.info("Loading system properties from ${propertiesFile.absolutePath}")
    propertiesFile.withReader { r ->
        /* Loading java.util.Properties as defaults makes empty Properties object */
        def props = new Properties()
        props.load(r)
        props.each { key, value ->
            System.setProperty(key, value)
        }
    }
}

Now restart jenkins and observe the following output:

Sep 26, 2014 9:59:17 PM jenkins.InitReactorRunner$1 onAttained
INFO: Augmented all extensions
Sep 26, 2014 9:59:20 PM jenkins.InitReactorRunner$1 onAttained
INFO: Loaded all jobs
Sep 26, 2014 9:59:20 PM jenkins.util.groovy.GroovyHookScript execute
INFO: Executing /home/rye/.jenkins/init.groovy.d/load-properties.groovy
Sep 26, 2014 9:59:20 PM org.jenkinsci.main.modules.sshd.SSHD start
INFO: Started SSHD at port 48042
Sep 26, 2014 9:59:20 PM java.util.logging.LogManager$RootLogger log
INFO: Loading system properties from /home/rye/.jenkins/jenkins.properties
Sep 26, 2014 9:59:20 PM jenkins.InitReactorRunner$1 onAttained
INFO: Completed initialization

Visit $JENKINS_URL/systemInfo (e.g. http://localhost:8080/systemInfo) and see your system property defined.

I needed this because the certificate I got from StartSSL was not trusted by JVM by default, so I had to override trustStore by creating a new keystore ($JENKINS_HOME/.keystore), importing StartSSL Class 1 certificate, and set javax.net.ssl.trustStore=/var/lib/jenkins/.keystore system property.

Sad Acer A1 status update

This January after 3 years of horrible performance of buggy hardware and software my Acer Liquid E USB port has partially detached from its motherboard which prevented the device from being charged and accessed over USB.

Replacing the motherboard makes no sense since it's equivalent to buying another horrible broken Acer Liquid E device. Replacing 10 pin MiniUSB requires both compatible part CN 10PIN 215+916+2450 ACT and precision tools I don't have.

This brings the end to my attempts of fixing the thing that was not supposed to be broken from the start.

Acer Liquid E idle at 39.2 ℃

I've learned a lot about Android internals and kernel development. It inspired me to dig deeper and even join Samsung R&D Ukraine briefly to study embedded development, which made me realize that supporting a device without manufacturer assistance is an unthankful job.

The devices get released at an increased rate and deprecation of components brings the cost of support for existing devices prohibitively high. That means there are two purchasing options now - either an undertested or obsolete device.

Sad but true.

Shrinking Oversized Images in Liferea

I started using liferea quite a while ago for RSS feed and the only issue I encountered was the way the images were displayed if the image was larger than the window:

Liferea display before the change

By adding the following rule to ~/.config/liferea/liferea.css I got all images resized to fit the window and browsing large photos in the feeds is no longer an issue.

img {
    max-width: 100%;
    height: auto;
}
Liferea display after the change

Working With L-2 Status

Please note that I can't be held liable for any errors or omissions in the document and you will need to seek real immigration lawyer should you have any questions not answered on the USCIS/SSA websites.

TL;DR version: get EAD then SSN and that's all the documents you need to start working.

L-2 is a visa type/status issued to "a spouse of intra-company transferee". Regardless of what you read elsewhere you are NOT eligible to work anywhere unless you receive an Employment Authorization Document.

For some weird reason, SSA and DHS disagree on whether L-2 holders are eligible to work w/o EAD:

USCIS/DHS:

Spouses of L-1 workers may apply for work authorization by filing a Form I-765, Application for Employment Authorization with fee. If approved, there is no specific restriction as to where the L-2 spouse may work.

SSA:

For COAs displaying a double asterisk (**) (non-immigrant E-1, E-2, and L-2 classifications), the spouse is also authorized to work without specific DHS authorization.

A person admitted under L-2 can obtain SSN w/o EAD, the list of documents is:

  • an EAD (Form I-766) showing “A-18” under Category; or
  • evidence other than an EAD that proves the L-2’s lawful alien status (e.g., I-94) and a marriage document as evidence that he or she is the spouse of the principal L-1 alien.

However, in my case I was specifically asked for an EAD while submitting the documents for SSN, stating that otherwise I would not be eligible for receiving SSN, your mileage may vary.

Based on the DHS documents, your employer will want to see the work authorization and the I-9 form states that SSN showing "ALLOWED TO WORK ONLY WITH DHS AUTHORIZATION" is not enough.

Getting EAD

Employment Authorization Document is issued by Department of Homeland Security. While you can eFile the documents, you will still need to provide a payment (personal check or money order) and photos, so you will need to get these to the USCIS (U.S. Citizenship and Immigration Services) and the easiest way is to mail everything using the post office.

You will need to figure out where you need to send the documents based on the state you are currently in, see the instructions for your I-765 form.

Double and triple-check the contents of your mail prior to posting. Create a checklist and tick it off as you put the items into your mail, you really want to get everything done properly from the first time.

You will want to get a tracking number, so that you will be able to check the status of the message as it is traveling through the US to the lockbox facility.

Once USCIS receives your mail and checks that it is intact, you will receive a mail message, Form I-797C, Notice of Action, where you will see the current status of your case and the receipt number.

Now go to USCIS, create an account and register for e-mail notification as your case passes various stages.

When your application is approved, DHS will send you another I-797 Notice of Action, this time on a fancy watermarked paper stating that your card is being sent to you.

Here's how the card looks:

/galleries/dropbox/ead.jpg

If you signed up for e-mail notifications on the case progress, you will also receive an e-mail containing the USPS tracking number, however in my case there appears to be a template processing bug, and I was left with "#DCN" as the tracking number. I have notified the webmaster about the issue, but haven't heard anything back yet.

Change of address

EAD processing may take up to 90 days, if you happen to relocate while you are waiting for the document to arrive, you can update the address online, specifying the receipt number you received in the first "Notice of Action". When DHS updates your information they will send you a paper mail notification about the same.

Social Security Number

Once you receive your EAD, you can go to your local Social Security Administration office and apply for a Social Security Number.

You will need to provide:

  • A completed SS-5 form.
  • Your foreign passport with the L-2 visa.
  • Employment Authorization Card.

You will be given a receipt showing your name, mail address, and application date. The social security card should arrive to your mailbox within 2 weeks.

First day

As expected, on the first day of work I needed to provide my Passport and EAD. Employment quest is finished, no issues detected.

Метки в IMAP Яндекс.Почты

Письмо в поддержку:

Здравствуйте! Спасибо за отличный сервис - почтой и диском пользуюсь постоянно.

В последнее время я начал пользоваться Mozilla Thunderbird для почты и обнаружил две неисправности:

  1. В случае, если метка содержит заглавные буквы (например "Work") то при добавлении флага "work" через IMAP веб интерфейс не замечает добавления метки (cудя по RFC, флаги в IMAP должны быть регистронезависимыми).
  2. После того, как приложение ставит флаги и переподключается к серверу, в IMAP флаги пропадают, хотя на веб интерфейсе метки остаются. Во вложении находится лог обмена сообщениями между мной и сервером, а на видео http://video.yandex.ru/users/roman-yepishev/view/16/ можно увидеть, как флаг "shopping" внезапно пропадает после close/select в IMAP, оставаясь при этом в веб-интерфейсе. Это происходит только с метками, которые предварительно созданы через веб.

Из-за данных неисправностей невозможно использовать одни и те-же метки в IMAP клиенте и на web интерфейсе.

Ответ из службы поддержки:

Здравствуйте, Роман!

Наши специалисты уже занимаются решением проблемы, о которой Вы сообщаете, и постараются закончить эту работу как можно скорее. Приносим свои извинения за временные неудобства! Мы будем признательны за Ваше терпение и понимание.

Ок, подождем, вот моя переписка с IMAP сервером:

imap-flags-reset.txt

$ telnet-ssl  -z ssl imap.yandex.ru imaps
Trying 87.250.250.124...
Connected to imap.yandex.ru.
Escape character is '^]'.
* OK Yandex IMAP4rev1 at imap15g.mail.yandex.net:993 ready to talk with 24.2.252.8:42823, 2013-Dec-14 00:05:33, V5PajE3m64YO
1 login roman-yepishev "***"
1 OK LOGIN completed
1 select inbox
[...]
1 close
1 OK close complete.
1 select inbox
* FLAGS (\Answered \Seen \Draft \Deleted $Forwarded)
* 1 EXISTS
* 0 RECENT
* OK [PERMANENTFLAGS (\Answered \Seen \Draft \Flagged \Deleted $Forwarded \*)] Limited
* OK [UIDNEXT 23396] Ok
* OK [UIDVALIDITY 1274466921] Ok
1 OK [READ-WRITE] select completed
1 fetch 1 flags
* 1 FETCH (FLAGS (\Seen))
1 OK fetch completed
1 store 1 +FLAGS (shopping)
* 1 FETCH (UID 23394 FLAGS (\Seen shopping))
1 OK store completed
1 close
1 OK close complete.
1 select inbox
* FLAGS (\Answered \Seen \Draft \Deleted $Forwarded)
* 1 EXISTS
* 0 RECENT
* OK [PERMANENTFLAGS (\Answered \Seen \Draft \Flagged \Deleted $Forwarded \*)] Limited
* OK [UIDNEXT 23396] Ok
* OK [UIDVALIDITY 1274466921] Ok
1 OK [READ-WRITE] select completed
1 fetch 1 flags
* 1 FETCH (FLAGS (\Seen))
1 OK fetch completed

AppArmor config for Yandex.Disk

I've been using Yandex.Disk for quite a while for data synchronization and file sharing because of its simplicity - a standard WebDAV implementation (+ extensions for file sharing, all documented, although in Russian) allowing for different clients to be used, a nice web UI and they have introduced a Linux client recently which marries WebDAV and XMPP which is used for OOB notifications.

Being a bit cautious I decided to run it on my system but restrict access to everything else, so I wrote the following apparmor config and now it is only allowed to touch the files within ~/Yandex.Disk directory and it's configuration, put it to /etc/apparmor.d/usr.bin.yandex-disk:

usr.bin.yandex-disk

# vim:syntax=apparmor
# Author: Roman Yepishev <roman.yepishev@yandex.com>
#include <tunables/global>

/usr/bin/yandex-disk {
    #include <abstractions/base>
    #include <abstractions/nameservice>
    #include <abstractions/user-tmp>

    owner @{HOME}/.config/yandex-disk/ rw,
    owner @{HOME}/.config/yandex-disk/** rw,

# yandex-disk can add itself to autostart configuration
    owner @{HOME}/.config/autostart/Yandex.Disk.desktop rw,

# default sync location
    owner @{HOME}/Yandex.Disk/ rw,
    owner @{HOME}/Yandex.Disk/** rw,

# or change the location like this:
#   owner @{HOME}/OtherFolder/ rw,
#   owner @{HOME}/OtherFolder/** rw,

    /usr/bin/yandex-disk ixr,

    /bin/dash ixr,
}

Yandex.Disk supports symlinks, so if symlinks to other locations are used, these all should be described in the configuration file. Otherwise, the access checks will fail and you will get this in kernel log:

[77109.846335] type=1400 audit(1386173505.778:116): apparmor="DENIED" ↩
operation="open" parent=2000 profile="/usr/bin/yandex-disk" ↩
name="/home/rye/_wine.tar.gz" pid=2869 comm="yandex-disk" ↩
requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000

P.S. Yeah, I've stopped using Ubuntu One for the time being.

ATM Deposit gone bad

I had a checking account with CityBank during my stay in the US in 2007. A lot of US-based online stores wanted US-issued card only (the same goes for UK stores, same attitude towards foreign cards), so I had to physically withdraw money from my Ukrainian card and deposit it to my US account (other options were not available at that time).

So once I found out I can do the deposits without bank teller via the ATM I decided to try it immediately.

Here's my dialog with the machine:

  • What do you want to do?
  • Deposit
  • How much do you want to deposit?
  • (Huh? That does not look right, you should check how much I have deposited. Okay, let's test) $200
  • Insert bills or envelope
  • (Excuse me? An envelope? How will the ATM check the bills are genuine? Bills or envelope... ok, I will go with the bills. I insert the stack of bills into the machine hoping there's some sort of feeder and verification system in place and notice the bills simply dropped somewhere inside the machine, oops)
  • Thank you for banking with CitiBank

This happened after working hours, so I decided not to continue stuffing the ATM with my money for the time being and see whether something goes wrong.

At home I checked CitiBank onine banking system and found that I had a successfull +$200 deposit.

The next day I went to CircuitCity and purchased some things using the card, when I returned home in the evening I found out that I had -$140 balance on a debit account.

Something went wrong.

The next day I went to CitiBank branch, spent half an hour with my account manager explaining what I did, she asked around and one teller confirmed that yeah, they had $200 unaccounted in the ATM because some idiot (my word, not theirs) decided it was a good idea to shove the money into the deposit slot. Overdraft was dropped, I learned a valuable lesson and used an envelope next time.

In 2011 Citibank started switching to ATMs that count and verify the bills and no longer require these weird envelopes.

2002:12:08 Exif Date

Some Android phones/versions have a bug that cause the EXIF DateTimeOriginal/DateTimeDigitized to be set to 2002:12:08. Recently I had a chance to dig into the library provided by Qualcomm, and found the offending string.

It turned out the date in question is the default string used as a placeholder. The application using the library is expected to override the date by calling exif_set_tag function. Unfortunately, not everybody consider metadata to be important, so sometimes this gets left out.

The copyright start date on the files is said to be 2002 so I guess some milestone was reached on 8th of December, 2002.

If only all the phone software was open source that would not have been an issue – the fix would have been ready in minutes, but in our current real world it is a matter of months, years, eternity or workaround such as my Acer EXIF Fixup. Once the device is out the user is left one on one with the bugs (should it be “one on many?”).

Tizen: Building a Platform Application for Emulator

While I am still in love with Tizen platform, and having spent some time fixing build bugs I should not have introduced in the first place, here are my findings about Tizen build system.

Tizen supports both HTML5-based applications and native ones. The latter can be packaged as RPM archives for platform applications or as a widget ZIP archive when installed by a user. RPMs are built using GIT Build System (GBS) which manages a local build chroots, export the sources for building, submit changes to Gerrit etc.

You should install GBS by following the Installing Development Tools guide. Also note that you don't really need to have all the platform sources on your local machine as GBS will fetch all the required dependency archives and re-create the build environment in the chroot. RPM files must specify the BuildDepends for the magic to happen.

Emulator builds are different from the real device ones in some subtle ways. I've spent a few days figuring out why libewebkit2 compiled from the sources would not work on an emulator. It turned out there exist a separate tizen repository for emulator RPMs and trying to put real-world packages into an emulator may fail in really bizzare ways (how do you like a black screen upon HTML5 app launch?). At the moment of writing the latest snapshot is tizen-2.2-emul_20130719.2.

You will need a .gbs.conf in your $HOME. We are building for an emulator, please note the repo URL:

[general]
tmpdir=/var/tmp/
profile = profile.tizen2.2_emul

[repo.tizen2.2_emul]
url = http://download.tizen.org/releases/2.2-emul/tizen-2.2-emul_20130719.2/

[profile.tizen2.2_emul]
repos=repo.tizen2.2_emul

Now we need our application. The source is available from GitHub branch at tizen-example-platform-app.

GBS looks for a packaging directory for a spec file, so this should be always present:

Name:       example-platform-app
Version:    1.0
Release:    1
Summary:    Example Tizen Platform App

License:    GPL2
URL:        http://rtg.in.ua
Source0:    %{name}-%{version}.tar.gz

%description
Example Tizen Platform Application

%prep
%setup -q

%build
make %{?_smp_mflags}

%install
make install DESTDIR=%{buildroot} PREFIX=%{_prefix}

%files
%{_bindir}/example-platform-app

%changelog
* Sat Aug 17 2013 Roman Yepishev <roman.yepishev@yandex.ua>
- Initial version

Upon cloning the repository you are ready to build the application.

$ git clone https://github.com/roman-yepishev/tizen-example-platform-app.git
$ cd tizen-example-platform-app
$ gbs build -A i586
info: generate repositories ...
...
info: generated RPM packages can be found from local repo:
    /home/rye/GBS-ROOT/local/repos/tizen2.2_emul/i586/RPMS

GBS automatically creates GBS-ROOT in your home directory, visiting the RPMS shows we have new shiny RPM packages:

$ cd /home/rye/GBS-ROOT/local/repos/tizen2.2_emul/i586/RPMS
$ ls
example-platform-app-1.0-1.i586.rpm
example-platform-app-debuginfo-1.0-1.i586.rpm
example-platform-app-debugsource-1.0-1.i586.rpm

While you are at it, there are a few useful gbs build options, the full list of options can be seen by running gbs build --help:

--debug        debug output
--overwrite    overwrite existing binaries and build them anyway
-C, --clean    delete old build root before initialization
--clean-repos  clean up local repos created by gbs

Fire up the emulator instance and wait until sdb sees it:

$ sdb devices
List of devices attached
emulator-26100  device  Test

The only part left is to push the RPMs and install them:

$ sdb push example-platform-app-1.0-1.i586.rpm /tmp
1 file(s) pushed. 0 file(s) skipped.
example-platform-app-1.0-1.i586.rpm   36 KB/s (4645 bytes in 0.125s)

$ sdb root on
Switched to 'root' account mode

$ sdb shell
sh-4.1# rpm -Uhv /tmp/example-platform-app-1.0-1.i586.rpm
reading device security policy from /etc/device-sec-policy
package ac-domain-system defined ac domain Isolated
...
Preparing...                ########################################### [100%]
no RSA signature, cannot search sw source
using _default_ sw source
No manifest in this package. Creating default one
adding example-platform-app manifest data to system, package_name example-platform-app
sw source _default_ provided package example-platform-app
Request for a domain name _ is allowed based on package sw source
    1:example-platform-app   setting SMACK64 _ for /usr/bin/example-platform-app
setting SMACK64EXEC _ for /usr/bin/example-platform-app
########################################### [100%]
sh-4.1# example-platform-app
Hello, Tizen!

Congratulations, you have a platform application running on the emulator. This application does not do anything interesting for now but it can be used as a starting point.

I can also confess that I really like RPMs now.

Tizen SDK on Fedora 19 x64

At the moment I am checking out other distributions after spending more than 5 years on Ubuntu and this week my Linux distro is Fedora 19. I am also interested in Tizen, so ability to run Tizen SDK on Fedora is quite welcome.

Tizen SDK is supported on Windows and Ubuntu machines only, but it is not really a big deal to get it working on Fedora installation.

First of all, install all the extra packages the installer wants you to:

$ sudo yum install qemu-user expect libgnome webkitgtk libpng12

It wants to use Oracle JDK, so after installing the RPM from Oracle web site you will need to set up the alternatives link (by the way, if you happen to find this link while searching how to set up Oracle JDK on Ubuntu, java-package is your friend):

$ sudo update-alternatives --install \
/usr/bin/java java /usr/java/jdk1.7.0_25/bin/java 900
$ sudo update-alternatives --config java

There is 2 program that provides 'java'.

Selection    Command
-----------------------------------------------
* 1           /usr/lib/jvm/java-1.7.0-openjdk-[...]/jre/bin/java
  2           /usr/java/jdk1.7.0_25/bin/java

Enter to keep the current selection[+], or type selection number:

Installer should work after this. I prefer downloading the sdk image and using it instead of re-downloading all the files via the installer itself. During the installation it should ask you to grant it superuser access to install kvm SysV init script (/etc/init.d/tizen-kvm) and udev rule file to configure permissions for Samsung development devices.

Ok, if installer has finished successfully you can now start the IDE, which... well, it won't work due to libsoup crash. The workaround is to add the following to ide/eclipse.ini:

-Dorg.eclipse.swt.browser.DefaultType=mozilla

Now the IDE starts, it still complains about MOZILLA_FIVE_HOME, it is not critical for now, but I would need to find out the real reason.

Creating a new VM will fail - qemu-img is linked to libcurl-gnutls.so.4, which is not present in Fedora. A dumb solution for this was to add a symlink in /usr/lib64/ to libcurl.so.4. While qemu-img could start, it looks like it's output is being parsed, and a message about version info gets in the way. I ended up symlinking tools/emulator/qemu-img to a system-wide /usr/bin/qemu-img. Our libcurl-gnutls.so.4 symlink still helps, because emulator-x86 is also linked against that lib.

Having done all that I got the Tizen IDE and emulator running on Fedora.

/galleries/dropbox/tizen-sdk-fedora.thumbnail.png