January 21, 2012

Tummy.com Blogs : A word on logging and database commits.

From: Sean Reifschneider

Earlier this month we switched our bandwidth accounting system to use new software. Previously we used a kernel module on a system, which was conceptually very cool. But with CentOS 4 going end-of-life, that kernel module doesn't work on CentOS 6 and I wanted to go a different route rather than fix the module.

So earlier this month, after extensive testing in parallel with our normal traffic stats collection software, I flipped the switch and started using the new software. Except that I forgot to re-enable the database update code, so it was only updating the graphs. I had disabled it to prevent double-accounting when running the old and new code in parallel during testing.

But, I log all those updates to syslog. I was able to pull out the logs of all those updates and replay them into the database. Logging of updates is a great safety net.

Which leads me to my next point. The simple code I had written to replay the logs, just was going to do one big commit at the end. I didn't think about how many updates we were talking about, over 2.5 million... I also wasn't writing out status, so I wasn't sure how far along it was. So I eventually killed it after an hour of running, and added code to commit every 1,000 updates and then write out a progress message.

With these changes, it ended up finishing after 18 minutes, giving me progress all the way along. Of course, I could have consolidated the data down in the program and done only a few updates, but 18 minutes was totally acceptable.


January 17, 2012

Kevin Fenzi : Post Fudcon todo’s

After seeing Christoph’s post fudcon 2012 todo list I thought that making a post fudcon TODO list was a great idea. Here’s mine (help welcomed!):

  • Need to drop our staging git branch in puppet and merge any staging machine changes into the master branch
  • Need to work on making out applications more ‘container’ like. ie, reduce the things they depend on and make it easier to spin up an env they run in
  • Check out cloud tech and filesystems to see if any will meet our needs
  • See if we can automate spinning up a application env with all needed integration testing machines
  • Get two factor auth working for sudo for sysadmin-main and deploy. Continue adding types of auth and services once it’s solid
  • Talk to the Board about our torrent seeder.
  • Make sure the folks who want to work on reviving smolt have all the info and help they need
  • Figure out how best to deploy the new community/tagger applications to production
  • Find the time to add the nightly live compose to the rawhide/branched scripts so it happens in a totally automated way
  • Finish migrating everything to RHEL6

If there’s something I told you I would help you with/do at Fudcon and you don’t see it above, please let me know and I will add it to the list. ;)



January 15, 2012

Kevin Fenzi : Fudcon day 3

Day 3 started out over at Macbride hall again.

Some of us Fedora Infrastructure folks got together to hash out any issues and projects we are concerned about in the coming weeks, months or year. We may have some big challenges ahead with ARM possibly coming in as a primary arch, which will stretch our storage and networks and building code. We are going to take a harder look at torrents and see if they are still worth providing to the community. The new community packages and tagging stuff needs to move into production. Lots of high bandwith talks with involved folks in all those areas.

After a nice little lunch, and a few more discussions it was time to head out to the airport. Matt Domsch was able to take 3 of us to the airport, which was nice. At the airport, there was time to sign gpg keys and mail them out from the keysigning the other day as well as make another pass of the cacert.org assurances that I needed to enter into the system. Hopefully flights home will go smoothly.

Overall it’s been a great fudcon. Lots of things seemed to get discussed and worked out. I heard very little where people were asking for something that they were not willing to champion themselves, which I think is excellent.

Thanks to all the folks who worked so hard to put on a great event and those who attended.



Andrew Barney : Ubuntu 12.04 Preview

I haven’t been giving computers or linux much attention on my blog for awhile. I hope to remedy that situation soon. I am eagerly awaiting the Ubuntu 12.04 LTS release in a few months. It feels like I’ve been waiting forever, but once it is officially released i hope to give it a thorough review. [...]


Kevin Fenzi : Fudcon day 2

Saturday started off super early: Scheduled for a 8:30 start (although we didn’t actually start until 9am).

We had some intro and then pitching of barcamp sessions. Lots of nice sounding sessions. Then a short State of Fedora talk from our fearless Fedora Project leader.

There were tons of sessions (as you can see from looking at the wiki: Fudcon wiki page for saturday. I went to the session on making Fedora packaging easier. This was a talk to unveil a few new cool applications that can help folks with maintaining packages.

Pretty slick stuff: Community development packages and community dev tagger. It’s fast and could be very very handy for users.

Lunch was a delightful burger and beefy miracle. Good stuff.

After lunch I met up with some IRC folks to discuss some issues and ideas for improvements there. We also did some cacert.org assurances with a few folks (there’s another session just for that at 4pm, but since we had a few minutes we went ahead and did it to save time later).

Then on to the session on redoing comps and package organization given by Bill Notthingham. There are still lots of details to work out, but comps will split into distro groups (xfce, kde, base, webserver, etc) and categories (web browsers, editors, etc). distro groups will stay in the same place, but categories still need to be hashed out. Some info can come from the package tagging application I saw this morning and some from package maintainers. More info to come, but overall a good plan.

Next was the talk and show and tell on the rasberry pi arm box. It’s a pretty cute little device. I might have to pick up one after they are available.

Then, a lovely cacert event. I assured about 7 people and was in turn assured by 5 more. Then a gpg keysigning which had quite a few folks at it, but we managed to organize and run through checking fingerprints and id’s in short order.

Only a few minutes to drop things off at the hotel and then it was time for FUDPub over at the student center. Lots of food and fun. Finally some more talk back in the hotel where amusingly a wedding party was gathered.

tomorrow will be the last day and travel back home.



January 14, 2012

Kevin Fenzi : Fudcon day 1

Fudcon day 1 started with having to get up at 7:30am to get ready for the 9am starting time. Thats 5:30am my time, so that’s an excuse for me being groggy this morning. ;)
Had no problem getting to the venue and getting my badge and t-shirt. Then, after some logistics we started in on the first session of the day:

Fixing Staging in Fedora Infrastructure.

Some background: Currently we have a some ‘staging’ machines that are supposed to be copies of production instances that we can use to test and integrate new things with. We have a seperate git branch in puppet that handles the staging instances, which seems neat, but turns out to be an annoyance in several ways.

There was a lot of information and debate on what production, dev, staging, integration, or the meant. How we could setup puppet. If we could on demand make a staging instance or a subset of those. How process should work. How we could go from here.

We came up with a plan of attack and some things to consider:

  • Drop the ‘staging’ git branch. Everything is in the same git repo. ie, all machines are production.
  • Try and make our apps more able to be ‘containers’. Ie, reduce dependence on other parts of Infrastructure so things can be tested in containers easier.
  • Look at ways to build containers or integration staging machines on the fly as needed.

After a quick lunch (man the wind was nasty to/from lunch), it was time for a 2 factor auth session.

We’ve been talking about finishing off yubikey as a true two factor authentication method in fedora infrastructure. We had a lot of good input here and hashed out a plan here too:

Short term:

  • Fork linotp’s pam module to a new project. This would be just the pam module, and we would enhance it to require a valid ssl cert from the server it’s talking to before sending it anything, prompting for pin and pass and other enhancements.
  • First target is going to be sudo for all sysadmin-main users.
  • Create a CGI that the pam module can talk to and send auth info to and return ok, bad, broken
  • CGI will likely run on fas servers so it can talk to fas and yubikey
  • Some quick and dirty way to query pin

Longer term:

  • FAS changes to store and set/reset pin
  • ADD google auth or OATH to the CGI
  • Increase parts thats are covered/where 2 factor is required

All in all some great sessions today. I think we have some lovely plans in fedora infrastructure, ready to dig in and get working in the coming days and weeks.



January 13, 2012

Kevin Fenzi : Fudcon Day 0

Thursday (Fudcon Blacksburg 2012 day 0) was a travel day for me. Had to get up at the unreasonable hour of 4:45 to catch the shuttle to the airport, then to my first flight to chicago. That went off fine, but unfortunately my plane from Chicago to Roanoke was delayed quite a while. ;(
On the plus side I got to hang out with 3 other fudcon bound folks and we did some chatting there in the airport. Finally we got a plane and got to Blacksburg, where the magic Spot van picked up about 15 of us and took us to the hotel.
The hallway track was well in progress there, and I ended up staying up later than I had thought I could talking to people I usually only see on IRC. Finally got to bed around midnight after catching up on some emails.

Looking forward to a great fudcon!



January 06, 2012

Kevin Fenzi : Fedora Infrastructure at fudcon 2012

Next weekend is Fudcon Blacksberg 2012 and a number of Fedora Infrastructure folks should be there (Including me).

I’ve signed up to give/facilitate 3 workshops/hackfest sessions:

  • Fedora Infrastructure: Revamping our staging server setup, then implemeting it. This will be hopefully friday and sunday. We can try and hash out a plan on friday and look at starting implementation or at least timeline for implementing things on sunday.
  • Fedora Infrastructure: 2 factor authentication brainstorming. This will hopefully be saturday. I’d like to try and get full 2 factor auth setup for yubikeys and/or a clear plan to do so. Ideally we will setup a framework where we can also optionally use other 2factor setups (google authenticator, etc). I will also have some yubikeys with me to distribute
  • Fedora Infrastructure: Getting started/apprentices/Getting involved. This will be a intro session for folks that would like to get involved with infrastructure. We can answer questions, try and find out what would be a good fit for people starting out and work on our apprentice program to try and make it easier for people to join us.

In addition to those, Toshio is going to be running some sessions on Python programming and software releases using our infrastructure as the example. Should be great stuff.

Of course as always in addition to the talks and hackfests, there’s a lively “hallway” track: A chance to meet up with folks and discuss things in a high bandwidth way. I hope to see lots of folks I know, and lots of new faces as well. Happy to discuss any fedora related issues or items there.

If you’re unable to attend this Fudcon, do follow along in #fedora-fudcon on irc.freenode.net. There should be pointers there to whats happening, whats being discussed and allow for remote input. Hopefully we will have irc transcribers in various rooms as well.



Darrin Goodman : OpenSource Enthusiasts Need a Better Clipboard Tool

Dear LazyWeb,

From time to time, I am required to use third party tools in my job where I may have to copy a bunch of information (separate fields of data) and paste them one at a time into a web form.  Years ago, while working at a small web design firm, I was introduced to a tool for Windows called ClipMate.  At that point in time, ClipMate proved to be a huge time-saver when copying customer data from our Access database and then pasting it into an online account setup form for a third party web-stats tracking service that we used on client websites.  What sets ClipMate apart from other clipboard tools is that it not only stores a list of your clips (either text or images), but it will allow you to select a clip from where you would like to start pasting from, and then continue pasting down the list, one clip at a time.  In the example that I stated previously, can you imagine going to the database, copying the client’s name, then pasting the name in the web form, then going back to the database to copy the next required chunk of information, and so forth…?  Wouldn’t it be nice to be able to go to the database and copy, copy, copy, copy, copy…, then go to the web form and paste, paste, paste, paste….?  ClipMate allows you to do this.

There are a handful of clipboard managers/organizers in the world of open source, but I have yet to find one that will do as I have described above.  It has been some years now since I’ve used ClipMate, but recently, because of some repetitive copying and pasting that I’ve been doing in my job, I purchased a new license and am again happily plodding along with my friend ClipMate.  However, this requires that I am using a Windows machine.  Fortunately in my job, I have two separate production machines – on Linux and one Windows, so I am able to pick and choose the tools that work best for the task that I am trying to accomplish.  Below are some screenshots of ClipMate in action:

I would like to have a Linux-friendly clipboard tool that will do as I have described – pasting successively from the list of clipboard elements.  Seeing as how the clipboard tools that I’ve seen will allow you to select an item from the clipboard list and paste that item, it doesn’t seem like it would be all that difficult to implement a feature that would allow you to successively paste one item at a time from the list.  I’m not sure that my programming skills are sharp enough to accomplish this at the moment, nor do I have the time to invest in trying to figure out how to implement such a feature, so I am hoping that some skilled individual will read my plea and decide to do what Open Sourcers do… grab some fine piece of software that already exists, make it better, and re-release it to the world.

Incidentally, I’ve tried running ClipMate under Crossover and Wine, and although the software did run, it somehow did not seem to be able to connect with my clipboard and so it was useless to me.

Maybe what I am looking for already exists and I just am not aware of it.  Please feel free to comment and let me know if you have found a tool that will work as I have described, or if you have created something that will perform the desired task.  Thank you!



January 04, 2012

Kevin Fenzi : Another fedorahosted.org trac plugin

I’ve just updated in epel and installed on fedorahosted.org another trac plugin: PeerReviewPlugin

This is a nifty little plugin that lets you do codereviews. You can set users to have CODEREVIEWDEV (developer who can submit reviews) and CODEREVIEWMGR (can approve reviews). You can enable the plugin in the admin section of your trac instance, and should then see a “Peer Review” button.

Enjoy.

EDITED TO ADD(2012-01-06): We ran into a problem with the plugin that I missed in my testing of it. ;( I’ve disabled it for now… if anyone has ideas on fixing http://trac-hacks.org/ticket/7034 please chime in there. ;)



December 28, 2011

Kevin Fenzi : Some new fedorahosted.org plugins

Thanks to some quick packaging work by Andrea Veri we have some new plugins we have added to trac on fedorahosted.org for your tracking pleasure:

  • trac-workflowadmin-plugin: This plugin lets you change the ticket workflow on your project. You can setup what states tickets must pass through and in what order. It even gives you a nice little graph of workflow.
  • trac-navadd-plugin: This isn’t too visible yet, but I am going to hopefully use it to add handy ‘register’ and ‘forgot password’ links to all projects. This should help with end user ticket reporting.
  • trac-watchlist-plugin: This allows any logged in user to watch tickets or wiki pages without having to CC to the ticket or otherwise distrub it
  • trac-tocmacro-plugin: This was enabled in the old fedorahosted, but wasn’t packaged up correctly and has been now. This allows you to use a TOC macro to provide table of contents on wiki pages.

As always, these plugins are available in the EPEL repos (currently in testing) for all to use, improve and share. If you need some specific plugin or macro in fedorahosted, just let us know!



December 22, 2011

Tummy.com Blogs : New Year Python Meme

From: Sean Reifschneider

Via Richard who got it from Tarek...

1. What's the coolest Python application, framework or library you have discovered in 2011?

I haven't been using it much lately, but looking back the library I think I was most excited about was bottle a Python micro-framework for building web applications. The thing I like is that it's extremely small, just a single file. For simple things that I might have used a CGI for in the past, bottle is great.

As far as the thing that I use the most on a day-to-day basis, that would probably be cony. Cony is a personal URL-bar command-line, so you can write custom shortcuts to different locations. For example, I have shortcuts like "backup [HOSTNAME]" which searches for the host and takes me to the page on the backup server, or "nagios [CUSTOMER]" which takes me to their nagios page.

2. What new programming technique did you learn in 2011?

Via a recent code retreat (written about previously), I really got into test driven development. Which is great, because our system administration work I like to call "test driven system administration", via Nagios, so it's very comfortable to me. But I hadn't had time to really get comfortable with testing my code until I got this opportunity at code retreat.

3. What's the name of the open source project you contributed the most in 2011? What did you do?

That's a tough one, because I've mostly done a lot of small contributions rather than any large ones other than ones I maintain. So probably the python memcache module or vPostMaster would be at the top. Until, that is, we release the source to our backup system, which I spent a lot of time contributing to this year. Aside: We've finally settled on a name for it: Network Attached Backup.

4. What was the Python blog or website you read the most in 2011?

I don't really follow any Python blogs... Most of my news comes from my friends feeds in facebook or plus. But the number one website I read in 2011 is almost certainly the library documentation. :-)

5. What are the three top things you want to learn in 2012?

I don't really set out goals for what to learn, certainly not a year in advance, because things change too fast. In general I want to continue to improve my business chops.

I'm expecting that in 2012 I'll be able to start programming seriously in Python 3.

6. What are the top software, app or lib you wish someone would write in 2012?

I'd love to have something that did a really good job of bringing together and making searchable all the data that comes at me. Thunderbird can often be pretty good for e-mail, but sometimes it seems like it just misses huge parts of my correspondence for reasons I don't fully understand. But I'd also like web pages I visit in there, photographs, and more...

Thanks Tarek and Richard! So what are your answers?


December 18, 2011

Kevin Fenzi : fedorahosted.org changes an enhancements

I just thought I would shoot out a quick post about some changes and enhancements at fedorahosted.org (an excellent place to host your open source project).

We’ve moved fedorahosted to RHEL6 and a newer set of hardware. Everything should be faster and newer. You will probibly most notice the upgrade to trac (from 0.10 to 0.12), but mailman, scms and all other software should also be newer. The backend is now a cluster of two drbd using nodes. We are going to look at decentralizing things much further in the coming year.

Speaking of trac, there’s a ton of new items in the new version along with some new plugins we have enabled:

  • The MasterTickets plugin is now installed, so you can have tickets block or be blocked by other tickets, and get a nice graph of the dependency tree.
  • Multiple repository support. You can now have your project list and show multiple source repos, using the same or different SCM’s
  • A great deal of configuration is available to trac admins on notification emails and permissions.
  • Unicode and i18n support is vastly improved
  • With a bit of adjustment, the PrivateTickets plugin works fine with the new trac. This allows you to have tickets only some groups can read/see if needed.
  • Configurable work flows for tickets. You can set things to go through specific states before being fixed.

Mailing lists (lists.fedorahosted.org) have some small but nice improvements, like properly handling bounce messages from inactive google.com accounts and better utf8 handling.

Our review board instance is still running along, and should be a bit faster now.

We have great plans for 2012 for fedorahosted. If you’re interested in helping us out, take a gander at the Fedora Infrastructure Getting Started page and jump in and join us.

See the fedorahosted.org FAQ for more information about Fedora Hosted and how to host your next open source project there.



December 13, 2011

Paul Hummer : Announcement: YUI 3 Nightlies

I'd like to announce the general availability of a YUI 3 Nightly combo server. Each night, it will check out and create a new build of the YUI 3 source code, and serve it via a combo handler. In order to use it, just point your YUI_config to the new combo loader. Information about it can be found at the main page at YUI Nightly Doc Page.

Why did I do this? There are a few reasons. First, Ubuntu One can't use the Yahoo! CDN because we're using SSL. This means we have to run our own combo loader. The problem with this is that it's a pain to go out and get new YUI and plug it into my dev environment just to get surprised by something that broke or something that changed, etc. With the nightlies, I can regularly just point YUI to this combo loader and let it run.

I'm using this in "production" for a small personal site, but I wouldn't recommend it be used it any production site that actually has uptime requirements.

Comments, questions, and pull requests welcome.

Update: The URL has now been changed to http://yuinightly.com/.



December 11, 2011

Tummy.com Blogs : Google Calendar in Gnome 3

From: Sean Reifschneider

Several of us have been running Gnome 3 lately, and have been happy enough with it. One thing I was thinking was that it would be nice if the date/time bar app showed my google calendar. Then Mike found this project that does just that: gnome-shell-google-calendar.

But, I subscribe to 8 other calendars. So whenever we had a company meeting, it would show a bunch of duplicated events, and it was hard to tell my events from others. So I hacked on it this weekend and have pushed a new version up to github: Sean's fork of gnome-shell-google-calendar.

This version de-duplicates events with the same title that start at the same time, and also displays what calendar the event came from. So far it's been working really well for me, but the upstream author is reporting an error so I'm working with them on that at the moment.


December 10, 2011

Kevin Fenzi : Fedora NFS server outage retrospective

As you may have seen if you are on the fedora announce list, we had an outage the other day of our main build system NFS storage. This meant that no builds could be made and also data could not be downloaded from koji (rpms, build info, etc). I thought I would share here what happened so we can learn from and try and prevent or mitigate this happening again.

First, a bit of background on the setup: We have a storage device that exports raw storage as iSCSI. This is then consumed/used by our main nfs server (nfs01). It’s using the device with lvm2, and has a ext4 filesystem on it. It’s around 12TB in size. This data is then exported to various other machines to use, including builders, kojipkgs squid frontend for packages, koji hubs and release engineering boxes that push updates. We also have a backup nfs server (bnfs01) that has it’s own separate storage with a backup copy of the primary data.

On the morning of December 8th, the connection between the iSCSI backend and nfs01 had a hiccup. It retried current in progress writes, and then decided it could resume ok and kept going. The filesystem had “Errors behavior: Continue” set so it kept going (although no actual fs errors were logged, so that may not matter). Shortly after this, NFS locks started failing and builds were getting I/O errors. A lvm snapshot was made and a fsck run on that snapshot, which completed after around 2 hours. A fsck was then run on the actual volume itself, but that took around 8 hours and showed a great deal more corruption than the snapshot had. In order to get things into a good state, we then did a rsync of the snapshot off to our backup storage (which took around 8 hours), and merged that snapshot back as the master fs on the volume (which took around 30min to complete). Then, a reboot and we were back up ok, but there were some small number of builds that were made after the issue started. We purged them from the koji database and re-ran them with the current/valid/repaired filesystem. After that builders were brought back on-line and queued up builds processed and things were back to normal.

So, some lessons/ideas here, in no particular order:

  • 12TB means most anything you decide to do will take a while to finish. On the plus side that gives you lots of time to think about the next step.
  • We should change the default on-error behavior to at least ‘read-only’ on that volume. Then errors would at least stop further corruption, and best prevent the need for a lengthy fsck. It’s not entirely clear if the iSCSI errors would have made the fs hit error condition or not however.
  • We could do better about more regular backups of this data. A daily snapshot and rsync off of that snapshot to backup storage could save us time in the event of another backup sync being needed. We would also then have the snapshot to go back to if needed
  • Down the road some of the cluster fses might be a good thing to investigate and transition to. If we can spread the backend storage around and have enough nodes, the failure of any one might not be as much impact.
  • Perhaps we could add monitoring for iscsi errors and note and react to them quicker
  • lvm and it’s snapshots and ability to merge a snapshot back in as primary really helped us out here.

Feel free to chime in with other thoughts or ideas. Hopefully it will be quite some time since we have another outage like this one.



December 09, 2011

Paul Hummer : YUI and PhoneGap Sitting in a Tree

...K-I-S-S-I-N-G

The Web and Mobile Ubuntu One team is in Buenos Aires, Argentina (along with most of the rest of the Ubuntu One teams) exploring the boundaries we may experience merging the Web and Native App experiences. I realized very quickly in this exploration project that I needed an end goal. Since we are already using YUI on the web part of Ubuntu One, I figured that I needed to figure out where the limitations of YUI would be there.

Enter PhoneGap.

It became very clear that it'd be much better to use one of these "glue" frameworks than to roll our own (the important reason being that we'd rather do more fun things). One of the first things I noticed is that the default PhoneGap doesn't really "compile" out of the box, which annoys me. Once I linked in the www folder properly, I had a good stub.

Using the YUI Loader in PhoneGap is not impossible, but it's relatively impractical. It stores a whitelist of URLs that you can get to, and even then, javascript is so required on the site that we can't afford to not have javascript. At this point, I realized that all the front-end tweaking/ricing I've been doing for the last year or so gets thrown out the window. I broke down and made giant rollup files for yui.js and yui.css.

As a sidenote, I also took the time to actually explore the YUI App Framework by coding rather than reading about it (which I've done a lot). There is an example Todo app (thus, the reason why I made a todo app). So I essentially cargo-culted that code.

Sometime during this cargo-culting, I realized one very important thing: Debugging PhoneGap apps is a pain in the ass. It really is. It resulted in this late night tweet (which I was at least half serious about). Unless you're a human jslint machine (and if your name is not Doug Crockford, I assert that you are not a human jslint machine), you're bound to make typos and syntax errors and such. You don't really get a decent access to the console1. I tried running the app in a normal desktop browser but I found that events I was expecting either weren't firing or weren't being handled (without a console, I don't know). I eventually went digging into the PhoneGap js that comes with the default template, and realized that I needed to just kill the PhoneGap js when testing in my browser. The browser only takes you so far, but it at least helped me to get the YUI toolchain sorted out.

I then took a bit of time sorting through the touch-specific interface and adapting the App example to that interface. For instance, hover events are useless on mobile. I also found that the "keypress" event for the Enter key in an input wasn't firing with the keyboard "return". Apparently, the iPhone wants the form input wrapped in a form itself, and then it'll show the "Done" button in the on-screen keyboard, which will send the right event (make sure that the form doesn't actually submit).

The end result is MoarTodo2. It's a really ugly app, but it's academic and I just wanted to learn about the toolchain. I can't imagine not using something like PhoneGap (it doesn't have to actually be PhoneGap) to build a mobile web app to be distributed through the various app stores. I expect there will be more to the debugging story, but it's still a learning curve.

I still feel pretty strongly that the Native vs. Web argument will continue, and that they'll still have their various places. I look forward to a day when that argument is settled, but I also look forward to the Year of the Linux Desktop, the rapture, and Santa Claus.

1 I didn't try Weinre because I had switched to using iWebInspector a few weeks ago (when I wasn't using a PhoneGap container), and so didn't have it immediately on my system. I'll probably have to go back and try it out in a PhoneGap context.

2 Xcode creates new projects with Git. I'm not making a political statement here. I just pushed it where it was easiest. Don't hate.



December 04, 2011

Tummy.com Blogs : Report on 2011 Code Retreat

From: Sean Reifschneider

Yesterday Bill Tucker and Matt Rose organized a Code Retreat in Fort Collins. It was "Global Day of Code Retreat", and there were events happening all around the world. The basic idea was that you paired up and for 45 minutes used best practices (as if you had all the time in the world to do it) to work on a programming problem. Then everyone deleted their code, stood up and discussed the previous round. Then you paired up with someone new and started over on the same problem.

It was a great event, extremely rewarding on many levels. Read on for more of my thoughts on the event. (read more)


December 01, 2011

Kevin Fenzi : Lessons from password/key changes

Recently, Fedora infrastructure requested everyone change their password and upload a new SSH public key. We gave folks almost 2 months to make the change. I’d just like to note here the reactions we had, divided into 4 ‘groups’ of users. Of course some people were between two of these groups or some probably had slightly different reactions, but this is what my reading of the feedback leads me to:

  1. Group one sees the announcement, skims it, goes and changes their password, generates and uploads a new ssh key, goes back to what they were doing.
  2. Group two sees the announcement, reads it, reads the links off it. Adjusts their firewall, checks their backups, re-enables selinux or applies updates, then changes their password and uploads a new key
  3. Group three sees the announcement. Complains that their private ssh key is safe and always has been, and they know all about passwords and ssh and encryption and this change is unneeded.
  4. Group four doesn’t even see the announcement. They are no longer involved, too busy to read it, or just don’t care

Group one spends about 5 minutes. The advantage to Fedora Infrastructure isn’t great here, but they do have a new password that meets the guidelines and a new ssh key in case they were careless with the old one. Of course they didn’t learn much, so they could be careless with the new one as well.

Group two are the very people we are trying to reach most, and here’s the most advantage to this plan. These people will learn how to improve their security some, how better to handle their ssh private keys and hopefully prevent compromise on their personal machines. They may spend a good deal of time following the links and learning about best practices, but it’s all time well spent.

Group three are the vocal minority. While they already know best practices and keep their ssh private keys safe, they don’t realize we have any way of telling them apart from group 4 (below). Time spent here is large for both them and Infrastructure folks, but advantage is low because it amounts to “I know I am fine and shouldn’t have to do this” vs “We have no way of knowing that”. There are likely a less vocal subset of these folks that show up in Group one (just do it and grumble and move on).

Group four is another group where there is good advantage for infrastructure. These are folks that are gone, don’t pay attention to their Fedora work, or are too busy to spend a few minutes on it. Packages with these folks as maintainers would be better off being orphaned and reassigned to people who use and care for them. Sysadmin groups with these folks are better off not having someone who they think are involved, but really doesn’t have time to be.

So, in the end I think there is still good advantage to us having done this. I hope the folks in group two are large and learn from our documents and best practices. I hope the people in group three realize that this isn’t just about them, it’s about the community, and I hope pruning the people from group four helps improve the health and activity of our community.

Finally, as a side note, the deadline was last night, but we are still assessing exactly how we want to mark inactive folks who haven’t yet changed their password and uploaded a new key. You still have time to go do it now. ;)



November 30, 2011

Paul Hummer : THE Ubuntu Success Story

Last night, I came home from a meeting, kissed my wife, and was walking back upstairs when my coat started vibrating. I pulled my phone out to see that I was too late, and wasn't able to answer a phone call from my dad. I called him back, and here's a summary of the beginning of that conversation.

Me: "Hi dad."

Dad: "Hi"

Me: "Did you call? What did you need?"

Dad: "I did. I installed Ubuntu and now I'm trying to figure out how to install the driver for my video card."

Me: "Waaaaaaaaaaitaminute. There's a backstory here that I have to know before we go any further."

My dad is "technical". I remember as a little kid realizing how excited my dad was when he was installing Windows 95 the day it came out. I spent summers and school holidays making money at the company he worked for by being the floppy swapper when installing software. He was also the person who introduced me to the term "freetard". He's always been pretty resistant to free software, and sometimes for good reason (ever tried sending a document back and forth between on OpenOffice environment and a MS Office environment multiple times?). Last year for Christmas, my little brother Matt received a netbook that got infected before Christmas Day was over. I offered to put Ubuntu on it (something he wanted) but my dad was so resistant that he went out and bought a USB CD-ROM drive just so he could make sure Windows stayed on the machine.

For me, Ubuntu has never been about "So easy my mom can use it", but "So simple my dad doesn't have a reason not to use it".1

As the story unfolded, my dad had been exploring the idea of virtual machines for a client, and had installed Ubuntu in a Virtual PC environment on Windows 7 host. Unfortunately, his video would only give him 800x600, when his Windows XP guest would fill his dual-monitor setup easily. He expected this to be a driver issue (Virtual PC apparently doesn't have a driver pack for guests like VirtualBox and VMWare do). I found this article, but as I looked at the instructions, I thought "Holy crap. I wouldn't even do this." It became pretty clear that Microsoft Virtual PC was a pretty hostile environment to anything non-Windows.

At this point, my dad starts asking about the Windows installer he saw for Ubuntu (Wubi). Most of his concern centered around whether or not it was going to screw up his Windows partition (it doesn't). After a bit of talk about Wubi, we ended the phone call.

This morning, I get an email from him that says:

Installed 32-bit Ubuntu on my system last night (Wubi). Booted this morning and found that my USB keyboard/mouse combo is not recognized at Ubuntu login screen. No time to troubleshoot this morning before work and probably won’t spend a great deal of time on it, but wondered if you had any ideas of things I could try this evening.

Sounds like he's got a bluetooth keyboard/mouse combo that is having problems. It's not a happy ending just yet, but it's a giant step in the right direction.

The Chasm. Ubuntu is crossing it.

1 I gave my mom my old laptop, running Ubuntu, and connected to Landscape so I can manage it for her. She's not technical, and Ubuntu satisfies most of her computer needs (the only one that it doesn't satisfy is that she has no genealogy software that's compatible with the other software she uses).



November 29, 2011

Tummy.com Blogs : Python Template for Omnicompletion in Vim

From: Sean Reifschneider

Vim Omnicomplete is extremely useful. We use vim for an internal project and have some cases where I wanted to do a custom Omnicomplete, however I'm not really that comfortable with vim's own scripting language. Looking at the existing completion scripts really wasn't helping much either.

What I really wanted to do was build the "omnifunc" completion function in Python. After a few hours of playing, I was able to come up with exactly that and get my completion code working. Now when I press Control-X Control-O I get a menu of my custom completion items, based on project names. It's wonderful!

So I spent a few more hours cleaning it up and making it into a template that hides all the magic and presents (what I hope is) a dead simple structure that a Python programmer can use to make omnicompletion plugins. I've released this template on github as: vim-omnipy-template


November 28, 2011

Kevin Fenzi : Reminder: Fedora password and ssh key change deadline looms (2 days left!)

Just a friendly reminder: If you are a Fedora account system account holder, and haven’t changed your password and uploaded a new ssh key since we announced the mandatory change, you best do so NOW. The deadline is 2011-11-30 (only 2 days away).

If you don’t, you may no longer have access to groups you currently do (like packager, or sysadmin or ambassador).

Go take a few minutes, read the announcement and security information linked to it, and change your password and upload a new ssh public key.

If you aren’t a Fedora contributor, the information linked in our announcement is still a great read and may just help you be more secure on your machines. :)



Tummy.com Blogs : "Word" Doc Authoring with pandoc

From: Sean Reifschneider

This weekend I wrote a lot of documentation. I spent around 12 hours on it in total. I knew there was no way I could stand being in LibreOffice for 12 hours, but I also knew that the consumers would prefer a prettier format than just plain text. I've been writing READMEs lately using markdown format, which converts to pretty HTML on github, so I decided to go that direction. Boy did it work well, once I found the magic tool: pandoc! Read on for more details... (read more)


November 22, 2011

Paul Hummer : Using Mustache templates in Express Apps

Tonight I decided to hack on a quick little webapp and use the opportunity to explore some tech that I've only gotten to tinker with so far. I wanted to build a small webapp with express, but I hate jade templating (I realize this may make me a javascript heretic). Since I'd rather just write HTML, I decided to use Mustache (plus, I have previous experience with Mustache).

The biggest problem with Node.js in general is that development is too fast. Blog posts get out of date really quick. I found a few blogs that show how to do it, but they're more than a year old, and at that point, it's almost worthless. Then I found stache. The docs there helped out to get me most of the way there. Here's what I did to get a basic express app using mustache.

First, install express and stache, and then create a new express app named myApp:

sudo npm install -g express stache
express myApp

Now change into the myApp directory. Edit app.js.

var stache = require('stache');

...import stache and then configure the app to use stache (you'll replace the existing jade config)...

app.set('view engine', 'mustache');
app.register('.mustache', stache);

In this case, I'm using a .mustache extension for my templates, and then passing stache to it as the handler for mustache templates.

In your views/ folder, you should see two files that the express command created by default: layout.jade and index.jade. We want to replace these with mustache stubs similar to these files. Let's start with layout.mustache.

<html>
    <head>
        <title>{{title}}</title>
    </head>
    <body>
        {{{yield}}}
    </body>
</html>

In stache, {{{yield}}} seems to be a special keyword for using the subtemplate. Make sure you remember all three suspenders around it, or you'll spend 20 minutes scratching your head and wondering why the HTML is being escaped (a behavior I hadn't ever used in mustache).

Now in index.mustache, we add the following:

<h1>{{title}}</h1>
<p>Welcome to {{title}}</p>

At this point, we've got a similar layout and template to the jade templates. The last thing left to do is change the data structure of the context we pass (since mustache wants the template context in a different format). Crack open routes/index.js and change the res.render call to look like this:

res.render('index', {
    locals: {
        title: 'Express'
    }
});

Now fire up the app with node app.js and hit /. Does everything work? Hooray! If not, uh, sorry. I'd be interested to know what didn't work, so I can fix the post.

In fact, since Node.js posts tend to get out of date, if this one does, please let me know and I'll update it accordingly.



November 13, 2011

Tummy.com Blogs : ineedpy2: Library to run newer Python from a system-installed Python.

From: Sean Reifschneider

One problem that production system administrators have is running systems with older Python versions installed as /usr/bin/python. Worse, you probably have some systems with a newer Python and some with an older Python. For example, in our environment we're managing some systems with Python 2.1 and some with Python 2.6...

And you can't just upgrade /usr/bin/python, because that will likely break many other things on the system, mean that packages that provide modules either have to be rebuilt or are no longer reachable by the Python interpreter, etc...

We've been struggling with this for one of our system maintenance packages, where there is newer Python available on the system, but just doing "#!/usr/bin/env python" will pick up a very old version.

The "ineedpy2" module will either try to find a newer Python version and re-run the currently-running program with that, or you can specify a minimum minor Python 2 version that you need, and only if you are running something older than that will it swap in a newer one. For example, you may have both Python 2.6 and Python 2.4 on a system, but 2.4 is sufficient, so you don't need to do the extra work, but if you are running under 2.3 it will.

For example, you can say "ineedpy2.rerunonlatest()" to get the latest available Python on the system, or "ineedpy2.requireminor(4)" to only re-run the program if you are on 2.3 or older.

I've released this module on github at https://github.com/linsomniac/ineedpy2 and will put it in pypi soon.


November 08, 2011

Tummy.com Blogs : Switching from hardware to software RAID.

From: Sean Reifschneider

A few weeks ago I had a 1U system that had a RAID card, but we needed to add more network interfaces to. I had the idea of switching it to software RAID, freeing up the only slot for the network card, and it went amazingly smoothly.

The bulk of the system was installed on an LVM, with just a small /boot partition. So what I did was add two drives to the system, and partition them with a small partition for /boot, and the remainder for LVM. These partitions were set up with software RAID-1.

I then added the LVM partition to the existing LVM, and did a "pvmove".

"pvmove" is a great tool that tells LVM to move the blocks from one device to another. It achieves this by first creating a mirror of a block from the source device on the destination, waiting for that mirror to sync up, and then breaking the mirror by removing the source block. After an hour or two, with the system still operating normally, the source RAID array just contained /boot.

Finally, I copied the /boot partition over to the software RAID, rebuilt the initrd to include the software RAID tools, re-ran grub-install on the two new drives.

So with fairly little muss and fuss, and little down-time, I had migrated from a hardware RAID array to software, on 2 new drivers. LVM is a very wonderful thing!


Tummy.com Blogs : Automated changing of Postfix configuration.

From: Sean Reifschneider

As part of system automation work, the other day we were talking about changing the postfix configurations. Mention was made of using sed, but I brought out "postconf -e", a tool that postfix provides to allow modifying the configuration. Particularly useful for more complicated entries which can span multiple lines and a simple sed script wouldn't do the right thing.

You run it as: "postconf -e name=value"

This will modify the configuration to change the setting "name" so that is assigned the value "value". Of course, proper quoting is necessary if you are using special characters.

I also frequently use "postconf" to have it tell me what the current configuration is (because sometimes looking at the file it isn't obvious) and "postconf -d" to tell me what the default configuration values are.

Definitely useful tools to have in the tool-box.


Paul Hummer : YUIConf 2011 Day 2

A few days late, sure...

Once again, I pity the fool who looks at my notes expecting them to be coherent. They make sense to me, and that's why I took the notes. Here's the highlights:

Andrew Wooldridge - YUI Hidden Gems

I didn't expect to take many notes here, since I'd taken my fair share of dives into the YUI source code (I generally no longer care to read the online docs), but Andrew pointed out a few things I had glanced over and missed the value of. Among them, he mentioned:

  • Y.Frame - this is a wrapper for using the IFRAME element. It creates a YUI instance inside the IFRAME, so there's sandboxing, etc. but without the complications that come from IFRAME communication. There are quite a few places that we could use this in Ubuntu One. In particular, I think we could use it for the multi-file upload that we've been wanting to do for a long time.

  • Y.DOM.inViewPortRegion - The previous day, I went looking into the ImageLoader source to see how it worked, since the NFL talk mentioned a WidgetFold that only rendered the widget when it came into the viewport, and I was curious how it did it. Even though I had found this hidden gem the day before, it's worth noting its value in all sorts of cases. What I'd like to do is make a synthetic event for Node such that we can hook eventHandlers into "enterViewPortRegion" and "exitViewPortRegion" or something similar.

  • Y.on('hover') - How did I miss this? It's a synthetic event that YUI provides, since mouseOver and mouseOut can be a bit of a fun house of edge cases. Quite useful.

  • Y.on('clickoutside') - I use this in my little phazr library to close on Overlay or Dialog. It's fantastic.

  • Y.Later - A wrapper for setTimeout and setInterval. I made specific notes to play with this in some of the U1 things that I'm working on right now.

Eric ForRealYo - The App Framework

This talk Melted. My. Brain. A common theme that I heard repeatedly was that people tend to implement things in YUI, and right when they're finished, the YUI team announces the exact same thing in YUI. I did this recently with the App Framework.

The App Framework in YUI 3.4 leaves just a bit to be desired, but Eric's talk made it clear in his talk that all those desires will be available in YUI 3.5 (with a promised pr release in December). Eric had mentioned earlier in the week that he kind of looked at the iOS UI framework API when designing the App Framework, and I can see that connection. It's got a pretty good disconnect between data and presentation, which can often be kind of painful if you don't give it some thought. A nice API like the one the YUI team has designed makes it easy to design things correctly without putting too much thought into it.

One of the things I'm looking forward to the most in YUI 3.5 is the addition of support for Handlebars templating. This templating will be directly connected into Y.View, but won't be compulsory, so you can use any template system you'd like, and aren't forced in to Handlerbars.

As it stands now, YUI 3.4 has some of the App Framework stuff, and in particular, it has Model and ModelList, which have events that can be hooked into. To me, that's the best way to start using the App framework. Create widgets that handle events in your Model and ModelList instances. At the very least, that means that I have a clear upgrade path from my app framework to YUI's (so I don't have to maintain code, I can just file a bug and complain... :)

After all of this, it became clear that I've been neglecting the YUI Gallery, both in contributing to it and using it. I need to remedy that.



November 04, 2011

Paul Hummer : YUIConf 2011 Day 1

Day 1 of YUIConf 2011 is over. I didn't keep copious notes that are coherent to anyone but myself. Here is a congealed version of my notes (hopefully they aren't too hard to follow).

Dav Glass - Keynote

Dav said something that seemed to ring very true to me about the "Graded Browser Scale". Instead of talking about browser support, he started referring to it as a list of platforms to test on. If everything works on that list of platforms, it should work on everything. This is usually the way that I think about testing my own projects, and probably the way we should start thinking about Ubuntu One (granted that we don't see too much IE 6/7 on Ubuntu One currently).

The YUI team is starting to think more about time based releases. Having worked for Canonical for so long, I love the "cadence" that time-based releases bring. I hope this means new YUI features are available in a faster manner, but mostly I'm looking forward to the promise of being more open with what features are being worked on. It seems that we at Ubuntu One aren't the only ones implementing things that the YUI team end up releasing right after we finish writing it.

Luke Smith - From one, many; From many, one

One of the hardest and most overwhelming things about YUI is figuring out how to implement features. Should I use a Plugin, a Widget, or an Extension. Along with that, if you're used to class-based inheritance, inheritance (or the oddities thereof) of javascript is a little awkward. In general, for what I'm building, I don't need to worry about how the constructors link together, so I usually just build off of Y.Base and everything is fine.

One really important thing I had previously personally asserted and Luke confirmed to me is this: Unless you have a valid reason, use Y.Base.create.

Jeff Craig - Demystifying Loader

This was easily the best talk I went to today. The YUI Loader is a fantastic little piece of YUI, but it's also a black hole for documentation and isn't something most people grok. At Ubuntu One, we use convoy for combo loading YUI, and our configuration is a bit complicated. I've known about some of the things we could do to make it less complicated, but this was pretty beneficial for me. Particularly, the Loader can conditionally load modules, which should help in cases where we use modules to "monkey-patch" other modules in certain cases coughIOcough.

Ryan Cannon - There is no off-season.

Ryan talked about implementing YUI on NFL.com. This is very similar to a talk I proposed for YUIConf this year as well. Essentially, I like the stories of "This is how we got our site all working in YUI". They wrote a really neat sounding widget they called WidgetFold that only rendered the widget once the user scrolled down to see the widget. I can think of all kinds of uses for that kind of widget.

The highlight of Ryan's talk was "Are you writing scripts or building applications?" He used it in the context of picking the right tool for the job. I often bring up this theme when people ask "Why not just use jQuery?", but the way Ryan phrased it is pretty excellent.

I bypassed taking notes for the last two talks of the day. After dinner, Douglas Crockford spoke. My notes would make absolutely no sense, in that they are all over the place. The talk was about jslint (which Doug wrote). As a summarizing quote (although it doesn't nearly do the talk justice), I noted "use of good style can help reduce errors".

Afterwards, someone pointed me to the github issues page for jslint. Doug's responses are pure comedy. Next time I'm having a bad day, instead of going to laugh at bad Craigslist personals, I'm going to laugh at jslint issues on Github.



November 03, 2011

Davide Del Vento : Moved to Debian

After a few years of being a happy Ubuntu user, I was getting tired of their too much consumer-oriented focus. I mean, I am a geek and I don't care much about the latest and greatest Unity, UbuntuOne, Apple-like styling like why-don't-we-put-the-windows-buttons-on-the-left and the likes. Worst, I was annoyed by this stuff. Don't take me wrong, I still recommend Ubuntu to family and friends (most notably, my father in law is a good example). But myself? I wanted something more suitable to my geek soul. So, I tried Debian (Wheezy, current in testing to be precise).




You know what? It's great, works out of the box as Ubuntu (on a super recent hardware which has some weird driver requirements), doesn't have the consumer-friendly the-geek-in-me-thinks-it's-crap feeling of Ubuntu. There are a couple of minor things to tweak, such as it doesn't install vim by default (like Ubuntu, see here, some of it applies to Debian too). The only Debian-specific problems are the gnome-display-properties (I still hate the GNOME policy of using a different name on the window) keeps forgetting that I have two monitors. And it doesn't suggest to install the stuff you don't have by default. But nothing too bad that I wouldn't figure out myself quick. If you just one to do a single thing, the most useful one is to include the following aliases (like in Ubuntu):
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias sudo="sudo "

Why I did the latter is left as an exercise to the reader :-)

Bottom line, I plan to run Debian for a long time.


November 02, 2011

Kevin Fenzi : Bugside manners

Looking at a bug report today, I saw some pretty poor “bugside manners” on the part of a few people (including the upstream developer). There’s tons of examples out there of good bug report interactions and poor ones. I’d like to urge everyone to take a minute and think before posting that next bug comment.

Good bugside:

  • Ask for facts. Program output, versions, exact behaviors
  • Provide info if asked for it by others
  • Try and see the issue from the reporters view
  • If you find yourself unable to say something nice or move the bug along, perhaps you should refrain from saying anything at all

Bad bugside:

  • Don’t pile on unrelated bugs. Open a new bug for a new issue.
  • Avoid talking about “big picture”/design/philosophy. Those should go to mailing lists or the like, bug trackers are to track and fix bugs
  • If you don’t have things to add about the specific bug at hand, don’t post

I’m sure there’s other good/bad rules. Anyone run accross any other common good or bad bugside manners they want to share?



November 01, 2011

Kevin Fenzi : Dear IBM

Your blade centers are pretty nifty… however:

a) Isn’t there any way the remote console could just be vnc directly instead of requiring a java applet? Because the java applet has various issues and there are some very nice direct vnc clients available. It would be less hassle for you even. ;)

and

b) Could you pretty please have servers pop up a list of boot options/items right away, even if it takes 10minutes to finish booting to any of them? Having to spend 10minutes staring at a java applet waiting for the 10 seconds I can press “1″ to get to the SMS menu is sure a drag on my time management. Especially when it doesn’t take the keypress and I have to just do it again.

Thanks!



October 25, 2011

Paul Hummer : Skeleton Jump is out!

Last night, Skeleton Jump got published to the App Store. Download it!

I've been working on this game for about a month, having had no previous iPhone development experience (outside of tinkering, really). I've been terrified of putting this out there, knowing about some heinous bugs that still exist in the game (but I can't find the cause for). It doesn't look like many people have problems with them, so I've been afraid for no reason.

Hooray for releasing code!



Paul Hummer : Thoughts on Mobile Development Platforms

I've been thinking about writing this post for about a month now. I should preface it by saying that I've found myself internally conflicted between software freedom and making a living. This is a fact that I'm reminded of every time I point out to a member of the Ubuntu community that I've moved from working on Launchpad to working on Ubuntu One. Let me be straight about this: I love Ubuntu, and I love software freedom. I also love fistfuls of cash. Some days, this internal conflict is maddening.

I have loved games since I was young enough to remember. My interest in technology came from learning to repair my NES console when I was 5. Last month, I met a fantastic artist named Jess Smart Smiley. He and I conspired to make a Halloween themed game in our spare time.

I don't have much of a desire to create games professionally, so I'm more interested in designing and creating games classified as "indie". Having blogged about the potential ecosystem for indie games before, I already had a head start on what our first target would be.

The first thing we thought about is existing and mature development libraries. The most popular mobile game framework is cocos2d. It was originally a framework for iOS, but also has an Android port. I also considered Ansca Mobile's Corona framework, but its high cost for both platforms (iOS and Android) made me eliminate it. The Android port of cocos2d had it's last commit Nov 15, 2010.

After looking at software, we started looking at the hardware. I have never owned an iPhone, but I've owned every one of Google's official Android phones. My wife has also had Android phones for a number of years now. She's not a gadget person, but she recently fell in love with an Android tablet (the Asus Transformer) and so we have a number of Android devices around the house. The only iOS device we had was my iPad. As I looked at the form factors and various hardware for Android, I thought "Oh man, this is going to be a QA nightmare." I tried out a number of Android devices and they each had their own quirks/lag/bugs. With the exception of a weird home screen bug in my Android devices, I never had that "lag" that everyone seems to be complaining about on my Nexus phones, but my wife's first Android phone was a huge piece of junk with a plastic touchscreen and Android 1.6. There are basically 4 different hardware configurations for iOS, and only 4 (currently).

We decided that our first game would target iOS.

After we decided on iOS, I had lunch and/or !coffee with a few local mobile game developers. All but one had experience with both Android and iOS. They all had the same problem with the Android market: people decompiling/recompiling their apps and putting them on the Android Market for free. It's basically an arms race at that point, where you spend your days sending takedown notices to various Android stores instead of developing new stuff. The developers who were still committed to Android said that the only way they've made money is by using ads. I don't like that, since your mobile's screen is small enough already without ads taking up part of the screen (or dealing with artificial load times while you show ads).

We'll probably move into Android in the future, especially with its market share growing like it is. However, for the our first game, I feel confident iOS was the best platform to deploy to.

If you're interested in our game, become a fan of Skeleton Jump on Facebook!

UPDATE: Lucio points out on Twitter that cocos2d is actually originally a python implementation. I knew this, but didn't see much connection between the two.



October 12, 2011

Kevin Fenzi : Passwords and Keys and changing them

This morning, we announced that we are requiring Fedora contributors to change the passwords and upload new ssh public keys by the end of next month. There’s no breach or cause for alarm, we just thought it would be a good time with all the high profile hacking happening out there for everyone to go look at their security practices and create new keys and passwords (see the announcement for full list).

Please do go and change your password and create a new ssh key at your convenience (but before 2011-11-30).

I’m sorry that the ssh key requirement has caused stress for some contributors, but realize we are not singling anyone out here, there’s good reasons to ask for this change now when it’s not urgent or triggered by outside events. Just a few of them:

  • Allow you to revisit your security process and policies and read about best practices
  • Allow you to see how to make changes and what machines and places you need to make them in the event you were making a more hurried change
  • Allow you to setup a separate ssh key for Fedora matters. This separates out some risk, at the cost of another passphrase and possibly hitting ssh server limits (most allow you to try only 6 keys).

While many of the more savvy Fedora contributors already know these things, and have good practices, we hope that everyone will learn something from this or at least not let it inconvenience them for too long.



Paul Hummer : Confusing UX: Facebook's Lists

One thing I really like about Google+ is the ability to limit your posts to a "Circle" of people. Facebook recently added a similar feature. I decided to try it out and share a post with all my roller derby friends (including my wife). So I start exploring the UI and hit this:

Facebook list ui

I had no idea what to put in the "Hide this from" text box. Maybe "everybody else"? Turns out, you can ignore it, and it'll be limited to just that single list. I assume that box is so that you can add a list and then exclude someone. Please to hide that away, or even take away the feature entirely.



October 03, 2011

Tummy.com Blogs : Lucid hangs after "Begin: Running /scripts/init-bottom".

From: Sean Reifschneider

I recently had a kernel bug that caused a process to hang in D (disc wait) status. I decided to do a reboot, but thought I'd try upgrading the kernel before I did that. The kernel upgrade also got stuck in "D" while trying to do a depmod, so I finally did a reboot, and had to hard power down.

During the reboot, it would get to where it would say "Begin: Running /scripts/init-bottom", and hang there. I searched around and didn't find much, so I figured I'd document the solution here.

I booted into rescue mode (off the initial media, I wasn't able to boot with "init=/bin/sh"), and then got a shell in the root file-system. I did a "dpkg --configure -a", and then rebooted and that solved the problem.

I found this issue by trying to run "apt-get update" in the rescue environment and it helpfully told me that it had been interrupted and I needed to run the above command. :-)


September 25, 2011

Tummy.com Blogs : Introducing nanomon: Extremely light-weight monitoring.

From: Sean Reifschneider

Last month I had wanted to try to get some real monitoring of a bunch of my personal systems. I spent weeks dabbling with setting up a serious monitoring system (tried Zabbix, Zenoss, nagios, and Opsview), but I was making little if any progress with those. Largely that was related to running a RHEL 6 derivative and running into compatibility problems...

After spending around a day of effort on them, I decided to roll my own. My needs were modest, I wanted to be able to run some nagios check scripts and get an e-mail if checks failed continually for 15 minutes. But not get e-mails every 15 minutes if they were down, and only alert if they failed several times.

Read after the fold if you're interested in my solution... (read more)


September 13, 2011

Paul Hummer : I Hate the Android Back Button

Android's Back button (whether in hardware or software) is braindead. I can understand the technical reason for its behavior. It's supposed to take you to the previous Intent...

...unless the current app has overridden the Back button.

Here's an example: Yesterday I attended BLDR.UX11. When I got into Boulder, I pulled over and pulled up my email with the ticket confirmation in it (using my Nexus S phone, not an Android phone with crapware on it). From there, I opened the conference web site. I then found an address for the venue and clicked on it, opting to open it in Maps. Once there, I had Maps give me directions to the venue, and then hit the Navigate button for turn-by-turn navigation. When I got to the Boulder Events Center, I grabbed my phone and hit back, which took me to the Maps app (from Navigation). I hit back again and it went to the BLDR.UX11 page in the browser. I hit back again. WTF? Now I'm looking at an article I read on my phone while waiting in the doctor's office a week ago. At this point, I repeatedly mashed the back button out of frustration until I was at the Home Screen (I realize I can use the Home button-I blame muscle memory).

While at BLDR.UX11, I met lots of folks who feel that having a single unified experience across mobile devices is a myth, and almost all of them cited the Back button as the reason. Some people go as far as to create their own back button in the app, which just makes the matter worse: now you have TWO back buttons.



September 05, 2011

Paul Hummer : Cancelling my Safari Books Subscription

I subscribed to Safari Books Online a few months ago. I like the idea of monthly subscription access services à la Netflix, and I tend to read a lot of technical books, so it seemed like a good idea. I just went through the flow for canceling that subscription, and I thought I'd document the reasons why, in case anyone else was curious.

Safari subscriptions have tiers, and you pay a monthly amount based on the tier you pick. I took the cheapest route, and opted for the 10-book "bookshelf". I thought it'd be fine, since I try real hard not to read more than 2 books at the same time (and usually I try and make one a fiction book). I went through and found a set of books I wanted to read, and added them to my bookshelf, essentially creating a backlog.

In order to start reading, I had a few choices: read on my computer, download a chapter at a time, or read on a mobile device with the app. Since I sit in front of a computer all day, I didn't want to spend my relaxing time in the same place. Downloading a chapter at a time wasn't at all economical, since it was quite painful to assign a "download token" to the download, and I was limited in the number of download tokes I could have every month. I installed the app on my iPad, and went to reading.

The iPad app crashes constantly. It requires an internet connection, so that limits where you can read it. If the iPad went to sleep at all, I had to re-authenticate the app with my account, often making it lose my place in the book in the process. When I turned pages, there was a latency that made the first-gen Kindle look blazing fast. Some of the books were essentially glorified PDFs, so you couldn't resize text or even highlight it. It was really painful.

By the time I finished two books, I wasn't really interested in reading any more of the books I'd put on my bookshelf. When I went to remove them, I found that they had to stay on my bookshelf for a minimum of a month. If a book takes me a month to read, it had better be a freakin' HUGE page-turner. At this point, the higher tiers started making more sense to me. It was obvious why someone would want a larger bookshelf now. I had gotten so trigger happy that I added books as a backlog that I never read, but sat in my shelf because I had to have them there for 30 days.

The one saving grace is that I had added some instructional/tutorial videos. I would regularly put these on while I cooked dinner or washed dishes in the evenings. There was one about gamification and one about Cassandra that I particularly enjoyed. I was never able to get the videos playing on my iPad, so I'd just prop my laptop on the microwave and play them. There were some bugs with playback on my laptop, but I chalked most of them up to Flash just being extra stupid (which is always a safe assumption).

Recently, Safari released a new mobile site, so I thought I'd give it a chance. I read an entire book using the mobile site. It too requires an internet connection (obviously). There is a "Remember Me" checkbox when logging in, which I was pleased to see, since the app didn't have one. I guess the mobile site has Alzheimer's though, since it would forget who I was even if I merely switched to another "tab" of the browser. There was also a section of the book that was mostly code or diagrams, so I'd flip through the "pages" pretty quickly. If I did it too quick, the site had to verify that I was human by prompting me with a captcha, which isn't very accessible, but also is a terrible thing to have to sort out on a mobile device.

I understand the need for DRM on content I don't own. If I check a book out of the public library, I'm not against the library putting protections to make sure I bring the book back. Netflix requires DRM to stream, and I don't mind that. The kicker here is that in both cases I don't notice the restrictions while enjoying the content. Safari, on the other hand, always had fiery hoops for me to jump through. After getting a singed a few times, I think I'll pass.



August 31, 2011

Kevin Fenzi : laptops and mail flow

Recently, the filesystem on my trusty Dell D820 laptop started having some problems. It’s using btrfs and installed back when btrfs first showed up, so I am no too surprised that something happend with it. Side note: Josef (btrfs maintainer extraordinaire) has been absolutely great in helping track down and fix it, see https://bugzilla.redhat.com/show_bug.cgi?id=726814 for the nitty-gritty.

So, I decided at least for now to move to another laptop here (thinkpad t510). First order of business was to add memory and replace the 1600×900 screen with a nice 1920×1080 one. This went very smoothly. The lcd replacement was easy and made a gigantic difference. My D820 has a 1920×1200 screen in it, and I really didn’t want to move to too much smaller resolution. The higher resolution screen on the 510 also looks MUCH nicer: brighter colors, crisper and all around more pleasant.

Since the filesystem corruption was preventing me from just mass copying everything off the old machine, I just synced over a small list of things I needed: ssh keys, keepassxdb, xchat logs/settings, midori browser history.

This gave me a great chance to (re)setup my mail and it’s filtering. I’m a long time claws-mail user, and adding filters is pretty easy. So easy that I had added tons of them over the years. Seeing my full flood of email to my main mbox gave me a chance to look at things and ask: do I read this? Should I unsubscribe from this list? Do I need to save logwatch emails from my home machines? Do I care when something is auto-discarded from mailman? After just a few days I pretty much had everything filtering away, and in much better shape than I had things before. So, this might actually end up being something I try and do once a year or so: Drop all my filters and re-check my incoming emails for what really matters.

F16 prerelease is running great on the Thinkpad. Everything works out of the box. In fact aside from an anoying glibc resolver bug (which I am running a patched glibc for), this release is looking quite stable and boring so far. ;)



August 22, 2011

Paul Hummer : Ubuntu One and YUI: "Stale" events

A common pattern in any asynchronous web app is creating an item asynchronously, and updating the page to reflect that new item. This is pretty core functionality of Ubuntu One's Manager widgets.

What we started doing is something like this:

onSubmitForm: function(e) {
    var name = this.get('nameNode').get('value');
    Y.io('/notes/new', {
        method: 'POST',
        on: {
            success: Y.bind(this.onNewNoteSuccess, this)
        }
    });
},
onNewNoteSuccess: function(id, response) {
    Y.io('/notes/list', {
        on: {
            success: Y.bind(this.onNoteListSuccess, this)
        }
    });
},
onNoteListSuccess: function(id, response) {
    this.set('noteList', response.responseText);
}

This is obviously asynchronous. The problem is that once you start doing this six or seven times (or ten) times, it starts to get pretty messy. It becomes a pain to come back even a few weeks later and trace your steps through the code again. Part of this is asynchronous code in general, but you can make some very easy changes that make it a little easier to keep context in place.

One of my absolute favorite things about YUI is that it creates an API on top of the browser specific APIs, and thus allows for fun "middleware", such as YUI's support for custom events. With these events, you can do things like:

Y.fire('stupidMadeUpEvent');

...but, of course, that would be a no-op unless we had previously done...

Y.on('stupidMadeUpEvent', function(e) {
    Y.log('The stupid event I made up just fired');
}

Once you start to see the vision behind it, it actually allows you to do some pretty clever things. For instance, I like to be able to mark page fragments as stale, and have an event listener go and update that page fragment when needed. The above code then looks closer to this:

bindUI: function() {
    this.on('noteListStale', this.onNoteListStale, this);
},
onSubmitForm: function(e) {
    var name = this.get('nameNode').get('value');
    Y.io('/notes/new', {
        method: 'POST',
        on: {
            success: Y.bind(function() { this.fire('noteListStale'); }, this)
        }
    });
},
onNoteListStale: function(id, response) {
    Y.io('/notes/list', {
        on: {
            success: Y.bind(this.onNoteListSuccess, this)
        }
    });
},
onNoteListSuccess: function(id, response) {
    this.set('noteList', response.responseText);
}

This actually doesn't seem to be any more asynchronous or any faster, but I will say that it makes our code a bit more maintainable. Your mileage may vary.

You can fire an event on any event target in scope (which includes Widget, Node, and EventTarget objects). Between attribute change events and custom events, I find that most of my entry points for code are specified in bindUI.



Paul Hummer : Rasta.js and Selassie

My wife wasn't feeling well today, so I spent an inordinate amount of time inside, divided pretty evenly between tending to her, reading and tooling around on the internet. Hacker News had an item about Rasta.js. It's a simple javascript key/value store. It seemed like a toy library that didn't serve too much purpose, but was cute, and got me thinking. I played with it a bit and was intrigued. I've been thinking about various ways for javascript to log errors to a server for inspection later, and it looks like that's what the author of Rasta.js was doing as well.

Boredom became mindless farting around as I decided to implement the server side of the API. I'd never implemented the server side of JSONP, so it was also a bit educational for me as well. The output became Selassie, a toy server to go with Rasta.js. Emphasis on the "toy" part.

Comments welcome.



August 21, 2011

Paul Hummer : Bazaar Workflow Revisited

I have had a few conversations with various people recently about Bazaar workflows. I've previously blogged about my workflow, but it's been changed a lot since then. I figured I'd address it again.

I no longer use shared repositories and separate branches and lightweight checkouts like I detailed here. I've known for a long time that this isn't the easiest way to set up Bazaar, and every time I explain it to someone, I would watch as their eyes glossed over (don't worry, when Aaron Bentley originally explained it to me, I had the same reaction).

I now use the bzr-colo plugin. I started using it about the same time that the Bazaar mailing list started talking about making it the default in Bazaar 3.0. bzr-colo keeps your repository and its branches in a central location, and only requires one directory for all of that. There's only one tree, however, and this turns out to be a benefit, in that it keeps you a bit more serialized in work without the constraints that a non-DVCS workflow would create. Now I only have a single directory to worry about, and should I need to switch branches, I don't have to re-create any virtualenvs or dependency trees or anything like that. In fact, I can even keep my development server running (which has some rather hilarious consequences every once in a while).

Here are some aliases I find useful for working with bzr-colo:

cbranch = colo-branch
cpull = colo-pull
trunk = switch origin/trunk
branches = colo-branches
prune = colo-prune

Outside of that, there are two things that annoy me about this. First, it's a really long bzr cbranch <new-branch-name> --from-branch=<remote-branch> command-line just to bring a remote branch into my co-located branch area. That's a huge pain, but I don't have to do that very often. The other is that it's broken my locations.conf file's append_path policy, so I have to fix that bit, and the solution isn't very elegant.

The only other plugin I use is the single best plugin Bazaar has: bzr-pipeline. Most people I talk to don't use pipelines because it requires some really hairy separate branches and lightweight checkouts. The greatest thing about bzr-colo is that you get the pipeline setup for free. I've already posted my easy aliases for bzr-pipelines, but I think they've all been implemented in the plugin now (and I've been too lazy to remove them from my aliases).

I actually quite prefer that I can describe my workflow in two plugins now, as opposed to a series of blog posts.



August 20, 2011

Paul Hummer : Ubuntu One and YUI: Implementing History

Now that we (accidentally) got a crash course in creating YUI widgets in the last YUI post I wrote, I thought I would take the opportunity to go into the Ubuntu One specific YUI lessons learned.

We had a pattern like this in our Manager widget that we used to build the Notes app (I'd show you the code, but I'm too lazy to go back that many revisions and find it).

var Manager = Y.Base.create(...
    bindUI: function() {
        var noteList = this.get('noteList'); // ul node
        noteList.delegate(
            'click', this.onNoteClick, this, 'li');
    },
    onNoteClick: function(e) {
        var id = e.target.get('id');
        Y.io('/path/to/ajax_endpoint/' + id,
            cfg: {
                on: {
                    success: Y.bind(this.onIOSuccess, this)
                }
            }
        );
    },
    onIOSuccess: function(id, response) {
        var mainPane = this.get('mainPane'); // div node
        mainPane.setContent(response.responseText);
    }
}, {...});

In the .bindUI() function, I got the noteList from the ATTRS, and used .delegate() to essentially attach event handlers to every li object in the noteList node. What we're really doing is saying "when the event click bubbles up to the UL node, if it came from an li object, execute this function". Once again, we pass this in to keep context.

In the event handler, we take the node that actually got clicked on from e.target, and have it give us its id. In this case, the id is a unique note id from the database, and our server-side template created the markup in a way that made it easy for us to get that info. Once we have the id, we can make an asynchronous call to a URL that will return a HTML fragment (not usually my preferred way of working, but one that gets results quickly and allows us to not repeat template code on the server and the client).

Since the io request is asynchronous, we give it a response handler. In this case, that response handler is .onIOSuccess(). Basically, the idea is that we take the response HTML fragment and make it the content for the div node we've assigned to the mainPane ATTR.

We did this all over the place. Every Manager widget was like this. It was great, since we'd created asynchronous (albeit crude and probably clunky) web apps.

Here's the problem though: we broke the back button.

Shoot, we broke browser navigation entirely. I hated using it, because it never worked right.

I found the solution in the History module.

Eventually, our Manager then evolved into something like this:

var Manager = Y.Base.create(...
    initializer: function() {
        var history = new Y.History();
        this.set('history', history);
    },
    bindUI: function() {
        var history = this.get('history'),
            noteList = this.get('noteList');
        history.on('noteChange', this.onNoteChange, this);
        noteList.delegate(
            'click', this.onNoteClick, this, 'li');
    },
    onNoteClick: function(e) {
        var id = e.target.get('id'),
            history = this.get('history);
        history.addValue('note', id);
    },
    onNoteChange: function(e) {
        var id = e.newVal;
        Y.io('/path/to/ajax_endpoint/' + id,
            cfg: {
                on: {
                    success: Y.bind(this.onIOSuccess, this)
                }
            }
        );
    },
    onIOSuccess: function(id, response) {
        var mainPane = this.get('mainPane');
        mainPane.setContent(response.responseText);
    }
}, {...});

It looks like we've added another level of indirection. In a way, we kinda have. YUI 3 is really scary looking for the same reason that Node.js is scary looking: it's really hard to not write asynchronous code. It forces you to be more asynchrounous, which could mean more anonymous functions, but I prefer a little more structure to my javascript, so I write it this way.

Basically, we've added a history ATTR which is a History object. History is merely a key/value store, and we can listen for change events on the History keys. Now all the click handler does is get the id and set the value. Our event listener then gets fired, and it does the actual io call, and subsequent success.

We might've been tempted to do something like this:

onNoteClick: function(e) {
    var id = e.target.get('id'),
        history = this.get('history);
    history.addValue('note', id);
    Y.io('/path/to/ajax_endpoint/' + id,
        cfg: {
            on: {
                success: Y.bind(this.onIOSuccess, this)
            }
        }
    );
}

The problem with this is that we aren't listening for changes to our History object's note key, so if a user hits the back button, the change event doesn't get fired.

The one caveat that is still broken is that in browsers that support HTML5 History, we aren't changing the URL in the address bar, so we're maintaining state, but we're not supported an addressable state. I plan to remedy this as soon as I have some time to research the best way to do it and can implement it.

Edit: Immediately after I published this post, I went to read up on the History module again, and stumbled across exactly how to update the URL in the address bar. I've just created a task on our team Kanban board, and I expect that we should have this functionality in trunk next week and available on the website the week after that. Hooray for accountability in blogging?



August 19, 2011

Paul Hummer : YUI and You: How Ubuntu One Built Their Webapps

Note: this post was meant to be all-encompassing. After writing and proofing it, it's clear that this subject will take a few posts to really be descriptive. This post accidentally became a crash-course in making YUI widgets, which is still helpful though, so I'm posting it anyway.

Ubuntu One's website uses YUI 3 for its interactions. The site provides webapps for interacting with the data you've synced to the service from your desktop/mobile phone/various web services/etc. YUI 3.4 was released today, and it has an App framework in it. When I joined the Ubuntu One team in November, I didn't have that luxury.

So I endeavored to build my own...

In each case, I had a pretty self contained application already. They were synchronous, but they were self contained. I started out by creating a Manager widget that would handle all the interactions, etc. The YUI widget provides most of what I needed by default, so I'll start there and leave the more complicated stuff for followup posts.

var Manager = Y.Base.create(
    'manager', Y.Widget, [], {}, {});
new Manager().render('.main');

This creates a Manager object that inherits from Y.Widget. I've given it a name of 'manager'. This helps YUI assign the class 'yui3-manager' to the DOM node that Manager will attach to (called a srcNode). I specify this node when I call .render() on a new Manager object. Now, the first DOM element with the class 'main' is the node that the Manager has attached to. jslint might complain about that second line, since it doesn't like us using 'new' as a command, but we shouldn't need the reference to Manager (it's self contained, right), so just ignore jslint (just this one time). Rendering the Manager doesn't do anything you'd notice without inspecting the DOM, but that's okay. We'll have to teach it about the DOM and what we want it to do as we go.

YUI Widgets go through three different phases when .render() is called: render, bind, and sync. The render phase is for making changes to the DOM. The bind phase is for hooking up event listeners to the DOM. The sync phase is for changing Widget state based on items in the DOM (data that you probably generated and rendered server-side). You can hook into these phase with the following member attributes: renderUI, bindUI, and syncUI.

Let's start out by implementing the render phase and adding a class to all A links, so we can tell that the Manager has loaded.

var Manager = Y.Base.create('manager', Y.Widget, [], {
    renderUI: function() {
        var srcNode = this.get('srcNode');
        srcNode.all('a').addClass('javascript');
    }
}, {});

What we've done here is implemented a .renderUI() function that will be called when .render() is called. The first thing we do is get the widget's srcNode, which was specified by selector when we call .render(). YUI uses getters and setters A LOT (sometimes to a fault). There are lots of clever little things we can do because we're using getters/setters, but we won't go into that now. Basically, understand that srcNode is now the Node that matches '.main' (the first argument to .render()). I then query the node for all A links, and add a class called 'javascript' to all of them. My CSS might define that all a.javascript links are a different color than other links, or have different effects. The sky is the limit; go with what you feel.

There's a much easier way to run DOM queries on the srcNode, however. Widgets are built with progressive enhancement in mind, and so there is a clever way to define things that might already be in the DOM that you want to have access to. We should change our code to look like this:

var Manager = Y.Base.create('manager', Y.Widget, [], {
    renderUI: function() {
        var links = this.get('links');
        links.addClass('javascript');
    }
}, {
    ATTRS: {
        links: { value: [] }
    },
    HTML_PARSER: {
        links: ['a']
    }
});

What we've done here is created two static attributes called ATTRS and HTML_PARSER. ATTRS is where you define attributes for your widget (extra things you can get with <Object>.get() and set with <Object>.set()), along with default values and getter/setter functions themselves. In this case, we default it to an empty list. We then use the HTML_PARSER attribute to specify a selector with which to populate the attribute we specified in ATTRS. In this case, we want a list of all the nodes matching selector 'a'. Now, when we get to the .renderUI() call, we can request the attribute called "links" and the operate on the entire NodeList.

So if we add this to our DOM, we can see the classes for the links change (and apply the CSS you've decided to apply there). This is boring though. How can we start hooking event handlers up to the DOM? That's the real interesting part, amirite?

Let's say our DOM has a link with id 'delete' that should remove a div with id 'item' in it. How would we teach our Manager object how to do that? Like this:

var Manager = Y.Base.create('manager', Y.Widget, [], {
    renderUI: function() {
        var links = this.get('links');
        links.addClass('javascript');
    },
    bindUI: function() {
        var delete = this.get('delete');
        delete.on('click', this.onClickDelete, this);
    },
    onClickDelete: function(e) {
        e.preventDefault();
        var item = this.get('item');
        item.remove();
    }
}, {
    ATTRS: {
        links: { value: [] },
        delete: { value: null },
        item: { value: null }
    },
    HTML_PARSER: {
        links: ['a'],
        delete: '#delete',
        item: '#item'
    }
});

Oh wow. There's a lot of stuff going on here. Let's break it up into a few different pieces. The first thing I did was add the delete and item attributes to the Manager, with the accompanying entries in HTML_PARSER. This makes it much easier to get to the items that we need to work with. The second thing I did was implement the .bindUI() function. Remember, that's the second phase of a widget rendering. In .bindUI(), I get the delete link, and then add a click event handler to it. I've specified this handler as a function called onClickDelete. You can name it whatever you want, but trust me when I say you should name it pretty clearly to show that it's a click event handler for delete. Otherwise, when you come back in 6 months, you'll have to keep scrolling up to .bindUI to see what functions are called when (not fun). The last argument to .on() is the context with which the function should execute. Basically, we're saying "anytime inside the function where we reference 'this', that object should be the object we pass in as the third argument".

The last thing we do is implement the click handler itself, in .onClickDelete(). The call to e.preventDefault() keeps the browser from executing your javascript and then doing its own default behavior. In this case, we're clicking a link, and the browser says "Oh, the link has an href! When we're done with this javascript function, we should navigate to the url in the href." We don't want that, so we call e.preventDefault() to keep the browser from doing that. Then we move on to the nitty gritty of the handler, i.e. getting the item div and deleting it.

The last thing we might want to do is grab data already in the DOM and make sure the widget is aware of that. Let's say that there is a span with the id "name", and its contents has the user's name in it. We might want to store that name for later. We'll just make these last changes here:

 var Manager = Y.Base.create('manager', Y.Widget, [], {
    renderUI: function() {
        var links = this.get('links');
        links.addClass('javascript');
    },
    bindUI: function() {
        var delete = this.get('delete');
        delete.on('click', this.onClickDelete, this);
    },
    syncUI: function() {
        var nameNode = this.get('nameNode');
        this.set('name', nameNode.getContent());
    },
    onClickDelete: function(e) {
        e.preventDefault();
        var item = this.get('item');
        item.remove();
    }
}, {
    ATTRS: {
        links: { value: [] },
        delete: { value: null },
        item: { value: null },
        name: { value: '' },
        nameNode: { value: null }
    },
    HTML_PARSER: {
        links: ['a'],
        delete: '#delete',
        item: '#item',
        nameNode: '#name'
    }
});

So once again we start by adding some attributes to Manager. We add the name attribute, which we default to an empty string. Then we add a nameNode attribute, and specify it's selector in HTML_PARSER. In .syncUI(), we then get the nameNode, and set the Manager's name attribute to the content of nameNode.

The actual Manager widgets on Ubuntu One are a bit more complicated than this, but this should provide a basic understanding of how we've done it so far. Recently, I've learned that this approach doesn't scale very well with the sorts of complicated things we're doing now (and I will blog about that), but it does cover most of the things we have done up until this point.



August 15, 2011

Paul Hummer : Adding OS X Lion Scrolling to Ubuntu

We have two Macs in the house, and they've both recently been upgraded to Lion. Lion has a new "feature" that inverts your scrolling both on the touchpad and the mouse wheel. They want it to feel more like the flick you would do on a tablet.

After using it for even an hour, switching back to Ubuntu's standard scrolling always throws me off, and vice versa. I decided that I wanted my Ubuntu system to scroll like the Mac. This is what I did.

Edit ~/.Xmodmap (it probably won't exist already) and add the following line:

pointer = 1 2 3 5 4 7 6 8 9 10 11 12

Log out and log back in. Ubuntu should prompt you to see if it should use the .Xmodmap file. Tell it you would, and now you have flick scrolling in Ubuntu.

Now I just need to go get a Magic Trackpad so I can play with the gesture support in Ubuntu.



August 12, 2011

Tummy.com Blogs : pycurl.error: (26, 'failed creating formpost data')

From: Sean Reifschneider

The error: "pycurl.error: (26, 'failed creating formpost data')" was a bit tricky to look up, but I was able to find a report on the curl mailing list that this error indicates that the file up are trying to upload via a form upload does not exist.

Sure enough, when I checked the value I was passing as the name of the file to upload, I was using the wrong name -- a name that didn't exist. So if you run into this error, verify that the filename you are passing does exist.

If this answer helped you, please post a link to this page so that it shows up high in the results. I had to do a lot of digging to get the answer.

In general I've been pretty happy with pycurl. I had thought urllib would let me upload a file, but it required a lot of extra code to do. pycurl isn't that well documented, but I was able to find examples that helped me get it done, and I've been happy with curl from the command-line, so I figured I'd try it. Other than having to build pycurl on one CentOS 4 box, and this information-free error message, it's worked quite well.


August 09, 2011

Paul Hummer : LastPass and the YubiKey

I've been thinking a lot about passwords recently. I used to be really sloppy with my passwords, i.e. using the same ones over and over again. In most cases, I think they were pretty long and secure. When Gawker was hacked, I was among those who were compromised, inasmuch as I had an account, but I never got a temp password when signing up, and so I didn't have much to worry about. It would have been a real pain if one of my re-used passwords would have gotten leaked.

I eventually stumbled across LastPass1, which seemed to fit my needs perfectly. It's a cross-platform password storage service. It's free to use in the browser, and has a premium service with some extras like access from my mobile phone. I thought that alone was worth $1USD/mo.

While checking out, I saw an offer for a Yubikey/LastPass Premium Year membership bundle. By default, the Yubikey generates a One-Time Password, but it can also be programmed to hold a static password as well (say, for your encryption passphrase). After reading about Yubikey, I thought I would gamble on an idea I thought had lots of merit, even though the execution could be quite terrible.

The Yubikey shows up as a keyboard to the OS, and then has a simple button you press for generating the One Time Password. Once I connected my LastPass account to my Yubikey, I could no longer gain access to my LastPass account without my Yubikey. The concept of a One Time Password was something I'd never really understood before, but I was familiar with the RSA keyfobs, and did some Googling to kind of learn how it worked. Now I'm pretty glad that I picked up the Yubikey, and wish more services supported it.

I really like the simplicity that the LastPass/Yubikey combination provides. Now I'm thinking about getting another Yubikey to program with a static password for disk encryption. The one (tiny) gripe I have with the whole situation is that the LastPass user experience isn't the greatest, but I can get over that.

1LastPass recently had a security breach. It appears that only those with weak passwords were affected. In the case of using a password and a Yubikey to authenticate, there shouldn't be much of a risk.



August 06, 2011

Paul Hummer : My New Django Deployment

I generally don't like to do sysadmin-y things. They keep me from doing the things I actually like doing: making new things (as opposed to keeping old things going). Until recently, using Apache to serve my Django instances has been enough. I just throw my standard config onto a new VHost and I'm ready to go. I'm much more "dev" than "ops".

It just so happened that I was redesigning my blog at the same time as I was kicking up a new Linode instance to host my friend Kristin's blog, Feasting Fort Collins. After tweaking her site (hint: Ubuntu's apache defaults won't cut it on a small Linode instance), it became clear that I couldn't use the same settings.

So I started investigating a better way to deploy Django apps. This is what I came up (and what I'm using)...

gUnicorn

I chose gUnicorn as my wsgi HTTP server. There's been lots of hubbub about WSGI recently, but in Django you don't really see the WSGI, so it really is a moot point. I used the gunicorn_django script. Here's my config:

bind = "127.0.0.1:8081"
logfile = "/path/to/logfile"
timeout = 10
workers = 1

With that config, I get a single worker on the local 8081 port.

Supervisor

I've always liked the idea of Supervisor, but I've never had a need for it. With gUnicorn running, I wanted a cleaner way to perform start/stop/restart. This gave me my need to use Supervisor.

One gotcha I ran into is that, at least in Ubuntu Lucid, I needed to do supervisorctl -c /etc/supervisor/supervisord.conf whenever I wanted to use supervisorctl. It was apparently looking for the config in /etc/supervisord.conf. I should probably file a bug about that...

nginx

I actually already had nginx in charge of port 80 on this server, since it was a reverse proxy for the above mentioned Wordpress blog. I set up some simple proxy caching to 127.0.0.1:8081.

After that, there were some "new server" woes to deal with. gUnicorn was a bit difficult to get logging information out of until I wiggled it right. I ended up just turning Django debugging on rather than try and get gUnicorn to do sane debug logging. It got to a point where I got it to work (I have no idea how) and now I'm just not touching it (see above how I don't like doing sysadmin-y things).

Of course, I've also updated my automated fabric rules. I'll take the opportunity to automate the "ops" part any chance I can get.



August 02, 2011

Tummy.com Blogs : Intel X-25E SSD Showing Up As 8MB

From: Sean Reifschneider

I've been following this Intel forum thread on failures of the 320 series of SSD drives for a while now after having the Tom's Hardware article on it pointed out to me by our friends at Pattern Review.

So far it's been fairly full of speculation with little concrete information available... A week ago Intel responded that firmware fixes were being worked on.

Read on for more details about this, including the failure I've experienced. (read more)


June 27, 2011

Tummy.com Blogs : Getting the expiration time of an SMTP certificate.

From: Sean Reifschneider

Today I was trying to figure out how to check the expiration time of an SMTP certificate, to verify that after installing a new certificate the mail server was picking up the right certificate. What I came up with is:

SERVERNAME=mail.example.com
printf 'quit\n' | openssl s_client -connect $SERVERNAME:25 -starttls smtp | openssl x509 -enddate -noout

Just for completeness sake, checking it on a web server can be done with:

SERVERNAME=www.example.com
printf 'GET /\n\n' | openssl s_client -connect $SERVERNAME:443 | openssl x509 -enddate -noout


June 26, 2011

Kevin Fenzi : On reboots

Rebooting machines is a interesting study in the varied opinions of the Linux community. On one end, there are folks who will use ksplice or simply avoid rebooting for any reason short of a hardware failure. On the other you have desktop users who reboot their machines daily. I’m somewhere in the middle: For servers if there is a security update to the kernel or glibc that applies, the server should be rebooted. For my laptop, I usually reboot when there’s a reason (I want to test something related to the boot process, there’s a security update, etc).

Rebooting servers regularly (and it seems doing so for security updates accomplishes this) has several other advantages:

  • You can schedule your rebooting. Sometimes power cycling or rebooting a machine puts some stress on the hardware, if it fails, you are able to call for service, etc. If it happens at 2am on sunday morning when you have 9 to 5 business day coverage, you are in much worse shape
  • Even with configuration management there are times when things are added to a server, but not set to start on boot, or need some config change to start properly. Better to fix those in a maint window than to not have them come up after an unattended reboot
  • You can find out a lot about your servers and how they interrelate, and where the points of failure are by rebooting them
  • Do you recall how to get to that serial console / IPMI / pdu / kvm for that server? Scheduling a reboot is a great time to make sure your console access works and shows the boot process.

Fedora Infrastructure has about 150 or so machine instances to manage currently. Until recently the mass reboot process was pretty much just scheduling a block of time and powering through rebooting things. Often we would go over our window as that is a lot of machines to reboot and confirm are back up nicely. So, I worked on changing our process for mass reboots. Now, all hosts are put in 3 different buckets:

  • The “C” group. These are machines that only infrastructure folks will notice are down or are machines where there are redundant resources, so they can be rebooted anytime as long as failover or dns changes are made first so no live traffic is still hitting them.
  • The “B” group. These are machines associated with Fedora contributors and package manintainers. End users won’t notice these being down, but contributors/package maintainers will. These reboots need to be scheduled, but since there are few machines in this group, the outage is small.
  • The “A” group. These are machines that end users may notice being down or slow to respond. Database servers or mailing list hubs would be in this group. Again the number is very small, so outages would be very short

Over time, we are working on moving all the hosts in “A” and “B” groups into “C”. Which would leave us being able to reboot things as time permits with no need for any scheduled outage, but at least with the above setup, outages are much shorter and less frantic. The last set of reboots we did, we used the new method and planning, and I think it went much more smoothly. We also discovered some additional points of failure:

  • An nameserver reboot caused some internal machines to stop processing, which allowed us to revamp our nameserver setup and make sure all machines were setup to failover properly to another nameserver.
  • A nfs server reboot in the “B” group affected some web servers in the “A” group. This allowed us to revisit why there’s a dependent NFS mount on those web servers.

True to the Fedora way, the details are available at: Mass_Upgrade_Infrastructure_SOP.



June 14, 2011

Kevin Fenzi : Fedora FPCA deadline rapidly approaching…

If you have not had a chance yet to go and sign in to your fedora account and sign the Fedora Project Contributor Agreement please do so soon! The deadline is approaching this thursday. After that point you will be removed from any groups that require “cla_done”, for example the packager group, or any of the various sysadmin groups or access to fedorapeople.

You can of course be re-added to any groups later, but this could be a annoying and time consuming process. Take a few minutes to look it over today!

EDITED TO ADD: We decided to give another week for a variety of reasons. So, the new cut off is 2011-06-23. We are going to inform group admins and post a list of packages that will potentially be without owners soon.



June 02, 2011

Tummy.com Blogs : Manually checking a RAID array for consistency.

From: Sean Reifschneider

Stephen Warren tonight noticed that one of his backups of his storage server was transferring a file that it shouldn't have been. He was running with the "-c" option to rsync to do a full checksum check, so apparently this file had changed.

Stephen provided these instructions on how to compare the two copies of a file on a RAID array, to verify that they are the same, or in his case different. He wanted me to post them so he could find them again when he has to search google for them in the future. :-)

Read after the fold for the details of how to read from a single drive on a RAID-1 array. (read more)


June 01, 2011

Tummy.com Blogs : The burden of data.

From: Sean Reifschneider

Lately, Evelyn has come up with a very quotable, well, quote:

"Data is heavy." -- Evelyn Mitchell, 2011

We are frequently dealing with the storage, organization, and access of all the data we are accumulating. Part of this is that we can just store so much data, 3TB in a single 3.5" drive is plenty. But, we get less than 100 opportunities to access that per second (10+ms average access time).

Then we have to back it up, preferably off-site, and regularly re-read it to verify that it's good. And if the need to recover from backups arises, are you prepared for how long it takes to recover billions of files?

We're currently working with one client who wants the ability to roll back the entire system to a previous backup within an hour. However, one directory they have takes several hours just to run a "du" on...

I really wish Linux had some sort of hierarchical storage sub-system, but that just doesn't seem to be on anyone's radar. Something that could manage a pool of huge but slow hard drives, smaller but much faster hard drives, SSDs and non-volatile DRAM, automatically migrating chunks of data between the most appropriate storage technology, would be great.

Adaptec is taking a step in that direction with "MaxCache" and "Hybrid' RAID controllers, but both of these are strictly read-caching mechanisms. We also have the "flashcache" kernel driver, which can offer write-back caching to an SSD, but cannot survive a power failure or kernel crash without data corruption...

Meanwhile we just keep generating and storing more and more data.

So, yeah, data is heavy.


May 27, 2011

Paul Hummer : You Should Watch "Everything is Permitted: Extending Builtins"

While Javascript-centric, I think it applies to communities in general, and Free Software communities specifically.

I'm now thinking more about how I'm treating the shared property of the communities I participate with.



May 22, 2011

Kevin Fenzi : Fedora 15 Party!

The release of Fedora 15 is just around the corner (this tuesday, 2011-05-24)!

As always, we will be having a on-line release party over in #fedora-social on irc.freenode.net. :)

Please join us in celebrating the release…



May 20, 2011

Jeffrey Haemer : Seeing My DNA

There's a photomicrograph of my chromosomes on my living-room wall. I made it myself in a Human Cytogenetics course. When folks ask, I say it's a self-portrait.

I've been thinking about subscribing to 23andme, which analyzes your DNA, for several years, but the price was always too high. I knew it would drop over time.

Two things kicked me over the edge. One was posts by folks like Razib Khan about recent moves by the FDA to shut down or hyperregulate 23andme. The second was a trip to the Boulder Android Meetup, where I met G. Hussain Chinoy.

Chuck Coughlin and I went over to recruit an Android developer or two for a project we're working on, and Hussain sent me email saying he was interested. He wasn't a great fit for the particular slots we were trying to fill -- it happens -- but I told him I was very interested to see that he was a 23andme customer.

A few days later, Hussain dropped me a quick note to say that 23andme was having a "free day." Normally, the base price had been $199, but for that day, it was free.

That did it.

I'm now a happy customer.

I should say more about 23andme, but this post's long enough for now. Go look for yourself.

My company's still hiring, by the way -- contract and full-time positions.


May 17, 2011

Tummy.com Blogs : Adjusting window creation location.

From: Sean Reifschneider

On my desktop, where I have plenty of screen real-estate, whenever I start writing an e-mail, the window comes up all the way on the right side of my right display. Which is not at all where I want it, that ends up being at like my "two o'clock" position. This is not an issue on my laptop, because of the small screen.

Continue reading for more information on how I solved this. (read more)