Sunday, September 25, 2011

Falling from the cloud

So, for a few reasons, I've decided to try to take more of my identity back inhouse.  I'd outsourced some of my world to Blogger, Github, Facebook and domains hosted by GoDaddy, but, I figured I'd try to pull everything back home.

First up, I need to host my never-updated page back on my own server.  The most logical thing would be to run the Apache that have been integrated into Fedora 15, but, I want to run serveez, which is a GNU webserver that I've worked on a bit.

My network is very simple.  It looks like this:

I didn't have to do anything special to get the DSL Modem to allow traffic to my webserver.

The Router was more complicated.  I want anything trying to connect on port 80 to be forwarded on to the server.  So I used a browser to log into the control panel of the Linksys router.  Under a tab called "applications and gaming" and a section called "single port forwarding" I set the HTTP port 80 to be sent to the internal IP 192.168.1.99.

So why that IP xxx.xxx.xxx.99?  Well that router has its own DHCP server that the laptop and my server have been using when they connect to the router.  And that DHCP starts assigning numbers beginning with 192.168.1.100.  So usually my various computers are assigned IPs between 100 and 103 depending on which one is booted first.  But I need the HTTP traffic to be always forwarded to the server, so I'm going to have to give the server a static IP.

The server is running Fedora 15, so everything is hidden from the user and it is impossible to change anything without intensive google-fu.  But to change the network, run the command nm-connection-editor.  There I edited my wired IPv4 connection to "manual" mode instead of DHCP mode, entered the static IP, netmask, etc.  I found the address for the nameserver from the router's control panel.

Then, I had to figure out how to disable the firewall on port 80.  The magic command there was system-config-firewall-tui.  That brought up a firewall wizard.  Under the 'customize' section, I was allowed to disable the firewall for www port 80.

I used dyn.com's free service to make a temporary domain for my server.  Basically, you just create an account, choose a temporary hostname (something like blahblahblah.dyndns-home.com), have dyn's website tell you what your public IP is, and then connect that IP to your temporary hostname.

Then I kicked off the webserver, and was able to see my hello world web page.  Sweet.

But we're still not done.  Two more things have to happen.  The webserver needs to come up automatically when the computer boots, and a script needs to be in place to poll your public IP and inform Dyn whenever it changes.  When you have a DSL connection, you public IP probably changes every day as well as each time you reboot.

To get the webserver to boot on startup, you need to add it to the startup scripts.  Unfortunately Fedora has moved to the overly complicated and opaque systemd.  So to do that, I'd first have to get systemd to kick off serveez.

I created a file named serveez.service and saved it into /usr/local/share/systemd/system

[Unit]
Description=Serveez HTTP Daemon

[Service]
Type=forking
ExecStart=/usr/local/bin/serveez --daemon --cfg-file=/usr/local/etc/serveez-mg/serveez.cfg
PIDFile=/usr/local/var/serveez-mg/serveez.pid

[Install]
WantedBy=multi-user.target
From here, I ran the commands


systemctl enable serveez.service
systemctl start serveez.service

That should be enough to get it kicked off.  I verified that it was working using systemctl status serveez.service


The next chore was to get ddclient to run.  ddclient is a program that checks the IP address of the computer, and if it has changed, it notifies dyn.com, the provider of my dynamic IP hostname.  It wasn't included by default in my distro, so I installed it with yum.  The installed package included a script that gets put into /etc/rc.d, but, it didn't work for me.

I made a simple configuration file and put in into /etc/ddclient.conf


syslog=yes
mail=root
cache=/tmp/ddclient.cache
pid=/var/run/ddclient.pid
use=web, web=checkip.dyndns.com/, web-skip='IP Address'
protocol=dyndns2
login=XXXXXXX
password=XXXXXXX
XXXXXX.dyndns-home.com

Obviously your DynDNS login, password, and the hostname at the bottom line would change for your setup.

And to have this kick off automatically, I had to make yet another systemd service file: ddclient.service

[Unit]
Description=ddclient dyndns.com dynamic ip updater

[Service]
Type=forking
ExecStart=/usr/sbin/ddclient -daemon 900
PIDFile=/usr/local/var/ddclient.pid

[Install]
WantedBy=multi-user.target

Pfft. And that basically got Serveez up and running on my box. But, enough stupidity for one Sunday.

Wednesday, May 25, 2011

Fedora 15 and Gnome 3

For the past few months, I've given up any real hacking.  I've weaned myself off of the antidepressants I was taking, and then I found that to retain my sanity I really needed to up the amount of exercise, sunshine, and fresh air I was getting to keep my emotions up.  So I've become quite the exercise fanatic of late: not because I like it, but, because it is necessary.

So, I have not touched any of my software projects for a couple of months.

But, after having read all of the horrible things said about Gnome 3, I wanted to experience the horror myself.  So I wiped the Dell PowerEdge T100 server and put Fedora 15 on it.

Installation was painless, but, it let me know that I didn't have the graphics power to run Gnome 3 in regular mode, so it runs in 'fallback' mode.  Fallback mode is quite nice, but, there are many oddities.

The default wallpaper is some blue stripes, which I did not find very soothing.  Right-clicking on the desktop does nothing, so, to change the wallpaper in fallback mode, you have to select Applications > System Tools > System Setting, select "Background" from the "Personal" section of the dialog, and then choose something else.

My workflow has always been based on leaving my currently active files and folders on the desktop.  My habit is to have my current projects on the desktop and inactive projects are stored in Documents.  Gnome 3's fallback mode does not allow files on the desktop, but, you can enable that feature.  Install and run the gnome-tweak-tool.  In its 'File Manager' section, set "Have file manager handle the desktop" to "On".  I found that trick here.

The next aggravation I found was that if you select a file in a File Manager window and then press the key, nothing happens.  You can right-click and select "Move to Trash".  But, I'd prefer that the key delete a file.  I eventually came across Gnome bug 647048 that says that this was intentional, and that now Ctrl+ is used to move a file to the trash.  I find changes like this to be the most worrisome, because I bounce between multiple operating systems as part of my job.  Certain actions are so fundamental as to be muscle memory and are uniform across my platforms.

I pulled a USB drive without unmounting.  That didn't go well.

Anyway, I don't really use Gnome for anything other than as a window and file manager, so I probably am not really get too deeply into this.

Friday, April 15, 2011

On Desktop Linux

I've used various versions of open source and free operating systems for most of my adult life; but, most of my life is spent looking at a desktop PC running Windows 7.  At home, I have two functioning PCs: (1) a laptop running Windows 7 with an instance of Fedora 14 running in VirtualBox, and (2) a desktop running Fedora 14.

I've seen the future: Fedora 15 with Gnome 3.0.  I haven't even tried Gnome 3.0, but, just by looking at the ridiculous screen shots, I'm filled with seething hatred.  The round corners, the huge title bars that only contain a close button, and the blue stripes are all vile. This is certainly is an irrational, unscientific response.  I will give it a try when 15 is final in a couple of months, though.

I guess I'm just saddened that, yet again, some bit of the software ecosystem that I liked has been turned upside down.  I'm still filled with a seething hatred for the gizmo-laden toolbar of Microsoft Windows and Power Point.  After a year with them, I am still much less productive than I was before. I can understand their thinking, I guess.  They see that the future is moving to iPhone-style interactions, and they want a Desktop that can be iPhone-ized or something.

I also feel somewhat sad about the odd bloatware that Guile has become.  I liked Guile 1.8 a lot, but, 2.0 isn't really very fun for me.  It's the debugging that kills me.  There is never any good way to extract the information I need.  The stack and backtrace is always so devoid of useful information.  You can't really single-step in any meaningful way.  It has the same feel as trying to debug C compiled with -O3.

But, I *am* an old man now.  Get off my lawn.  Do I even need to move on to Gnome 3.0?

The truth is that despite using Fedora 14 with Gnome 2.x for almost all of my Linux devel, I don't think I use much Gnome functionality.  There are tons of Gnome programs, but, I don't use any of them.  The whole list of Gnome functionality I use is
  • Network manager
  • File manager
  • Terminal
  • System monitor
  • PDF viewer
  • Image viewer
The non-Gnome functionality I use is
  • Emacs
  • The development stack: gcc, guile, autotools, etc.
  • Fedora / Adobe Flash
And that's kind of it.  If I'm being honest with myself, I don't use Fedora or Linux for anything of value.  I just play with it.  It has become my golf.  I use Linux to play at development, and I develop out of habit for no useful purpose.

The software work that pays me money involves me using
  • C#.NET for Windows 7
  • MS Office: Word, PowerPoint, Outlook
  • VxWorks
And none of this really can be done on Linux.  (Yeah yeah, Mono, Open Office.  They just don't work well enough.)

My social life is all
  • Yahoo Mail
  • Facebook
I don't use any non-web app for my social computing.  I don't use Pidgin or whatever.

Tuesday, January 25, 2011

Guile web challenge: a mysql/php blog on sizzweb -- take 1

Today's internet challenge will be to set up a mysql/php blog on sizzweb, a webserver written entirely in Guile scheme.

Like yesterday, the blog software for today will be b2evolution version 4.0.3.

The webserver for today will be sizzweb version 1.12.

Again, why would I even want to do such a thing?  Because I find it fun.  I don't make fun of you for going golfing, and that's an even bigger waste of time.

sizzweb depends on the guile-www package.  I downloaded and installed guile-www-2.29.

A small bug in latest rev of guile-www-2.29 kept it from building on my machine guile-www bug #32244.

Part 1: getting sizzweb to run


Last time I tried to install this, it was a bit of a failure (not that I tried very hard, or at all).  The problem is that sizzweb is part of a larger package called ttn-do, and ttn-do historically has been targeted on a fork of Guile that had a more powerful set of install and configure tools that the official Guile.

I downloaded ttn-do-379.tar.gz and did ./configure and make, and the build failed with an error in a call to guile-toolsguile-tools is distributed with guile and is sort of a meta tool that calls on of a dozen other scripts that work with scheme sources. ttn-do was looking for the c2x script which is not a script in the mainline guile distribution. This is the sort of thing I thought would happen. This means I won't be able to build the modules in the ttn-do/zz directory because they rely on c2x.

Also guile-tools does not give a nice warning if it can't find a script. Guile bug #32243

So, instead I directly copied the scheme files in ttn-do and ttn-to/zzz into my my guile site directory manually.  Then, to get it to work I
  • ttn-do/zzz/filesystem.scm: changed all calls to make-shared-substring to substring
  • ttn-do/zzz/publishing.scm: use (ice-9 optargs) instead of (ice-9 optargs-kw) 
I also added my own version of the module (ttn-do zz sys linux-gnu) to replace the one function that sizzweb uses from it.

 (define-module (ttn-do zz sys linux-gnu)
  #:use-module (system foreign)
  #:use-module (rnrs bytevectors)
  #:export (sendfile/never-fewer))

;;(define libc (dynamic-link "/usr/lib64/libc.so"))
(define libc (dynamic-link))

(define sendfile
  (pointer->procedure
   long    ; really ssize_t, but, (system
           ; foreign) doesn't have a
           ; ssize_t.
   (dynamic-func "sendfile" libc)
   (list
    int
    int
    unsigned-long   ; Really this is a pointer to
                    ; an off_t, but, we always
                    ; pass it a null pointer
    size_t)))

(define errno (dynamic-pointer "errno" libc))

(define (errno-val)
  (let ((bv (pointer->bytevector errno int)))
    ;; assuming errno is a 4-byte int
    (bytevector-s32-native-ref bv 0))) 

(define (sendfile/never-fewer outfd infd unused count)
  (let loop ((count count))
    (let ((bytes-written (sendfile outfd infd 0 count)))
      (cond
       ((< bytes-written 0)
        (scm-error 'system-error
                   "sendfile/never-fewer"
                   (strerror (errno-val))
                   '()
                   (list (errno-val))))
       ((and (>= bytes-written count))
        *unspecified*)
       ((and (> bytes-written 0) (> count bytes-written))
        (loop (- count bytes-written)))))))
And with all that, I've got the webserver up and running.

Part 2: getting PHP to run

sizzweb has no native php support, but it does have a plug-in architecture called `servlets'.  Basically you create a file named servlets.scm and then write a custom responder that gets used when the input path matches a given regular expression.


The way the servlets system works is that if it matches the regex it gets passed to the handler whether or not there is actually a document at that location.  There would actually be a fair bit of work involved to get it to run PHP.  Subtasks would include
  • Adding index.php to the list of default files
  • Checking to see if the php file is actually there, is not a symlink, and is readable
  • Parsing the GET variables out of the URI
  • And calling php-cgi
But that is enough hacking fun for one day.  Tomorrow, we shall see what the future holds.

Monday, January 24, 2011

Guile web madness: a mysql/php blog on serveez-mg -- take 1

Today's internet madness will be to set up a PHP/MySQL-based weblog on top of one of the Guile webservers.

The blog software for today will be b2evolution version 4.0.3.

The webserver for today will be serveez-mg version 0.2.  serveez-mg isn't really a Guile webserver, but, it is a software that I hacked on that has some Guile features, so I'm starting with what I know.

I'm starting off on my Fedora 14 box on x86_64.  I installed the mysql and phpMyAdmin packages.

So, b2evolution first says that you should use phpMyAdmin to make a database.  I could do this using the mysql command line tool, but, I'll need to get PHP working eventually.  May as well start now.


serveez-mg lacks an SAPI to use PHP directly, so I'm going to have to use it in cgi mode.

OK.

Part 1: setting up serveez-mg as a cgi-enabled webserver

On a Fedora 14 box, /var/www comes set up for Apache.  I don't really want to overwrite it, so I'll set up a parallel directory structure.

$ su 
$ mkdir /var/serveez-www
$ mkdir /var/serveez-www/html
$ mkdir /var/serveez-www/cgi-bin

serveez-mg needs a configuration file: `serveez.cfg'.

;; === Load convenience file  
(use-modules (serveez-mg lib))

;; === Greet the user
(printsln " "
          "** Welcome to Serveez" serveez-version
          "using Guile" guile-version
          (if have-debug
              "(debugging enabled)"
              ""
           ))

;; === Control protocol server for remote control.
(define-port! 'control-port `(
                              (proto . tcp)
                              (port . 42420)
                              (ipaddr . "127.0.0.11")
                              ))

(define-server! 'control-server)

(bind-server! 'control-port 'control-server)

(serveez-passwd "qruo5rZkLyu22")

;; === Web Server.
(define-port! 'http-port '(
                           ("proto"  . "tcp")
                           ("port"   . 80)
                           ("ipaddr" . "*")))

(define-server! 'http-server '(
              ;; standard properties                                           
              ("admin"        . "spike@xxxxxx.dyndns.org")
              ("host"         . "xxxxxx.dyndns.org")
              ("logfile"      . "http-access.log")
              ("logformat"    . "%h %i %u [%t] \"%R\" %c %l")
              ("indexfile"    . "index.html")
              ("docs"         . "/var/serveez-www/html")
              ("userdir"      . "public_html")
              ("type-file"    . "/etc/mime.types")             
              ("default-type" . "text/plain")
              ("nslookup"     . on)
              ("ident"        . yes)

              ;; cgi interface                                                 
              ("cgi-url"         . "/cgi-bin")
              ("cgi-dir"         . "/var/serveez-www/cgi-bin")
              ("cgi-application" . (("php"  . "php-cgi")))
                                   

Note in the last line how php applications are supposed to be associated with
the php-cgi interpreter.  This will be the source of some comedy in about four paragraphs.

(Wow, the default index file in serveez-mg tries to use the image internal-gopher-menu.  That's some old mojo.)

Part 2: making phpMyAdmin work

Fedora 14 installs phpMyAdmin to work gracefully with Apache and uses Apache aliases to translate paths to where it is installed.  That is not what I need.  So, I'm going to have to install phpMyAdmin by hand into serveez-mg's tree.

So I downloaded phpMyAdmin-3.3.9, unpacked it into the directory /var/serveez-www/cgi-bin/phpMyAdmin

In phpMyAdmin's manual, it tells you to unpack it, and then navigate to the setup folder.  I dutifully point my browser to http://127.0.0.1/cgi-bin/phpMyAdmin/setup and give it a try.  No joy.  So with about 20 minutes of debugging, I learn three important facts.
  1. serveez-mg only supports one default index file, which I've currently set to index.html.  I need to add support for multiple files so that I can put index.php as an alternate index file.
  2. That cgi-application alist in the serveez.cfg -- the one that is supposed to associate php files to the php-cgi executable -- does absolutely nothing.
  3. Thus, the only thing that would work in the cgi-bin directory are executable programs and shell scripts.
And, with dinner-time fast approaching, thus ends today's lesson.