Fun with iCal Server
We run an iCal Server at work, and the mandate has been handed down that everyone needs to be subscribed to a “Vacation Calendar” that a couple people in the building maintain (my boss, the head of Operations, and the Dean’s assistant). For the most part, this has been really easy. We just created a “Vacation” user, and subscribed people to it’s calendar on the server with iCal. However, we have a couple PC users in the building that use Outlook, and Outlook wants an ICS file to subscribe to… not a directory. It seems like iCal Server is supposed to (or at least version 1 did) give the client a combined ICS file if you just hit the directory of the user’s calendar without specifying anything else. This doesn’t appear to work though.
So, as a work around, I wrote up a very simple shell script that concatenates all the ics files for the vacation user into one ICS.
#!/bin/sh #This users caldav directory. Something like: #/Library/Calendar/calendars/__uids__/7E/1B/7E1B373E-8F22-469F-8BDF-5C3ECB996156/calendar INPUT="" TEMP="/tmp/temp.ics" #Where you want the combined ics file to go. Should be a web hosted directory if you expect to have clients subscribe to it. Something like: #OUTPUT="/Library/WebServer/Documents/vacation.ics" OUTPUT="" echo "BEGIN:VCALENDAR PRODID:-//Vacation Merge//example.com// VERSION:2.0 X-WR-CALNAME:Vacation Calendar" > $TEMP cat $INPUT/*.ics | grep -v "BEGIN:VCALENDAR" | grep -v "END:VCALENDAR" >> $TEMP echo "END:VCALENDAR" >> $TEMP tr -d '\r' < $TEMP > $OUTPUT
The big points here are, while you can just do `cat *.ics > /some/place/merged.ics` the “BEGIN:VCALENDAR” and “END:VCALENDAR” are still in there, which end up at the start and stop of each of the events in the calendar. Calendar software will stop reading once it hits one of those “END:VCALENDAR”… so the `grep -v` just removes those, and we add an end at the very end, just as we added a begin at the start.
The last line is to add unix line endings… because for some reason, this script is producing DOS line endings. *shrugs* Probably just the beginning block that has the wrong line endings. Anyway, it works.
That pretty much does it. It’s very simple. I have it run with cron every hour.
Good luck.
Bootcamp Assistant Nightmare
So, I recently got accepted into a beta program for a popular game. The problem is, there’s no Mac version of the beta yet. So, I had to get a windows machine up and going. All the PCs in my home, and at work, aren’t really capable of playing modern games. So, I had to get bootcamp working on my laptop (which is still fairly old, but at least is a C2D Macbook Pro (2006)).
So, I started with just trying to run bootcamp assistant. It failed saying “cannot move files”. Great. So, looking online, I found that it can be caused by insufficient space on the HD. So, I removed some data from my laptop. Ran the assistant again, and got the same result. Moving on, I tried using the work copy of iDefrag. I did both the “compact” option, and the “full optimize” option. After both, the result of the bootcamp assistant was the same: “unable to move files”.
So finally, after spending probably 16 hours on this problem, I “Target Disk Mode” booted my MBP, and hooked it up to my Mini Server, and ran Carbon Copy Cloner to backup my MBP to a disk image. Then, repartitioned the drive on the MBP as 1 partition, HFS+ Journaled. Then, ran CCC and restored the disk image back to the MBP HD. (Total time for backup, then restore, about 2 hours for 50GB (about 1 hour for each direction). I then booted the MBP back up, and ran the Bootcamp assistant. It worked!
So, while iDefrag SHOULD have been enough to move everything up to the start of the disk, it didn’t seem to be enough. CCC does file level copies, so wiping the drive, then restoring it, basically moved everything to the start of the drive, and all non-fragmented. Who knows, maybe the bootcamp assistant just looks at the age of the partition and decides to fail based upon it’s age. *shrugs*
Anyway, I installed XP SP3 since I couldn’t get Win 7 64-bit to install. I’m going to give it another shot when I have some time, given this link that seems to address the issue I saw when I tried booting from the Win 7 DVD.
So, all told, 18-20 hours (with some sleep in there) to install XP to play one game that’ll probably have a Mac version of the beta out in a couple weeks. But, it was worth it after playing 3 hours tonight, and probably playing more tomorrow.
All that said, Apple really should allow running the Bootcamp assistant from another machine while the “target” is in TDM. Or, run it from single user mode. The former should allow everything to be moved, and the latter should allow moving of just about everything but the kernel. *shrugs* Bit annoying. But, it’s really a “corner case” for those of us that want/need to install windows after the initial computer setup. The CCC route seems like the most easy, fast, and logical option. If only I’d thought of it to begin with.
URL Shortener
So, it’s been a desire of mine for a while to make up a URL shortener. It seems like such a trivial coding experiment, but a fun one.
The first hurdle, getting something better than base10 for the URLs. That’s fairly easy, in that you can look here. The code he lists isn’t complete, as you need some other stuff. So, go grab the Cassis project code instead.
Note: when you “include_once” that code, you’ll want to do it like:
ob_start();
include_once("./cassis.js");
ob_end_clean();
Next you’ll need to code up something to add URLs to your database. That’s also easy enough. My suggestion would be a simple table that would have “id”, “shortcode”, and “url”. Make id a primary key, and add an index on the “shortcode”. Maybe one on the “url” if your going to be using the system heavily enough to require checking to see if a URL exists already before blindly creating a new short-url.
The last hurdle is to write the decoder. Basically, just have it look for “GET”, and look that up in the DB table, then set the “header(location: )” to be the URL in the for that short code.
Now, normally, you’d have a mod_rewrite rule that looked something like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule shortener.php?url=$1 [L]
Except, Wordpress permalinks use something similar, and the two don’t play nice. Now, it would be cool to pass all URLs on to the decoder, and if it didn’t exist in the DB, you’d pass it on to the wordpress index.php. I haven’t quite figured out how to do that, but I found a pretty decent work around.
RewriteRule ^z(.*) shortener.php?url=$1 [L]
Stick that before the Wordpress rewrite rules. What that will do is, if there’s a URL that starts with “z”, it’ll pass whatever comes after that “z” on to the decoder. Personally, I don’t have any pages, or files on my website that start with “z”, so it’s safe for me to do. Your experience may vary. If the decoder doesn’t find the url in the table, it simply redirects to my main page. I think I’ll change that to a 404 here once I am further along.
I’m going to keep playing with this. And hopefully, make some pretty spiffy use of it, but for now, it’s “basically” working. I’ll try to remember to post back on this topic when I have more to report on it. =)
Special thanks to my friend Aaron for the advice on this one.
UPDATE 1: I got 404’s to work for non-existant short codes. So, the key with wordpress is to use something like this
header("HTTP/1.1 404 Not Found");
include("index.php");
Basically, I was trying all kinds of other things, then realized that index.php for wordpress will look for the header state, and redirect appropriately. So, that’s it. It now throws a 404 (which, without that include, it would throw a 404, but it was just a blank page)… Cheers!
Proxy Splunk behind Apache 2.2
Splunk is pretty damn cool. And since Splunk 4, it’s been much easier to set up and run. And since my environment at work produces a lot less than 500MB/day of logs, I can safely use the free version of splunk. But, this has a downside. You don’t get user authentication (there’s other stuff you don’t get, but the big one to me is user auth).
So, the obvious solution is to proxy Splunk behind apache and have apache do the user authentication. There’s some good info about doing this online, but it seems none of it is complete for what I was trying to do.
So, here’s what I had to do. First, the relevant chunk in the apache config (if you’re doing this over https, you may want to add “SSLProxyEngine On” before the mod_rewrite section):
<VirtualHost *:80> ServerName server.example.com:80 ProxyPass /splunk http://127.0.0.1:8000/splunk ProxyPassReverse /splunk http://127.0.0.1:8000/splunk <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^/(static.*) /splunk/$1 [P] </IfModule> </VirtualHost>
So, on my server, I’d go to https://server.example.com/splunk to visit my splunk page. The rewrite rule is there to fix what seems like a bug in the “jobs” page for splunk, that doesn’t seem to obey the “root_endpoint” set below.
The second part of this is to set a few things in the web.conf.
In my case, since this is running on a Mac, these go in a file in /Applications/splunk/etc/system/local/web.conf
root_endpoint = /splunk tools.proxy.on = True updateCheckerBaseURL = 0
The first basically says “everything is in the /splunk subdirectory”. The Second I’d assume says “Splunk is being proxy’d”, and the Third is something I had to add to fix a weird issue I was seeing after doing all of this. Once I’d proxy’d it, every time I would open a new session to Splunk, I would see the “Checking for Updates” and then the “Agreement” page, which the continue button wouldn’t point back to http://server.example.com/splunk but just http://server.example.com/. So, That third line basically disables the update check. It’s kind of silly anyway since I keep an eye on the splunk.com webpage to check for updates.
As for securing splunk beyond proxy’ing it, I just set up a realm in Server Admin that locks down the /splunk location. Pretty easy.
Good luck. Splunk is pretty cool, and makes it dead simple to track down issues, get statistics, etc. I’m still not really proficient with it, but I hope over time I’ll learn more of what I can do with it.
