Categories
Linux Python Raspberry Pi

What I’m working on: a Raspberry Pi digital photo frame

Intro
The idea is that for a display kiosk let’s have a Raspberry Pi drive a display like one of those electronic picture frames. Power the thing up, perhaps plug in a flash drive, leave off the mouse and keyboard, but have a display attached, and get it to where it just automatically starts a slideshow without more fuss.

Some discarded options
Obviously this is not breaking new ground. you can find many variants of this on the Internet. An early-on approach that caught my eye is flickrframe. I read the source code to learn that at the end of the day it relies on the fbi program (frame buffer imageviewer). I thought that perhaps I could rip out the part that connects to Flickr but it seemed like too much trouble. At the end of the day it’s just a question of whether to use fbi or not.

Then there’s Raspberry Pi slideshow. That’s a quite good write-up. That’s using pqiv. I think that solution is workable.

But the one I’m focusing on uses qiv. You would have thought that pqiv would rely on qiv (quick image viewer) but it appears not to. So qiv is a separate install. qiv has lots of switches so it’s been written with this kind of thing in mind it seems.

What it looks like so far

#!/bin/sh
# -f : full-screen; -R : disable deletion; -s : slideshow; -d : delay <secs>; -i : status-bar;
# -m : zoom; [-r : ranomdize]
# this doesn't handle filenames with spaces:
##cd /media; qiv -f -R -s -d 5 -i -m `find /media -regex ".+\.jpe?g$"`
# this one does:
if [ "$1" = "l" ]; then
# print out proposed filenames
  cd /media; find . -regex ".+\.jpe?g$"
else
  sleep 5
  cd /media; find . -regex ".+\.jpe?g$" -print0|xargs -0 qiv -f -R -s -d 5 -i -m
fi

The idea being, why not make a slideshow out of all the pictures found on a flash drive that’s been inserted into the Pi? That’s how a standard picture frame works after all. It’s a very convenient way to work with it. That’s the aim of the above script.

Requirements update
OK. Well this happens a lot in IT. We thought we were solving one problem but when we finally spoke with the visual arts team they had something entirely different in mind. They want to mix in movies as well. fbi, pqiv or qiv don’t handle movies. I have mplayer and vlc from my playing around with Raspberry Pi camera. mplayer runs like a dog on the movie files I tried, perhaps one frame update every two seconds. After more searching around I came across omxplayer. That actually works pretty well. It on the other hand doesn’t seem up to the task of handling a mixed multimedia stream of stills and movies. But it did handle the two movies types we had: .mov and .mp4 movie files. omxplayer is written specifically for the Pi so it uses its GPU for frame acceleration. mplayer just seems to rely on the CPU which just can’t keep up on a high-def quality movie. So as a result omxplayer will only play through a true graphical console. It doesn’t even bother you to get your DISPLAY environment variable set up correctly – it’s just going to send everything to the head display.

Overheard recently
And when using my TV as display omxplayer put out the sound, too, perfectly synchronized and of high quality.

I was thinking if we should kludge stitching together qiv and omxplayer. You know letting one lapse and starting up the other to transition from a still to a movie, but I don’t know how to make the transition smooth. So i searched around yet some more and found pipresents. I believe it is a python framework around omxplayer. It’s pretty sophisticated and yet free. It’s actually aimed at museums and can include reactions to pressed buttons as you have at museum displays. So far we got the example media show to loop through – it demonstrates a high-quality short movie and a still plus some captions at the beginning.

Pipresents isn’t perfect however
I quickly found some problems with pipresents so I went the official route and posted them to the github site, not really knowing what to expect. The first issue is that you are not allowed to import .mov files! That makes no sense since omxplayer plays them. So I post this bug and that very same day the author emails me back and explains that you simply edit pp_editor.py line 32 and add .mov as an additional video file type! Sure enough, that did it. Then I found that it wasn’t downsampling my images. These days everyone has a camera or phone that takes mmulti-megapixel images far exceeding a cheap display’s 1280×1024 resolution. So you only see a small portion of your jpeg. I just assumed pipresents would downsample these large pictures because the other packages like qiv do it so readily. Again the same day the author gets back to me and says no this isn’t supported – in pipresents. But there is a solution: I should use pipresents-next! It’s officially in beta but just about ready for production release. I don’t think I’ll go that route but it’s always nice to know your package continues to be developed. I’ve written my own downsampler which I will provide later on.

Screen turns off
The pipresents has a command-line switch, -b, to prevent screen blanking. But I think in general it’s better to not use that switch and instead disable screen blanking in general.

$ sudo nano /etc/kbd/config
– change BLANK_TIME=30 to BLANK-TIME=0
– and change POWERDOWN_TIME=30 to POWERDOWN_TIME=0
$ sudo nano /etc/lightdm/lightdm.conf
– below the [SeatDefault] line create this line:
xserver-command=X -s 0 dpms

How to get started with PiPresents
$ wget https://github.com/KenT2/pipresents/tarball/master -O – | tar xz

There should now be a directory ‘KenT2-pipresents-xxxx’ in your home directory. Rename the directory to pipresents:

$ mv KenT2* pipresents

To save time make sure you have two terminal windows open on your Pi and familiarize yourself with how to cut and paste text between them. Then from the one window you can:

$ cd pipresents; more README.md

while you execute the commands you’ve cut and paste from that window into the other, e.g.,

$ sudo apt-get install python-imaging
etc.

What happens if you forget to install the unclutter package
Not much. It’s just that you will see a mouse pointer in the center of the screen which won’t go away, which is not desirable for black box operation.

Python image downsizing program
This is also known as downsampling. Amazingly, you really don’t find a simple example program like this when you do an Internet search, at least not amongst the first few hits. I needed a program to reduce the large images to the size of the display while preserving the aspect ratio. My display, a run-of-the-mill Acer v173, is 1280 x 1024 pixels. Pretty standard stuff, right? yet the Pi sees it as 1232 x 992 pixels! Whoever would have thought that possible? And with no possible option to change that (at least from the GUI). So just put in the appropriate values for your display. This program just handles one single image file. also note that if it’s a small picture, meaning smaller than the display, it will be blown up to full screen and hence will make a thumbnail image look pixelated. The match doesn’t distinguish small from large images but I fel that is fine for the most part. So without further chatting, here it is. I called it resize3.py:

import Image
import sys
# DrJ 2/2015
# somewhat inspired by http://www.riisen.dk/dop/pil.html
# image file should be provided as argument
# Designed for Acer v173 display which the Pi sees as a strange 1232 x 992 pixel display
# though it really is 1 more run-of-the-mill 1280 x 1024
 
imageFile = sys.argv[1]
im1 = Image.open(imageFile)
 
def imgResize(im):
# Our display as seen by the Pi is a strange 1232 x 992 pixels
    width = im.size[0]
    height = im.size[1]
 
# If the aspect ratio is wider than the display screen's aspect ratio,
# constrain the width to the display's full width
    if width/float(height) > 1232.0/992.0:
      widthn = 1232
      heightn = int(height*1232.0/width)
    else:
      heightn = 992
      widthn  = int(width*992.0/height)
 
    im5 = im.resize((widthn, heightn), Image.ANTIALIAS) # best down-sizing filter
 
    im5.save("resize/" + imageFile)
 
imgResize(im1)

As I am not proficient in python I designed the above program to minimize file handling. That I do in a shell script which was much easier for me to write. Together they can easily handle downsampling all the image files in a particular directory. I call this script reduce.sh:

#!/bin/sh
echo "Look for the downsampled images in a sub-directory called resize
echo "JPEGs GIFs and PNGs are looked at in the current directory
mkdir resize 2>/dev/null
ls -1 *jpg *jpeg *JPG *png *PNG *gif *GIF 2>/dev/null|while read file; do
  echo downsampling $file
# downsample the image file
  python ~/resize3.py "$file"
done

Stopping the slideshow
Sometimes you just need to stop the thing and that’s not so easy when you’ve got it in blackbox mode and running at startup.

If you’re lucky enough to have a keyboard attached to the Pi we found that

<Alt> F4

from the keyboard stops it.

No keyboard? We assigned Our Pi a static IP address and leave an ethernet cable attached to it. Then we put a PC on the same subnet and ssh to it, e.g., using putty or teraterm. Then we run this simple kill script, which I call kill.sh:

#!/bin/sh
pkill -f pipresents.py
pkill omxplayer

Digital photo frame projects morphs to museum-style kiosk display
At times I was tempted to throw out this pipresents software but we persisted. It has a different emphasis from a digital photo frame where you plug in a USB stick and don’t care about the order the pictures are presented to you. pipresents is oriented towards museums and hence is all about curated displays, where you’ve pored over the presentation order and selected your mix of videos and images. And in the end that better matched our requirements.

The manual is wanting for clarity
It’s nice that a PDF manual is included, but it’s a pain to read it to extract the small bits of information you actually need. Here’s what you mostly need to know. An unattended slideshow mixture of images and videos is what he calls a mediashow. Make your own profile to hold your mediashow:

$ cd pipresents; python pp_editor.py

This brings up a graphical editor. Then follow these menus:

Profile|New from template|Mediashow

Choose a short easy-to-type name such as drjmedia.

Click on media.json and then you can start adding images and movies. These are known as “tracks.”

Remove the example track.

Add your own images and movies.

Do a Profile|Validate

There is no Save! Just kill it.

And to run it full screen from your home directory:

$ python pipresents/pipresents -ftop -p drjmedia

Autostarting your mediashow
The instructions provided in the manual.pdf worked on my older Pi, but not on the B+ model Pis. So to repeat it here, modifying it so that it is more correct (the author doesn’t seem comfortable with Linux). Manual.pdf has:

$ mkdir -p ~/.config/lxsession/LXDE
$ cd !$; echo "python pipresents/pipresents.py -ftop -pdrjmedia" > autostart
$ chmod +x autostart

And as I say this worked on my model B Pi, but not my B+. The following discussion about autostarting programs is specific to operating systems which use the LXDE desktop environment such as Raspbian. On the B+ this fairly different approach worked to get the media show automatically starting upon boot:

$ cd /etc/xdg/autostart

Create a file pipresents.desktop with these lines:

[Desktop Entry]
Type=Application
Name=pipresents
Exec=python pipresents/pipresents.py -ftop -pdrjmedia
Terminal=true

But I recommend this approach which also works:

$ mkdir ~/.config/autostart

Place a pipresents.desktop file in this directory with the contents shown above.

More sophisticated approach for better black box operations
We find it convenient to run pp_editor in a virtual display created by vnc. Then we still don’t need to attach keyboard or mouse to the Pi. But the problem is that pipresents will also launch in the vnc session and really slow things down. This is a solution I worked out to have only one instance of pipresents run, even if others X sessions are launched on other displays. Note that this is a general solution and applies to any autostarted program.

The main idea is to test in a simple shell script if our display is the console (:0.0) or not.

I should interject I haven’t actually tested this but I think it’s going to work! Update: Yes, it did work!

Put startpipresents.sh in /home/pi with these contents:

#!/bin/bash
# DISPLAY environment variable is :0.0 for the console display
echo $DISPLAY|grep :0 > /dev/null 2>&1
if [ "$?" == "0" ]; then
#  matched. start pipresents in this xsession, but not any other one
  python pipresents/pipresents.py -ftop -pdrjmedia
fi

Then pipresents.desktop becomes this:

[Desktop Entry]
Type=Application
Name=pipresents
Exec=/home/pi/startpipresents.sh
Terminal=true

To install the vnc server:

$ sudo apt-get install tightvncserver

And to auto-launch it make a vnc.desktop file in ~/.config/autostart like this:

[Desktop Entry]
Type=Application
Name=vncserver
Exec=/home/pi/startvncserver.sh
Terminal=false

and put this in the file /home/pi/startvncserver.sh:

#!/bin/bash
# DISPLAY environment variable is :0.0 for the console display
echo $DISPLAY|grep :0 > /dev/null 2>&1
if [ "$?" == "0" ]; then
#  matched. start vncserver in this xsession, but not any other one
  vncserver
fi

You need to launch vncserver by hand once to establish the password.

And we may as well pre-launch the pp_editor because we’re likely to need that. So make a file in the home directory called startppeditor.sh with these contents:

#!/bin/bash
# DISPLAY environment variable is :1.0 for the vnc display
echo $DISPLAY|grep :1 > /dev/null 2>&1
if [ "$?" == "0" ]; then
#  matched. start ppeditor in this xsession, but not any other one
  python pipresents/pp_editor.py
fi

and in ~/.config/autostart a file called ppeditor.desktop with these contents:

[Desktop Entry]
Type=Application
Name=ppeditor
Exec=/home/pi/startppeditor.sh
Terminal=true

Similarly we can pre-launch an lxterminal because we’ll probably need one of those. Here’s an example startlxterminal.sh:

#!/bin/bash
# DISPLAY environment variable is :1.0 for the vnc display
echo $DISPLAY|grep :1 > /dev/null 2>&1
if [ "$?" == "0" ]; then
#  matched. start a large lxterminal in this xsession, but not any other one
  lxterminal --geometry=100x40
fi

and the autostart file:

[Desktop Entry]
Type=Application
Name=lxterminal
Exec=/home/pi/startlxterminal.sh
Terminal=true

A note about Powerpoint slides
With a Macbook we were able to read in a Powerpoint slideshow and export it to JPEG images, one image per slide. That was pretty convenient. We have done the same directly from Microsoft Powerpoint – it’s a save option.

A note about Mpeg4 videos
Some videos overwhelm these older Pis that we use. Maybe on the Pi 3 they’d be OK? A creative student would hand us his 2 minute movie in mpeg4 format. The Pi would never be able to display it. We learned you can reduce the resolution to get the Pi to display it. A student was doing this on his Macbook, but when he left i had to figure out a way.

The original mpeg4 video had resolution of 1920 x 1080. I wanted to have horizontal resolution of no more than 1232, but maybe even smaller, while preserving the aspect ratio (widescreen format).

I used good ole’ Microsoft Movie Maker. I don’t think it’s available any longer except from dodgy sites, but in the days of Windows 7 you could get it for free through Windows Live Update. Then, if you upgraded that Windows 7 PC to Windows 10, it allowed you to keep Movie Maker. That’s the only way I know of. Not that it’s a good program. It’s not. Very basic. But it does permit resizing a video stream to custom resolution, so I have to give it that. I tried various resolutions nd played them back. i finally settled on the smallest I tried: 800×450. In fact I couldn’t really tell the difference in video quality between all the samples. And of corse 800×450 made for the smallest file. So we took that one. Fortunately, pipresents blew it up to occupy the full screen width (1232 pixels) while preserving the aspect ratio. So it looks great and no further action was needed.

The sound of silence
You want the video sound to come out the stereo mini-jack because you’re not using an HDMI monitor? PiPresents tries to send audio out through HDMI by default so you won’t hear the sounds if you have a VGA monitor. But you can change that. If you want to do this in raw omxplayer the switch which sends the sound out through the mini-jack is:

omxplayer -o local

In pipresents this option is available in the pp_editor. It’s a property of the profile. So you edit the profile, look for omx-audio, and change its value in the drop-down box from hdmi to local. That’s it!

A word about DHCP
We use a PC to connect to the four Pis. They are connected to a hub and there is an Ethernet cable connected to the hub and ready to be connected to a PC with an Ethernet port. The Pis all have private IP addresses: 10.31.42.1, 10.31.42.2, 10.31.42.3 and 10.31.42.4. For convenience, we set up a DHCP server on Pi 1 so that when the PC connects, it gets assigned an IP address on that subnet. DHCP is a service that dynamically assigns IP addresses. Turns out this is dead easy. You simply install dnsmasq (sudo apt-get install dnsmasq) and make sure it is enabled. That’s it! More sophisticated setups require modification of the file /etc/dnsmasq.conf, but for our simple use case that is not even needed – it just picks reasonable values and assigns an appropriate IP to the laptop that allows it to communicate to any of the four Pis.

References and related
I worked on this project with a student. Building a Four Monitor Media Show using Raspberry Pis
Pipresents has its own wordpress site.

LXDE has its own official site.
Read about a first look at the custom-built 7″ Raspberry Pi touch display in this blog post.

An alternative slideshow program to pipresents is to leverage qiv. I put something together and demo it in this post, but with a twist: I pull all the photos from my own Google Drive, where I store 40,000+ pictures!

Categories
Admin Web Site Technologies

A day in the life of an IT Specialist

Intro
I’m not saying every day is like this, and I’m compressing several days into one narrative, but you’ll quickly get the idea and see the difficulties we face. As I like to joke this is why we make the medium bucks.

The single remaining guy responsible for the in-house application environment has finally convinced the powers that be to upgrade IBM WebSphere from a five-year-old version to version 8.5. We traditionally use a web server front-end which I have traditionally supported. So I get tapped to figure out what to do for new web servers.

I get three enormous zip files from him and nothing else.

I happen upon a documentation file containing a link to an IBM web site and not much else. I go there. The installation mentions using IBM Installation Manager. Never heard of it. I ask the guy for that.

Get it and unpack. Try to find documentation on how to install the Installation Manager and none seems to exist. Isn’t that ironic?

I wing it and try to run a file with the promising name of install:

$ sudo ./install

 sudo ./install
00:02.01 ERROR [main] org.eclipse.equinox.log.internal.ExtendedLogReaderServiceFactory safeLogged
  Application error
  org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
  org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
    at org.eclipse.swt.SWT.error(SWT.java:4387)
    at org.eclipse.swt.widgets.Display.createDisplay(Display.java:913)
    at org.eclipse.swt.widgets.Display.create(Display.java:899)
    at org.eclipse.swt.graphics.Device.<init>(Device.java:156)
    ...
Install:
An error has occurred. See the log file
/tmp/IBMinstall/configuration/1420812667336.log.

The logfile referred to contains this “helpful” information:

!SESSION 2015-01-09 09:11:05.439 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.6.0_24
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=solaris, ARCH=sparc, WS=gtk, NL=en
Framework arguments:  -toolId install -accessRights admin input @osgi.install.area/install.xml
Command-line arguments:  -os solaris -ws gtk -arch sparc -toolId install -accessRights admin input @osgi.install.area/insta
ll.xml
 
!ENTRY org.eclipse.osgi 4 0 2015-01-09 09:11:12.346
!MESSAGE Application error
!STACK 1
org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
        at org.eclipse.swt.SWT.error(SWT.java:4387)
        at org.eclipse.swt.widgets.Display.createDisplay(Display.java:913)
        at org.eclipse.swt.widgets.Display.create(Display.java:899)
        at org.eclipse.swt.graphics.Device.<init>(Device.java:156)
        at org.eclipse.swt.widgets.Display.<init>(Display.java:497)
        at org.eclipse.swt.widgets.Display.<init>(Display.java:488)
        at org.eclipse.ui.internal.Workbench.createDisplay(Workbench.java:669)
        at org.eclipse.ui.PlatformUI.createDisplay(PlatformUI.java:161)
        at com.ibm.cic.agent.internal.ui.AgentUIApplication.initDisplay(AgentUIApplication.java:140)
        at com.ibm.cic.agent.internal.ui.AgentUIApplication.launch(AgentUIApplication.java:162)
        at com.ibm.cic.agent.internal.ui.AgentUIApplication.start(AgentUIApplication.java:64)
        at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
        at org.eclipse.equinox.launcher.Main.main(Main.java:1414)

The references to Display hint that my display is goofed up. Which it is. I have no X display.

So I have to export the DISPLAY to another utility server where I can run vncserver.

Oops. That server was rebooted and so there is no vncserver currently running. I launch that:

$ vncserver :2

Now I can connect to it from my desktop using the VNC client, fire up an xterm and allow others to export their displays to it:

$ xhost +

Now I go back to Solaris and set my DISPLAY environment variable:

$ export DISPLAY=vncserver_name:2

And re-install. This time it comes up. The screen dialogs are very sluggish but very simple. I get it going just before 9:30 AM. The status bar creeps over to the right veerrrry slowly. at 10 AM it is finally done – for a package of size 297 MB! But I can do other work in the meantime. Hey, they can’t do backups any longer on a firewalled subnet. may be a problem with resolving the backup server’s name in this domain. Can I look into it? Yes, the domain name is missing when I query the authoritative nameservers. The guy next to me, I happen to know, is the administrator of this special domain. I ask him to look into it.

Meanwhile I unzip disk 1 of the WAS 8.5 download and hunt for the documentation. I find it in readme_plugins/en/readme_en.html. It doesn’t have much, just a few links to IBM web sites. After a few wrong leads I decide there is no direct link. I want to install the plugin file. So I have to interact with the online documentation a bit to get what I want. The documentation is thorough to the point of being bloated and effectively masks whatever it is you actually need out of it. I think I am getting close now after about 15 clicks and skimming loads of crap. The bread crumb trail looks like this so far:

WebSphere Application Server Network Deployment 8.5.5
Network Deployment (Distributed Operating Systmes), Version 8.5
Setting up intermediary services (who knew?)
Implementing a web server plugin
Installing and configuring web server plugins
Installing and uninstalling the Web Server Plug-ins on distributed operating systems

I’m still not sure I’ve struck meat yet. I just feel I am getting close now! No, actually there is another level:

Installing the Web Server plugins using the GUI

From this document, which actually contains some useful information, I get the imp[ression that I may need a repository set up, whatever that is.

I find and launch the IBM Installation Manager regardless to see what it does. I found its path as /opt/IBM/InstallationManager/eclipse/IBMIM. Click on the Install option and sure enough it complains I have no repository setup. It offers a link to do that.

After some futzing it seems to lead me to click on a repository config file in /opt/IBM/InstallationManager/eclipse/repository.config. But that may be a fools errand because when I re-launch it says the repository is not connected. Huh?

So then I try to specify a URL as repository, but to connect that I need an IBM username/password which i don’t have. I ask my colleague for one.

Meanwhile I re-examine the unzipped 1 of 3 zip file for WAS 8.5 and I see a repsitory.config file there! So after some fumbling with the slow and awkward Installation Manager GUI I manage to indicate that as my repository config file and delete the original one I had configured. This looks promising. Now I see an option to select IBM WebServer plugins. Looking good.

Interruption. You know that SHA2 certificate you got last year? We don’t think it’s really gong to work and can you get an SHA1 one instead? I am doubtful at this late stage but I promise to ask my contacts and fire off some emails.

The installation needs disk2 so I have unzip that one; then disk3. Now I’m out of space and move things around before unzipping that one. I am soon able to hit the Install button and seven minutes later the 389 MB package is installed.

I see it hasn’t asked me which web server I use and where it is and all that. So clearly I need some more steps. Rummaging around I come across /opt/IBM/WebSphere8.5/Plugins/bin/ConfigureApachePlugin.sh, which sounds pretty promising.

I run that and see there are a bunch of switches I have to provide values for. No problem. I get those and it runs. I examine what it has done to my config file and it looks partially promising and partially puzzling. It relies on an environment variable which I don’t think it has defined.

I stop the server and it already complains about that very thing:

httpd: Syntax error on line 344 of /usr/local/apache203/conf/httpd.conf: Syntax error on line 183 of /usr/local/apache203/conf/vhosts/secure-siteinfo.conf: Cannot load /usr/local/apache203/${WAS_PLUGIN_DRIVER} into server: ld.so.1: httpd: fatal: /usr/local/apache203/${WAS_PLUGIN_DRIVER}: open failed: No such file or directory

I define that variable. And try to stop it again. The next error kind of scares me:

httpd: Syntax error on line 344 of /usr/local/apache203/conf/httpd.conf: Syntax error on line 183 of /usr/local/apache203/conf/vhosts/secure-siteinfo.conf: Cannot load /opt/IBM/WebSphere8.5/Plugins/bin/64bits/mod_was_ap22_http.so into server: ld.so.1: httpd: fatal: /opt/IBM/WebSphere8.5/Plugins/bin/64bits/mod_was_ap22_http.so: wrong ELF class: ELFCLASS64

To me that hints I may have the wrong architecture installed. I run some control tests:

$ file /opt/IBM/WebSphere8.5/Plugins/bin/64bits/mod_was_ap22_http.so

/opt/IBM/WebSphere8.5/Plugins/bin/64bits/mod_was_ap22_http.so:  ELF 64-bit MSB dynamic lib SPARCV9 Version 1, dynamically linked, not stripped

and now compared to my apache binary:

$ file /usr/local/apache2/bin/httpd

/usr/local/apache2/bin/httpd:   ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped

I check with the system administrator if he had ever provided me a 64-bit apahce package for Solaris. After some checking we realize that Solaris 10 does provide an apache package but it is 32-bit.

I have an idea. I can simply change the path to the shared object file in my environment definition:

export WAS_PLUGIN_DRIVER=/opt/IBM/WebSphere8.5/Plugins/bin/32bits/mod_was_ap22_http.so

I had originally specified 64bits. Maybe this will be compatible. My first thought is that I installed the wrong package and would have to ask for a different download.

Yess! It now stops. And it starts. And I can access its homepage.

Now go into its config and change its home page to the same as used by the Sun Java System web server.

Find a page that actually calls out to WebSphere by examining the log files and grepping for js (just a hunch). I find something. Try to reproduce it with curl on the real web server and I get a not found. Hmm. Work harder to match up the host header to the vhosts mentioned in the plugin config file. Specifying the right host it gives me a redirect and sets some cookies. I know the web server isn’t programmed to do that so I must have reached the back-end WebSphere app server and now I have something to test with. Test against the port running apache with this WAS config file and it produces the same result! A redirect and some cookies. Great. The hardest part is over. Now a control. We’ll remove the plugin config line in the apache config and re-try it. Yup. 404 not found. We really are communicating to the app server.

No way I am going to go through that pain for each and every server where this is needed. I’ll just tar up the needed files and untar them on any server where this is needed.

But I wonder if I should use the provided apache instead.

Interruption. We’ve received a corrupt pdf file in email two months ago. The vendor is mad at us because we are the only ones with this problem. Could our systems have corrupted an attachment? This is kind of an interesting question and deserves some rumination. The quick reaction is no we don’t do that. But years of experience tell me that exceptions abound. I open the attachment. Yup, corrupted. I save the file in an effort to examine the bytes. Then I see it has 0 length, That’s peculiar. I’ve never seen that around here. Then I think to check our mail server log files two months back for their record. I quickly find it and see that its size was reported as 34000 bytes. That strikes me as kind of large for a message with no attachment, but kind of small for a pdf attachment. I share my results with the requester.

Answer: they can still issue an SHA1 CERT. But probably only one which has a year’s duration. I tell the customer for this certificate that all is not rosy as they will probably use an obscure CA which is not accepted by all his customers, so there is no way out without experiencing some pain here.

Unix admin tells me they’re now getting alerts about running out of disk space on the filesystem and system where I put my WebSphere installation downloads. I move another one of those puppies (1 GB in size) to /tmp.

Categories
Admin Network Technologies

Fixing a hanging JunOS Pulse VPN client login

Intro
I often have trouble getting a clean disconnect when shutting down my JunOS Pulse client. As often as not it hangs while displaying Disconnecting… A reboot seemed a little drastic to me so I found a kinder, gentler way to reset things. Read the details if this applies…

The details
When it’s hanging you will have an additional adapter not normally present called JunOS virtual adapter or something like that. To get to this adapter in Windows 7 type network in the Run text box. Click on Network and Sharing Center; then Change adapter settings.

Find the JunOS virtual adapter.

Right-click and disable it.

That’s it!

Your disconnect should then complete and the virtual adapter will eventually disappear on its own. I imagine you would need administrator access to your PC in order to be able to do this.


The catch

And this is a very big catch. This did save me a reboot as promised. But it has a huge drawback. The next time you try to use the JunOS Pulse client it will never finish connecting! So while it is trying to connect you have to repeat the steps above but this time enable the adapter!

I was really stumped when I first encountered this problem and couldn’t connect.

Why does this work?
Well, the symptoms I was experiencing during hanging is that the virtual adapter JunOS creates is present and keeps its IP address, as you can see form an output of ipconfig /all. So I thought there should be a way to remove the adapter with a command-line command. But when I clicked on the adapter I reasoned that if I could simply remove the IP address then I would achieve what I needed and restore my regular connectivity. Disabling it did that and it worked!

How do I get myself in this situation?
I use VPN. Then I leave my laptop for a length of time. Eventually the laptop hibernates, keeping its memory of running JunOS Pulse. Next I bring it to an office with a physical LAN port and that JunOS virtual adapter is still hanging around upon wake-up and the Pulse client is stuck disconnecting.

Conclusion
I have shown a method of saving yourself a reboot if your JunOS Pulse client is hanging upon disconnecting. However I have given you enough rope to hang yourself. You will never connect again unless you undo those very same steps the next time you try to connect!

The JunOS Pulse client is provided by Juniper Networks.

References
I explain how to work on a Juniper SA appliance in this post.