[JIRA] Dev – Where are OSWorkflow Transition Screens?

Found a piece that isn’t well documented. But as usual, I’m explaining my steps and then the solution. It’s no real big deal anyway. 🙂

Here’s the background:
Mission was to write a Groovy script that returns all the transition screens used across all workflows of a given JIRA workflow scheme (for documentation purposes). This looked pretty easier, until a collection of ‘com.opensymphony.workflow.loader.ActionDescriptor’ came up without any linked JavaDocs. That looked like a dead end.

Then, with a little bit of googling I came across ActionDescriptor source code, which wasn’t helpful either. getView() method looked promising because ‘Transition View’ is a synonym used in JIRA UI for ‘Transition Screen’. But disappointingly it was just returning string ‘fieldscreen’ for every transition. Aw.. snap! 😦

Next attempt is called the ‘Bruteforce method’ (not java.lang.reflect.Method of course 😉 ).

Since I was too lazy to read across the ActionDescriptor’s source code:

// workflow is type of com.atlassian.jira.workflow.JiraWorkflow
// I'm not explaining all my code here
workflow.getAllActions().each {
  it.class.getDeclaredMethods().grep {
    it.name.matches( "^get.*" )
  }.each {
    log.debug ( it.name )

It didn’t took much of time. With a bit of guessing I made my first attempt with getter method ‘getMetaAttributes()’. And it had the eye-catching piece I was looking for!

workflow.getAllActions().each {
  log.debug ( it.getMetaAttributes().toString() )
[opsbar-sequence:10, jira.description:, jira.fieldscreen.id:10000]
[opsbar-sequence:20, jira.description:, jira.fieldscreen.id:20000]
[opsbar-sequence:40, jira.description:, jira.fieldscreen.id:30000]
[opsbar-sequence:60, jira.description:, jira.fieldscreen.id:30000]

getMetaAttributes() returns a HashMap. So, finally…

def screens = [:]
workflow.getAllActions().each {
  def screenId = it.getMetaAttributes()["jira.fieldscreen.id"]
  if ( screenId != "" ) {
    def workflowAction = workflow.name + " - " + it.name
    def workflowActions = []
    if ( screens[screenId] ) workflowActions = screens[screenId]
    workflowActions.add ( workflowAction )
    screens[screenId] = workflowActions
for ( e in screens ) {
  log.debug ( "Transition Screen: " + e.key )
  e.value.each {
    log.debug ( "  Workflow action: " + it )

Nice! This HashMap (‘screens’) is all what I wanted. 🙂 Each transition screen, and then where it has been used.

So one last thing… I also wanted to have a one last peek into ActionDescriptor’s source code on GitHub. Only the writeXML() method gave an indication that metaAttributes is actually a HashMap. There was absolutely no indication that screen association information is kept as a ‘meta attribute‘.

Bottom line(s):

  1. If you are a JIRA developer and whenever you want to find screens associated to a workflow, don’t use getView(). Use getMetaAttributes() and then look for the attribute with key “jira.fieldscreen.id”. In other words, transition screen is stored as a meta attribute in each transition. Screen is referred by its numeric ID as a string.
  2. Since OpenSymphony doesn’t seem to go away from JIRA, and some already claim that OpenSymphony is dead, it would be worthwhile if Atlassian maintains their own repository of OSWorkflow docs and special remarks.

Wunderlist Today wallpaper for Ubuntu

Wunderlist again. Currently this is the only Microsoft thing that I use – apart of Windows servers involved in my DevOps job.

Wunderlist hasn’t been treating nice for Ubuntu recently. So I thought about working on something that works for Ubuntu. Then here I got an idea of a very small app that will embed your day action items into the desktop wallpaper. Since I’m not very much into software development, this as a pilot project will make me comfortable for building something better for Ubuntu.

To be honest, first I was planning to do some browser DOM hacking and figure out how it works. Soon after, I found out that there’s a public API for Wunderlist (awesome, isn’t it?), and that can avoid the need of DOM hacking. So, that’s how wunderlist-ubu-wallpaper started as my pilot project.

It is still very young, and I’m sure my code needs a little cleanup as well. It’s just a 150 line Python script – not at all a big deal. Readme file has all the information you need to set it up on your Ubuntu. Run it and see what happens to your Ubuntu wallpaper. Isn’t that awesome?

14 years back when I was a kid, I was just making little Windows executables (I was a Windows user back then) with Visual Basic. After that I did programming to a some level when I was a systems administrator, but I was never permitted to release my work to the public for obvious reasons. After that, here comes my very first little code contribution to the world of Open Source.

By the way, my all other action items are overdue! 😳

[JIRA] Delete projects from XML backup using Python


If you are a JIRA system administrator, have you ever come across the requirement of partially exporting JIRA into XML – probably for importing individual projects into another JIRA instance?

If yes, this might work for you. However, my work is incomplete and experimental. This worked with a small JIRA instance (100 issues), and failed with a huge JIRA instance (1 million issues).

Here’s the Python script I wrote for deleting projects from JIRA XML backup:


from lxml import etree

#xp = etree.XMLParser(encoding='utf-8', recover=True)
#doc = etree.parse('entities.xml', xp)
doc = etree.parse ('entities.xml')

# Array of project keys
plist = ['ABC', 'DEF', 'GHI']

for x in plist:
    for p in doc.xpath ("//Project[@key!=\'" + x + "\']"):
        #p.get entities and delete
        pi = p.get("id")
        for i in doc.xpath ("//Issue[@project=\'" + pi + "\']"):
            ii = i.get("id")
            for cfv in doc.xpath ("//CustomFieldValue[@issue=\'" + ii + "\']"):
            for cg in doc.xpath ("//ChangeGroup[@issue=\'" + ii + "\']"):
                cgi = cg.get("id")
                for ci in doc.xpath ("//ChangeItem[@group=\'" + cgi + "\']"):
            for fa in doc.xpath ("//FileAttachment[@issue=\'" + ii + "\']"):
            for il in doc.xpath ("//IssueLink[@source=\'" + ii + "\']"):
            for il in doc.xpath ("//IssueLink[@destination=\'" + ii + "\']"):
            for na in doc.xpath ("//NodeAssociation[@sourceNodeEntity=\'Issue\' and @sourceNodeId=\'" + ii + "\']"):
            for wl in doc.xpath ("//Worklog[@issue=\'" + ii + "\']"):
            for c in doc.xpath ("//Action[@issue=\'" + ii + "\']"):
        for na in doc.xpath ("//NodeAssociation[@sourceNodeEntity=\'Project\' and @sourceNodeId=\'" + pi + "\']"):
        for c in doc.xpath ("//Component[@project=\'" + pi + "\']"):
        for v in doc.xpath ("//Version[@project=\'" + pi + "\']"):
        for a in doc.xpath ("//ProjectRoleActor[@pid=\'" + pi + "\']"):
        for pk in doc.xpath ("ProjectKey[@projectId=\'" + pi + "\']"):

f = open ('entities.new.xml', 'w')
f.write (etree.tostring(doc, pretty_print=True, xml_declaration=True))

Before you run this, you need to unzip the JIRA XML backup which is a zip archive containing two or three XML files. Put the script file in the same directory where you have the unzipped XML files and run it. It will produce output into file ‘entities.new.xml’. Once completed, replace ‘entities.xml’ by ‘entities.new.xml’, remove the Python script and re-pack the folder into a new zip file. Now it is ready to be imported into another JIRA instance.

Please note that this is incomplete and I cannot guarantee 100% success. You can easily follow the structure of this code and improve it by yourself.

උබුන්ටුවේ සිංහලෙන් ලියමු

උබුන්ටු වලට සිංහල දාන හැටි? කැම්පස් කාලෙ ලියාපුවනේ…! 😀

හරි. එහෙනම් චූටි ළමයි ටික ඉස්සෙල්ලම අහගන්න. මීට අවුරුදු හත අටකට කලින් ඔය ළමයි ඉස්කෝලෙ යන කාලෙ උබුන්ටු වලට සිංහල දානව කියන්නෙ වෙනමම ගේමක්. ඒ දවස් වල අපි අළුතින් වින්ඩෝස් හෝ ලිනක්ස් ඉන්ස්ටෝල් කළ ගමන්ම ඊළඟට දාගන්න එක තමා සිංහල යුනිකෝඩ් කියන්නෙ. ඊටත් කලින්, වින්ඩෝස්, ලිනක්ස් ඔය ඔක්කොටම සම්මතයක් විධියට සිංහල යුනිකෝඩ් එක ගේන්න විවිධ බාධක මැද තවත් පිරිසක් තමන්ගෙ කාලය, ශ්‍රමය කැප කරමින් ගොඩක් මහන්සි වුණා. තවත් පිරිසක් සිංහල භාවිතය ප්‍රචලිත කරන්න ලොකු වෙහෙසක් දැරුවා. ඒකෙ ප්‍රතිපලයක් විධියට, අද වෙනකොට අළුතින් වින්ඩෝස් හෝ ලිනක්ස් ඉන්ස්ටෝල් කළාම සිංහල ඉන්ස්ටෝල් කරන්න ඕනෙ කියන එක අමතක වෙන තරමටම අද අපි සිංහල භාවිතා කරනවා. වෙන එකක් තියා, සිංහලෙන් ලියන එක පොෂ් මදි වගේ දැනිච්ච අයත් අද අපූරුවට සිංහලෙන් ලියනවා. සිංහල තමා දැන් ට්‍රෙන්ඩ් එක! 🙂

ඉතින් ඔය වැඩේ කරන හැටි මතක තියාගන්න අමාරු නිසා අපි උදව් ගත්තේ sinhala.sf.net කියන අඩවියෙන්. හැබැයි මේ අඩවිය 2009න් පසුව යාවත්කාලීන වෙලා නැහැ. එදාට වඩා අද උබුන්ටු වලට සිංහල දානවා කියල කරන්න තියෙන්නෙ input method එක දාගන්න එක විතරයි. පෙරනිමියෙන් දීලා තියෙන phonetic method එකට වඩා ඉතා පහසු විජේසේකර යතුරුපුවරුව හදාගන්න මෙන්න මේ ටික කළා නම් හොඳටම ඇති. Ctrl + Alt + T ගහලා අරින්න ටර්මිනල් එකක්..

$ sudo apt-get install ibus-m17n m17n-db m17n-contrib
  1. System Settings –> Text Entry
  2. (+) ලකුණ ක්ලික් කරලා wijesekara කියල ටයිප් කළාම එන එක එකතු කරගන්න.
  3. “Switch to next source using:” කියන තැන ක්ලික් කරලා Left Alt + Left Shift තද කරන්න – නැත්තම් ඉංග්‍රීසි-සිංහල අතර මාරු වෙන්න තමන්ට පහසු යතුරු සංයෝජනයක් ඇතුළත් කරන්න.

ඉතාම සරලයි. 🙂

දැං ෆේස්බුකියේ ලිය ලිය ඉන්න ගමන් Left Alt + Left Shift ප්‍රෙස් කළ ගමන් එතනින් එහාට ලියවෙන්නෙ සිංහලෙන්. ආපහු ඒකම කළාම ආපහු ඉංග්‍රීසි.

ප.ලි. –
විජේසේකර සිස්ටම් එක අමාරුද? මගේ ඇඟිලි ඊට වඩා අමාරු එකක් මේ දවස් වල පුරුදු වෙනවා. ඒ තමා ගිටාර් එකේ F කෝඩ් එක ප්ලේ කරන හැටි.

Cisco AnyConnect VPN for Ubuntu Xenial?

Post-upgrade first World problems are here.

A friend who recently upgraded to Ubuntu 16.04 Xenial Xerus LTS told me that Cisco AnyConnect VPN doesn’t work anymore. So I wanted to give it a try.

In Ubuntu 14.04 what you’d normally do is installing the three packages network-manager-openconnect, network-manager-openconnect-gnome and openconnect (or may be two of them – can’t recall).

However, this no longer works. You can install the packages but you will no longer see the “Cisco AnyConnect compatible” OpenConnect option when you attempt to create a new VPN connection.

What now? Back to basics!

Hit Ctrl+T to get a terminal and here’s all what you have to do:

$ sudo openconnect --setuid=`id -u` --user=shaakunthala vpn.provider.com
  • Replace shaakunthala with your username in the VPN server.
  • Replace vpn.provider.com with your actual VPN provider’s hostname.

Hit Ctrl+C to disconnect.

Surf and enjoy!

Getting old Truecrypt to work with Xenial

Truecrypt died two years back.

Despite their warning I continued to use it for encrypting some of my data, because I believe Truecrypt was rather killed by a hidden hand – not actually because of any unfixable vulnerabilities.

So, straight to the topic; a new Ubuntu LTS is here and everyone is upgrading. I wanted to install it from the scratch this time. Therefore first of all I took backups using Truecrypt that I have been using since 2014. (My laptop had Ubuntu 14.04 LTS until right now)

All went so smooth until I tried to mount my encrypted Truecrypt volume with the previous Truecrypt 7.1a binary I had. It has been previously compiled into one single executable binary, and the architecture was the same (x86_64).

The error was;

error while loading shared libraries: libwx_gtk2u_adv-2.8.so.0: cannot open shared object file: No such file or directory

Mmm… dependency problem! I tried to install libwxgtk-2.8 from official Ubuntu Xenial Xerus repositories, but the only available version was 3.0. Installing version 3.0 did not address the issue.

After trying out a couple of other options I figured out that easiest option is directly downloading and installing dependencies from the Launchpad. It fixed the issue!

So, this is what worked for me:

$ cd /usr/bin
$ sudo ln -s /opt/truecrypt truecrypt    #Note: I put my previous binary in /opt
$ mkdir /tmp/wx
$ cd /tmp/wx
$ wget http://launchpadlibrarian.net/219037037/libwxgtk2.8-0_2.8.12.1+dfsg2-2ubuntu2_amd64.deb
$ wget http://launchpadlibrarian.net/219037033/libwxbase2.8-0_2.8.12.1+dfsg2-2ubuntu2_amd64.deb
$ sudo dpkg -i *.deb
$ truecrypt &

I believe this is the time I should be looking for an alternative encryption solution, because eventually dependencies will also get old and die, completely killing Truecrypt.


[Ubuntu] “not a com 32R image” boot error

A new LTS is here and it’s the season for upgrades.

I downloaded Ubuntu 16.04 Desktop 64-bit and wanted to give it a try. First thing I would normally do is installing it on a virtual machine. So I could install software, customize, shake it, break it and feel how it works.

Next thing is preparing a startup USB stick (I don’t use DVDs) and booting up my laptop to test it. And here I kept getting this error when booting up.

Missing parameter in configuration file. Keyword: path
GFX BOOT.c32: not a com 32R image

And, finally I got it after a bit of trial and error. If I create the startup disk from the VM, this error doesn’t occur and it boots up the machine.


The culprit I suspect here is BIOS. For years I’ve had enabled the BIOS compatible legacy boot mode on top of UEFI in my laptop.

If I create the startup USB stick through the currently installed Ubuntu on my laptop, Startup Disk Creator thinks my computer boots with UEFI, so it prepares the USB stick to be booted up with UEFI.

If I create the startup disk using the VM which is BIOS (by directly presenting the USB stick to VM), Startup Disk Creator does it the way it is supposed to do in a BIOS environment.

That’s my hypothesis. I don’t have a conclusion yet, but if you use legacy boot options in your computer’s startup settings, create Ubuntu startup USB stick using a computer that has true BIOS. Or, switch to UEFI booting for good.

Got anything to add?