Sunday, September 19, 2010

Why are So Many Mom & Pop Retail Stores Run by Idiots?

I just want to offer a bit of general feedback to all those Mom and Pop stores that find themselves trying to compete with large, volume-buyer, retailers. It's acceptable in many circumstance to charge a little extra for the things you sell. Everyone probably understands that you can't discount your prices as much as a Wal-Mart type store that buys the same item in multiples of a billion. However, if the only way you think you can stock a common (i.e. non-specialty) item is to charge way over list price for it, you'd be better off just not stocking it at all. When your customer finds out they've been dramatically overcharged, it will likely be the very last thing you sell to that customer.

I recently visited "The Country Pedaler" in Castle Rock, CO on the way to a mountain bike ride to pick up an innertube, just in case I had a flat on the ride that couldn't be patched. It's a small shop, so I went in expecting to pay up to the full retail list price for the tube. The store location was convenient because it was along the way to the trailhead, so I didn't even mind paying a bit more than I would have paid for that item at a larger bike store like BikeSource or Performance Bicycle. I had never bought a tube of the particular size I needed so I wasn't sure what its normal price should be. I was charged $10.00, which I thought was a little high, but I trusted that even if the price was on the high end of the retail price range for that item, it wouldn't be too different than what I might find elsewhere. So, I considered the convenience factor to be worth maybe 10% or 20% and bought it anyway.

Any time I find that I have been charged more than 40% OVER the full retail list price for a basic, commodity, accessory item (like a bicycle innertube), I can't help but feel I've been ripped off. I found out later that the same exact item has a full retail list price of $7.00. To make things even worse, I found that the price for a similar (maybe even better) quality tube, at other local specialty bike stores, was as low as $5.29. "The Country Pedaler" price was marked up in excess of their competitors by a margin of almost 90%. You read it right, almost double the price other local stores charged for the same simple accessory item. It wasn't hard to find or in short supply. It didn't require special expertise or consultation from a sales person. It was just WAY overpriced.

The tube was the very first thing I purchased from The Country Pedaler bike store, and, because it was so drastically overpriced, it will likely be the VERY LAST thing I purchase from that store. They don't really have any option to correct their mistake now because they've already proven that I can't trust their prices to be even approximately fair, never mind competitive. Offering a refund or price adjustment now wouldn't even change my impression that the store generally charges an exorbitant amount over even full retail list prices. I wonder if it is any consolation to the store's owner that he gets to keep that extra $3.00 profit on that one sale (assuming I don't just return it for a refund) or if he even realizes how much it cost his business to jack up the price on a simple accessory item.

It is possible that I might decide to give The Country Pedaler a second chance several years from now, just to see if they got a clue and changed how they're setting their prices, but for now, they've lost me as a customer. Somehow I doubt the store will survive if they continue to alienate potential customers they way they have with me. I suspect anyone who finds this blog post will be reluctant to do business with them either. I certainly won't be recommending that anyone else visit that shop. In fact, I'll definitely warn them and send them elsewhere whenever possible.

Other mom and pop retailers that wish to keep customers and remain competitive should take this as a warning. You might be able to justify prices closer to full retail because you may be in a more convenient location than the "discounter" shop. Your customers might not even mind spending a little extra with you if you're able to give them more personal attention when they visit your store. But beware if you go beyond "a little extra" on your prices and gouge someone by pricing a relatively insignificant item well over its fair retail price. You're compromising the trust they have in your store, swapping positive word-of-mouth advertising for bad, and forfeiting any profit you might have earned on future purchases. All you gain for that is a few extra bucks, one time... most likely one LAST time.

Saturday, September 18, 2010

Garmin PC Map Updater Software SUCKS

I'd venture a guess that Garmin spends 99+% of its software development resources on the software that is actually on the device. I have experience with Nuvi, eTrex, and Forerunner models and most of the time, the menus, functions, and display options a Garmin GPS device seem to be reasonable and stable. But then Garmin's Windows based tools to support those GPS devices SUCK. I mean they REALLY, REALLY SUCK!! My last 3+ hour episode of utter frustration using one of Garmin's crap-ware tools was while attempting to simply update the Maps on a Nuvi automotive GPS device. I know it costs money to keep map data up to date, but the $90 I had to pay was still a bit steep for the marginal improvement in usability. Roads just don't change that significantly, that often. The map updater software required the following steps before it completed the simple simple task of checking a purchase license, matching it to the device serial number, and transferring map data onto a USB device.

1. Install a "communicator" plugin into the web browser (Firefox). Web browsers already have as their single most definitive purpose, "communicating with web servers" so it is aggravating that Garmin feels it is necessary to introduce additional software to accomplish this for "their" data.

2. Realize that for some unreported, unexplained reason, the Garmin Firefox plugin just doesn't work. No error message appeared suggesting that something was wrong. It just didn't ever "communicate" anything.

3. Install a "communicator" plugin into Microsoft Internet Explorer. IE is not the browser I normally use, so I have to remember this for any other interaction with Garmin's special IE only web site. C'mon Garmin, those days are long gone. Only the worst type of idiot-clown web sites authors still lock their content into IE only.

4. Play a guessing game with the Garmin web site to figure out where exactly they have the page where I can actually purchase the map update product I'm after. Enter credit card information to pay the excessive $90 fee. In my opinion, a GPS device that includes map data, should just include the map data updates for at least 5 years or so as part of the initial purchase price. After all, the pre-loaded map data already a bit out of date when it was first purchased, presumably because it had been sitting on a shelf in a store for a few weeks or months already.

5. Go check email for a link to another web page that contained the download link for the purchased map update data. Listen Garmin, the only reason I should need to give you an email address at all is if I want to receive a receipt or some other notification from you. Once I enter valid credit card information and purchase the maps, JUST FORWARD MY BROWSER DIRECTLY TO THE !@#$% DOWNLOAD PAGE!!!! All you accomplish by making me jump through the email link hoop is to make me even more angry when I get to the next boneheaded step.

6. Realize that after all the hassle and effort to get the communicator plugin working, it was only so I could download a map updater program that must run outside the web browser in order to transfer the map data to the Nuvi USB device. What a colossal waste of time. Please, just cut all the web browser calisthenics and let me jump straight to the download. Any web browser works just fine for that task, without any modification, extensions, plugins or anything.

7. Download and run the map updater program.

8. Watch the map updater program attempt to install Microsoft's .net framework 3.5 in spite of the fact that it was ALREADY INSTALLED on the machine.

9. Watch the .net install step fail and roll back, also without any explanation, which stops the map update process with no obvious next step. Frankly I don't know whether to thank Garmin or Microsoft for this aggravation, but since Garmin chose to require the .net framework, and their map updater program doesn't properly detect whether it is already installed, I'll still give Garmin the blame.

10. Switch to another computer (which is an option Garmin should know isn't available to a large percentage of their customers) and start basically from the beginning again.

11. Install the stupid "communicator" plugin for IE.

12. Poke around Garmin's web site to eventually find the link to download the map updater again.

13. Start the map updater. BTW, the version of the Garmin map updater initially downloaded from the site immediately downloads and installs different version. This happens transparently, but WHY? Once again, Garmin has absolutely no respect for their customer's time. Whenever I have observed other software doing this, it is usually doing something sneaky. My level of trust in Garmin's software was already very low, but this just helped push it well in to negative territory.

14. Wait approximately 1/2 hour while it installs the Microsoft .net framework (and yes it was already installed on this machine too).

15. Scream loud enough for Garmin's software staff to hear every expletive I know, no matter where in the world they happen to be because at this late stage, the map updater finally checks to see if there is even enough free disk space (which is a whopping 5GB on the System (c:) drive BTW) to complete the update process. WHY DIDN'T IT CHECK THAT SIMPLE MATTER UP FRONT. Yikes, how stupid are these people?

16. Since the only machine that would get though all the .net nonsense and run the map updater was a netbook that came pre-partitioned with a small system drive having less than 5GB free, the map updater wouldn't run without playing some space-available tricks. I suspect this is also an option that is not within the know-how limits of the majority of Garmin's customers. Garmin's map updater software offers no options to choose another drive or partition to use for temporary space so if your machine doesn't have at least 5GB free on the C: drive, just give up.

17. After several hours of frustration and false starts trying to get the map updater to run, then you have to leave it all of it running for several hours. Yes, I said SEVERAL HOURS while it downloads, unpacks, and transfers updated data to the device. Just to be sure it is able to make it through this process without making the GPS device into a brick, it would be best to have a redundant internet connection, an uninterrupted power supply, and fix Windows power management settings temporarily so that it never shuts off the hard drives or initiates system stand-by. This process takes a VERY LONG TIME. By the way, the map-updater's downloader client program consumes 100% of your internet connection's available bandwidth making everything else that needs to share the connection slow to a crawl. Garmin, this isn't just amateur network client software design, it is OBNOXIOUS and RUDE!!!

Garmin should be ashamed. How they could so totally screw up such a simple piece of software is utterly perplexing. It has been a very long time since I encountered a software utility, especially something that does nothing more complicated that transferring data from a server to a portable USB device, that was SO COMPLETELY frustrating and so poorly designed. I'm hoping that this blog post eventually costs Garmin as much in lost sales as their crap-ware map updater has cost me in aggravation. Even if it doesn't, maybe it will save someone else some of the annoying troubles getting map updates for their Garmin GPS device.


On a second Nuvi device that I now DEEPLY regret ever having purchased, the Garmin Map Updater software forced a firmware update to the GPS device and WIPED OUT ALL MY ROUTES, ALL MY FAVORITES, and EVERY BIT OF TRACK DATA that I might have been able to capture first or restore later if there had been any indication at all that the crapware was about to wipe it all out. Someone in charge of Garmin's map updater software really needs to be put in prison. There is absolutely no excuse for this blatant disregard for Garmin's customers. I expect there must be a special place in hell for the a**hole who released this stinking pile of garbage into the lives of unsuspecting Garmin Nuvi owners throughout the world. May the responsible person rot in a pit of their own waste.

Monday, March 29, 2010

My Eye!!

Many of the Pixar animated movies have a few catch phrases like "I'm okay!!" or "My Eye!!" Having only been to an eye doctor once before, years ago, to find out if there was any reason to be concerned about "floaters," today I went to find out whether there was anything more to the blurry focus in my right eye than just the ordinary effects of getting older. I was relieved to learn that "I'm okay!!"

I learned a few more things about eyes too that I might have figured out, based on what I know about photography, if I'd given it any thought. For the few weeks prior to the eye exam today, I had been checking each eye under different conditions so I'd have more useful ways to describe how my right eye was bothering me. One thing I had noticed is that in lower lighting, one of my eyes seemed to give me a darker image but the same wasn't true in the brightly lit outdoors. The other thing I noticed is that looking at certain things like a television or the moon seemed to cause double vision worse than other things like a shelf full of small objects or dishes on a table.

So, as it turns out, my right eye is just not focusing quite right any more at a distance. However, that didn't readily explain the comparative brightness in low light only. If I had thought a bit about it, I would probably have remembered that to increase the depth of field, i.e. expand the range of things that are projected sharply on a camera's back-plane, the aperture can be made smaller. This lets less light through, so the projected image, although sharper, is also darker. With a camera, a brighter flash can offset the darker image but with an eye, the available light is fixed. Apparently, one of the things the eye will do in order to compensate for the failure of the lens shape to project a sharp image on the retina is to constrict the pupil to increase the depth of field. So, like a camera with the aperture narrowed, less light gets to the retina. It makes sense that blurry results in darker, but it isn't really obvious.

Double vision puzzled me because it seemed to only appear when I viewed things that were far away, somewhat high contrast, and, to the naked eye, essentially 2D / flat, like TV or the moon. I probably learned in grade school that the image projected on the retina is actually inverted up/down left/right from the scene that appears before the eye. The brain does the work of flipping everything back around so it all makes sense and you don't end up reaching low and to the left to catch a ball passing high and to your right. The brain also compensates a little when your eyes don't quite line up with one another. That's easy for 3D objects that are up close because the actual image differs enough that the brain is composing a 3D perception anyway. When the brain is attempting to align the distant image from two perfectly focused eyes it's easy to match up edges too, but when one of the eyes is sharp and the other is blurry, the brain-alignment doesn't work as well. The result is that the brain partially surrenders the task of compensating for what is perceived as physical mis-alignment of the eyes, and delivers a halo or a double image. This also makes perfect sense if you consider the challenge of overlaying a blurry image and a sharp image in a graphics program like Photoshop. It would be almost impossible to determine the exact positioning with crisp edges upon which to align in only one of the images.

So this simplified explanation is for my own benefit later, when I've forgotten what I came to understand today, and it's here in case someone else stumbles over it and finds my particular way of explaining it easier to understand than some other way.

Thursday, March 18, 2010

Two Things Wrong with Health Insurance

1. Most of it is NOT insurance!

Insurance is a concept of voluntary pooling of resources to counteract a potential risk that, statistically, could never affect all of those pooling their resources, but will, statistically, affect a very small percentage of those pooling their resources to a degree that would require the most or all of the resources that have been pooled. Insurance isn't too different than a bet on a race where the loser is awarded the winnings. Just like bets though, it would never be fair to enter the game once you already know the outcome. If that were allowed, those who pooled their resources with the expectation of offsetting their own risk would ALWAYS lose.

Health insurance that pays for pre-existing conditions is NOT insurance. Because employers forcibly set aside part of their employee's compensation as a health care "benefit" and government regulation (COBRA) forces employers to accept known risk with new employees, most health insurance is a coerced sharing system where the healthy are compelled to bear the cost of the unhealthy.

2. If the health insurance business actually provided insurance, the profitability could never get so wildly out of control.

The business of insurance should be a service that is provided to those pooling resources to assess the risk, determine differential cost based on risk, and prevent fraudulent claims on the pooled resources. For this, the administrators of an insurance plan, as a neutral third party that manages the pooled resources, are due a reasonable fee for performing that service, but they are not entitled to keep a share of the pooled resources based on their ability to deny the distribution of those resources.

This may sound anti-capitalist, but it is no different than saying that a bank is NOT entitled to claim, as their own, the money they have on deposit so long as they can keep their customers from coming into the bank to make a withdrawal. There is opportunity for insurance companies to earn what they're paid by providing a legitimate service, just as banks do. That still fits perfectly in a capitalist based economic system.

Friday, March 12, 2010

A "Likely Story" from an EBay Seller

I purchased something on EBay on the 3rd of the month and got a USPS tracking number back right away. I was thinking I should probably see the package on about the 9th. However, on about the 10th, the info reported on the USPS tracking web site from the tracking number I was given still said:

    The U.S. Postal Service was electronically notified by the shipper on {-month-} 4, 20xx to expect your package for mailing. This does not indicate receipt by the USPS or the actual mailing date. Delivery status information will be provided if / when available. Information, if available, is updated periodically throughout the day. Please check again later.

So, I was getting a little worried that I was being scammed (which, despite EBay's efforts to fight it, is still WAY too common on EBay), so I sent a message to the seller on the 10th to ask if the item had actually shipped yet. The reply I got was as follows:

Note: The names, etc. below are redacted (edits in [brackets]) for now, just in case it isn't that of which it reeks.

    I would first like to apologize for your purchase being delayed.
    ...My name is [---------] ...I am part owner...and I have been out of town along with [----] the other owner since [the] 1st.
    ...Our Shipping Manager of 4 months....has been printing orders off Pay pal to make them look as if they are being shipped.... but in fact as we found out late last night, when we returned.. They have not been shipped.
    ...We have basically been robbed blind by someone we had trusted.
    ...No orders have shipped out since [the] 2nd.
    ..He has stole everything we had in stock and new shipments that have come in. In all we have been robbed of over 2700 [item-1] and almost 3000 [item-2].
    ...where as we have had Him arrested this morning...He refuses to tell the Police where the merchandise is.
    ...We have another shipment coming in on the 12Th....along with other dealers who are selling us some items to help to cover shipments that have already been paid for...and we have called in extra help to assist us with getting all orders shipped out [the 12th].
    ..I am very sorry for any loss of business this may have caused many of our dealers...and to any of our regular customers who where just buying these for personal use.
    ...Please feel Free to call me if you have any questions at [000-000-0000]
    ..please leave a message if you get voice mail due to high call volume I will be expecting.
    ..I will call everyone back.
    ...again...There is no way to explain how embarrassing this is to us as a company and I can only Hope that you will understand that we are working hard to process each and every order to make sure we get every ones items shipped out in a timely manner.
    ...please, as stated above...if you have any questions ..please call me.

    - [-----------]

I'm posting this in case this seller's excuse for not shipping something is habitual, and so that if someone else gets a similar story from this seller, they might find this, outside of EBay, as an indication that they're being jerked around by the same seller. Other feedback comments from buyers for this seller are nearly all positive and contain many reports of immediate shipping, but curiously, there is no gap in the dates of those feedback items as you might expect if nothing had shipped for a week. Perhaps the seller was actually robbed by his shipping guy, and perhaps the timing of my purchase was just that precisely bad. However, it seems very fishy to me that the seller happened to have suffered this misfortune exactly one day prior to my purchase, and then happened to return home and discover it on exactly the day I decided to inquire. If there were a way to ask EBay to take a look at past communications sent from this seller, I wouldn't be surprised at all if I learned that a nearly identical set of circumstances happened to have been described by this seller in the past, to other buyers, as an excuse for non-shipped items.

I finally received the items I purchased on the 17th but I remain suspicious that the story I got was just a stall tactic. If anyone finds this and has been told a similar tale, send me a message with names. If they match, I'll confirm.

SELinux becomes SDLinux

I still don't know how it happened, but on my CentOS 5 (a.k.a. Red Hat Enterprise Linux 5) system, something changed the SELinux context of the /etc/services file from what it is supposed to be to object_r:rpm_script_tmp_t. Several days later, I noticed that no messages were being added to system logs. /var/log/messages was empty. /var/log/secure was empty. /var/log/cron was empty. Just about every log file written to /var/log ended up with 0 (zero) bytes.

My guess is that some RPM I installed, or that got installed via yum, changed the SELinux context of /etc/services. So, without log messages, the security of the system is a bit degraded (so I'll dub that SDLinux for "Security Degraded Linux"). My first thought was that somehow someone managed to get past the certificate-only source-ip-restricted SSH login and zap the logs. However, since no additional log messages were being written, that isn't as suspect as I had feared.

To get logging started again wasn't too complicated:
  1. restorecon /etc/services
    (changes the SELinux context back to what it should be, which is
    system_u: object_r:etc_t)
  2. service syslog restart
Testing to be sure things were working was easy too:
  1. logger -p daemon-warn "this is a test"
  2. tail /var/log/messages
Verify the SELinux context for /etc/services is correct with:
  • ls -Z /etc/services

Here's a reference to the bug that makes this quieter and uglier than it should be:


Friday, January 29, 2010

Barking Dogs and Irresponsible Neighbors

For the past several years, I have had to listen to two dogs barking next door. I've asked their owner several times to take responsibility for the dogs and prevent the barking. Until today, I haven't been pushed to the point where I was motivated to file a report with animal control. I have tried shushing the dogs, but of course that doesn't work. I have tried making them uncomfortable with one of those ultrasonic things, but those are a big joke because they only work sometimes, with really small dogs, that have ultra-sensitive ears, and are no more than two feet away from the device. (So if you were thinking those things might help you in a similar scenario, forget it. They're junk.)

This week I decided a water sprinkler spraying a mist of water might train the dogs not to bark on my side of the irresponsible neighbor's house. Instead, the dogs just played in the water and kept on barking. However, the presence of the sprinkler caught the attention of the owner. This is someone who cares so little for her pets that she leaves them outside all day, every day, to bark and beg for attention from anyone who walks by. She has never, to my knowledge, bothered to walk the dogs, and there is a growing, stinking collection of dog poop in the corner of the yard that she has not bothered to clean up for months. But when she noticed that her dogs were being discouraged from barking by water mist from a sprinkler, which isn't even a fraction of the discomfort imposed by the rain, snow, and even hail storms that have pummeled her dogs, because she leaves them outside all day, every day, then she suddenly has cause to care about how her dogs are being treated. I reminded her that if she had obeyed the law and responded to the complaint to keep the dogs from barking all day, I would have no reason to even try to discourage the barking. Water mist from a sprinkler was the only thing I thought might encourage the dogs to choose the other side of the house for their barking. Again, they just played in the water, so it didn't help anyway.

But when the irresponsible dog owner saw the sprinkler, she decided to march over into my yard and start threatening to report me for all kinds of things that aren't actually a violation of any kind of law, except in her imagination. I told her she could take responsibility for the dogs, prevent them from barking all day long every day, and clean up after them or I would file a report to compel her to control her dogs' barking. Allowing your dogs to bark actually is a violation of the local disturbing-the-peace laws. And I suggested that if she chose not to clean up after the dogs, I'd have cause to ask animal control to come and decide whether they thought her mistreatment of the dogs was criminally abusive. I actually don't know what the criteria are for that, but if it were up to my opinion on the matter, the dogs would be given a new home with someone who wouldn't just leave them outside in rain and snow.

The argument went on with some more screaming about whether she needed to take responsibility for the dogs, or I just needed to put up with it. Then she screamed a threat at me that I just will not tolerate. She threatened to file a report with children's services claiming that she had reason to believe I was abusing my children. Obviously this was her infantile response to being confronted about her responsibility to care for and control her pets, but with all the stories about children's services agencies acting first and investigating later, I can't allow this to dispute to go unrecorded. If only she'd threatened to do bodily harm. That would solve the problem of the dogs and the irresponsible owner since they'd both be taken away. However, the consequence of what she did threaten could be much harder to deal with, so that was the shove I needed to get motivated about filing the report to complain about the dogs.

So, I called a neighbor, who is a detective in a nearby jurisdiction and he suggested that, if it were possible, I should file some kind of "calm civil dispute" report so that there is a record of the incident, if the irresponsible dog owner were to follow through on the threat, for which she has no basis, by the way, because there _is_ no basis. Unfortunately, I was told by the sheriff's deputy, there is no such report to be filed in our jurisdiction, so I couldn't provide any context to the authorities to put her threats in the proper perspective. Our kids are well fed, loved, well clothed, receive individualized education, are immunized against every known microbe on a government prescribed schedule, and have a much larger percentage of the toys they've asked for than I did when I was a kid. None of that even gets within long range radar of what anyone could call abuse. Yet I have to consider the real threat that someone who does not know me would file a report and it's very likely I'd be considered guilty until proven innocent.

The irresponsible dog owner neighbor still refused to take any responsibility for the dogs barking. Her words were "So what? They're dogs. They bark." I have the complaint form filled out and ready to submit to county animal control. She could have chosen to take care of the dogs and obey the law that prohibits their incessant barking, but instead she chose to threaten me. This blog post may not be read by anyone, but it will be published and public today so that if I have to produce a record of how this dispute started, I can just point to this.

If you have had similar problems with your neighbor (regarding dogs or threats), and have found clever ways to handle it, please post a reply. Or, if you have dogs and your attitude is that they should be allowed to do whatever they want, no matter if it disturbs your neighbor, please post a very long reply, that takes you a few hours to write, so I can then delete what you write, because you're wrong. A dog owner is always primarily responsible for the actions of their pet.

Friday, January 22, 2010

VMWare Server Console 2.0

I just upgraded VMWare server to version 2.0.2 on a Linux machine. THEN I realized that the friendly folks at VMWare had taken most of what I knew about connecting to a virtual machine via the VMWare console and tossed it out in the waste bin.

The first clue was when the old VMWare console application, the one you used to be able to install in the normal way you install other windows apps, wouldn't let me connect any more. What exactly is "501 Global command GLOBAL server to non-host agent targets not supported" supposed to mean to me anyway? Well? VMWare? Are you trying to be as obtuse with your error messages as your buddies in Redmond? If so, then mission accomplished!!

So I relented, and read enough of the manual to realize that the whole remote console in VMWare server is now rewritten as some kind of web-browser based monster. I knew that I had set values for the http and https ports, 8222 and 8333 respectively, when I ran the vmware-configure script. I also knew that I would need to allow inbound access to those ports in the Linux firewall (iptables) configuration, so I had already added:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8222 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8333 -j ACCEPT
What I didn't know is that using the web-browser based VMWare console is the only way in v2.0, at least initially, to access the virtual machine guests.

Getting the web-browser based VMWare console application to show me the console was a little frustrating. VMWare still has something to fix on this part of it, but until they do, if you get a blank page on the https:/myvmwareserverbox:8333/ui page:
1. Accept the SSL certificate
2. Reload/refresh the page (ctrl + F5) over and over until the login prompt finally shows up.

But wait, there's more!!!
Not only do you have to throw the Ginsu knives up in the air several times before they stick in your meatloaf, you have to pull out the nonstick pan instead of cooking on a diamond ring. Ok, it has nothing to do with mid-80s "as seen on TV" cookware, but it's about that goofy.

You need to install a browser add-on to see the desktop of any virtual machine guests. Before you're given the opportunity to install the browser add-on, you have to start one of the virtual machine guests by selecting it from the inventory list and clicking the "play" button, and then switch to its console tab. THEN you're offered the chance to install the browser add-on. At this point I was getting worried that all access to my virtual machine guests would be trapped inside a web browser window/tab. However, as it turns out, the browser add-on is actually the core client binary executable application portion of the old vmware console app.

The documentation detailing how to use this client binary outside of a browser has a few holes in it. This blog post is my feeble attempt to fill a few of those holes.

1. Finding the path to the executable.
Since the VMWare console client is installed as a browser add-on, it will most likely be buried somewhere deep in the OS user's browser profile directory. This varies depending on which browser and which OS, but with a VM guest (named MyVmGuest for instance) selected in the Inventory panel of the web-browser based VMWare console app, in the "Command" panel of the "Summary" tab, there should be a link labeled "Generate Virtual Machine Shortcut." Clicking that link pops up a box that has a link labeled "Install Desktop Shortcut to MyVmGuest" Click that, answer the prompts, and then examine the target of the shortcut it creates. On a windows machine using Firefox, it's probably something ugly like:
That vmware-vmrc.exe IS the new console client binary!!!

2. Understanding the parameters.
I didn't look all that thoroughly in the documentation but most of what I found on VMWare's site, or elsewhere, about the parameters to vmware-vmrc.exe was in discussion thread form and required a bit of noise filtering to isolate the speculative conclusions that actually worked.

-X - Start in the client console for the VM guest in full screen mode.

-h {hostname} - this is just what it sounds like, the host name or ip address where VMWare server is running. However, unlike the old vmware console, which had a -P switch for the port, this one just takes a hostname:port combined, like myvmwareserverbox:8333

-u {username} - the username on the vmware server host that is permitted to access the vm guest. This is only useful in combination with the password switch. Note: Does not work as of v2.0.2 in combination with the -M switch.

-p {password} - supplies the password to be used with the username In the old version of vmware console, this was the -w switch. -p makes more sense I guess. Note: Does not work as of v2.0.2 in combination with the -M switch.

-M ## - this identifies the VM guest from the inventory in a simplified way (example -M 33). Unfortunately, this does not work when combined with the -u username -p password parameters.

{vm guest datastore path} - This is the last parameter and replaces the -M ## to specify a VM guest. The format of this may be documented somewhere, but I didn't end up finding that either. The forum posts I found on the topic were difficult to decipher because the brackets were translated into markup characters by the forum app. The format is:
"[standard] vmguest subdir/vmguest name.vmx"
Note: [standard] is a verbatim part of the pattern and is followed by a space. It tells VMWare Server to find the subdir and vmx file in the configured location for vmware guests.
Note: The -u and -p switches only work with this form of specifying the VM guest.

So, here's a full example of the target to a "click it and connect" shortcut (ignoring security precautions related to embedding a password):

"C:\Users\whirly\AppData\Roaming\Mozilla\Firefox\Profiles\jkbr2e9f.default\extensions\\plugins\vmware-vmrc.exe" -h myvmwareserverbox:8333 -u "vmwareadmin" -p "myvmwarepw" "[standard] Old Windows 2000 Pro VM/Old Windows 2000 Pro VM.vmx"

  • Note: C:\Users is the standard home directory path for Windows Vista. On XP, this part of the path would probably be C:\Documents and Settings
  • Note: whirly, in the example, is just the username on the client machine
  • Note: The quotes around the executable path, username, password, and vm guest datastore path are necessary if there are spaces in the corresponding parameter values. Quotes may not be necessary when there are no spaces in a parameter value, but using quotes anyway removes some guessing if something still doesn't work.
  • Note: Old Windows 2000 Pro VM, in the example, is the subdirectory that appears within /var/lib/vmware/virtual_machines on the Linux machine. /var/lib/vmware/virtual_machines is the location that is set in the VMWare Server configuration as the default place to store virtual machine guests.
  • Note: Old Windows 2000 Pro VM.vmx is the VM guest configuration file that appears within the Old Windows 2000 Pro VM subdirectory.
  • Note: In the datastore path, [standard] is interpreted on the VMWare Server end as equivalent to the configured default path of /var/lib/vmware/virtual_machines

I'm sure the reasons for these changes are related to VMWare's consolidation of components between the legacy GSX product and the ESX / infrastructure product line, which ultimately allows the development team to focus on features instead of dividing attention and support between products that have bigger differences in their behavior. But, I just can't resist being a little sarcastic, so I'd like to say thanks again VMWare for changing everything. I'm looking forward to learning it all from scratch again when 3.0 is released ;)

There are other posts, similar to this one, that refer to the ESXi product line. I found a few (links below) that may help if this didn't answer your questions. Searching for the executable name vmware-vmrc might find other information on the topic too.

Thursday, January 14, 2010

Another Fight between SELinux and PHP

After I installed the web portion of ZoneMinder, and navigated to the main console page, the system message log started filling up with a message saying:

SELinux is preventing /usr/bin/uptime from using potentially mislabeled files utmp (initrc_var_run_t)

Great, I thought... another annoying SELinux nag message to eliminate and another convoluted SELinux policy setting to figure out. Well, this time it was just PHP code, so then I thought, maybe there's an easier way to fix this one. There was.

ZoneMinder's PHP code was parsing the output of the uptime command just to get the system load information, and as long as the browser was sitting on the ZM console page, it would call the function again every few minutes. However, in addition to the system load info, the uptime command also collects the OS level user-session info by reading the /var/run/utmp file. SELinux prevents that file from being read by anything running in the web server (Apache) process. After a little searching around, I found that the load information is also available by just examining /proc/loadavg, so I changed the PHP code from
shell_exec('cat /proc/loadavg')
which SELinux doesn't seem to care anything about.

When the uptime command is used in a PHP script, the output could be parsed in various ways, but in the ZoneMinder PHP code, the output from shell_exec( 'uptime' ), which looks like this:
16:22:09 up 284 days, 1:04, 1 user, load average: 0.06, 0.06, 0.00
was being parsed by the preg_match PHP function like this:
preg_match( '/load average: ([\d.]+)/', $uptime, $matches )
so that $matches[1] got the value of the first system load number.

Instead, since /proc/loadavg only has the system load numbers in it like this:
0.06 0.06 0.00 1/239 5581
the preg_match PHP function needed to be a little different, like this:
preg_match( '/([\d.]+)/', $loadRaw, $matches )
and the rest of the code worked just like it did when it used the output from the uptime command.

Now the logs are quiet again, SELinux is still standing guard and preventing access to utmp from anything running in Apache, and I can get back to whatever I was doing before this annoyance from SELinux popped up... well, if I can remember what that was. I think SELinux must be preventing access to my own short term memory now. Grrr.

Apparently, this will not be changed in SELinux's default policies per:

I reported this to the author(s) of ZoneMinder in case they care to fix it permanently in their product's PHP code. But, I'm sure this is a larger problem since there are many references floating around that describe executing the uptime command from PHP. ZoneMinder also has other SELinux conflicts, but they'll have to wait for another day... probably after I find a decent webcam for Linux that has a stable v4l compatible driver.

Wednesday, January 6, 2010

Joomla! Installation Gotchas

After installing a number of Unix/Linux applications (at least the ones for which there is no convenient RPM in a repository somewhere) you get accustomed to the routine of "tar-xzf some_software-1.2.3.tar.gz", then "cd some_software-1.2.3", followed by "./configure", then "make", sometimes "make test", and finally "make install". It's just a little inconvenient when something isn't packaged that way and you actually have to find and read the install-readme file. Likewise, most LAMP (Linux Apache MySQL PHP) applications follow an install sequence of "cd my_webserver_root", "tar -xzf /my_downloads/some_lamp_app.tar.gz", "cd some_lamp_app", maybe "cp config.php-dist config.php", then "chgrp apache config.php" (or similar), and "chmod 775 config.php", followed by pointing the browser to "http://mywebsite/some_lamp_app/installer" (or similar). It's just a little inconvenient when something doesn't quite follow that pattern, and more so if it chews up time trying to figure out why something is subtly different. Joomla! has a few of those little time munchers so until they fix it, here are a few things that I stumbled over and how I got them fixed.

Unpacking Joomla!
It is just irritating to unpack any distribution and find that it has created more than a single directory within which the rest of the contents are unpacked. Unfortunately, Joomla! is distributed in an archive with no internal top level directory to contain the rest. Unless you want a few dozen files unpacked directly into your working directory, Create a directory first, change into that directory, and THEN
'tar -xzf Joomla_1.5.15-Stable-Full_Package.tar.gz'

FTP Layer Setup
Issue 1: If you get an message like: Error: the XML response that was returned from the server is invalid, you may have made the same mistake I made by copying /var/www/http/joomla_1_5_15/configuration.php-dist to configuration.php. Apparently, the installer script depends on code somewhere in the product that uses the ftp settings in the existing configuration.php file instead of what you filled in on the form. So, instead of copying configuration.php-dist, just create an empty configuration.php, adjust its permissions so that the installer can write to it at the end, and start the install process over. Also, since you would have already gone past the database table creation step, the advanced options on the database connection information page allow you to drop the previous tables before creating new ones.
Note: Even if you got through the install process, this same issue can show up the first time the actual Joomla site is accessed but the message may be something like: JError Unable to load Database Driver Starting with an empty configuration.php seems to avoid this too.

Issue 2:
If the "Verify FTP Settings" button reports that the ftp server may be incompatible, or it says that it the STOR ftp command failed, the Joomla! install directory is probably not writable and executable by the ftp user account (Note: Directories in a Unix/Linux file system must be 'executable' in order for their contents to be listed). Most likely this comes up because the ftp user account provided for Joomla's to use is a non-shell access account that is different from the owner of the files in the install directory. For example, if the ftp user account were 'joomlaftp' and the owner of the joomla files is set to a shell account called 'webmaster'). The group on the Joomla directory and files within it may be set to the group under which the webserver runs so that if the webserver process needs to write anything (e.g. an uploads directory) the write access can be granted using something like chmod g+w uploads. It probably wouldn't be a good idea to add the 'webmaster' group to the ftp user account's group list, because that could extend it's reach past the Joomla files, and defeat the purpose of even having the FTP Layer. It may not be practical to change the group on the Joomla files either. So, on most recent Unix/Linux distributions, ACL rules can provide more specific access on specific files, to a specific user or group. Add read/write/execute to the Joomla install directory for the special Joomla FTP account (-R is 'recursive' and -m is 'modify'):

setfacl -R -m u:joomlaftp:rwx /var/www/http/joomla_1_5_15

Then verify that the permissions now consist of the normal file system permissions plus the ACL.

getfacl /var/www/http/joomla_1_5_15
getfacl: Removing leading '/' from absolute path names
# file: var/www/http/joomla_1_5_15

# owner: webmaster
# group: apache

64 bit Linux Zip Library Bug
This has been reported to the Joomla! developers (see tracker 15044) but either they think it is a closed issue because they tested on a 32 bit system, or maybe it just isn't very high on the priority list because 64 bit Linux systems are a secondary concern. This issue may not affect more "bleeding edge" distributions but does affect CentOS 5 (i.e. RedHat Enterprise Linux 5) x86_64 distributions. If uploading a plugin or a template that is in pkzip (*.zip) format just silently fails on your 64bit system, you can try (at your own risk of course) applying this patch to the Joomla zip.php library code by saving the following patch file text into a file and running these commands...

cd /var/www/http/joomla_1_5_15/libraries/joomla/filesystem/archive
mv zip.php zip.php.orig
patch --ignore-whitespace < zip_php_fix.patch

------------- snip file: zip_php_fix.patch ----------------
--- zip.php.orig
+++ zip.php
@@ -223,8 +223,8 @@
function _extractNative($archive, $destination, $options)
- if ($zip = zip_open($archive)) {
- if (is_resource($zip)) {
+ $zip = zip_open($archive);
+ if (is_resource($zip)) {
// Make sure the destination folder exists
if (!JFolder::create($destination)) {
$this->set('error.message', 'Unable to create destination');
@@ -248,9 +248,8 @@
- }
} else {
- $this->set('error.message', 'Unable to open archive');
+ $this->set('error.message', 'Unable to open archive. Error code '.$zip);
return false;
return true;
------------- snip file: zip_php_fix.patch ----------------

It is a struggle to resist the urge to just shut off Security Enhanced Linux. SELinux is always locking up something to send you on a quest to figure out how to unlock it. Even if SELinux does some useful things in terms of protecting against intrusions or unauthorized modifications, it may just be a notch more difficult than sendmail to configure it correctly. That said, these rules for Joomla's files may not be exactly right, but they seem to give Joomla the access it needs while keeping SELinux set to enforcing. (Note: This assumes that everything in /var/www is already labeled by a default SELinux rule as httpd_sys_content_t but you may need to add a corresponding rule explictly if Joomla's install directory is elsewhere in the file system).

semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/components(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/configuration\.php'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/images(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/media(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/modules(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/plugins(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/templates(/.*)?'
semanage fcontext -a -t httpd_sys_script_rw_t '/var/www/html/joomla_1_5_15/tmp(/.*)?'
restorecon -R -F -v /www/joomlainstalldir