(no subject)

Apr 21, 2012 00:44

So I decided to stand up a new Zetathustra, and base him off of a terrible IRC channel's logs. Here's how I'm standing it up, based on App::Pocoirc. I'm gonna assume you speak at least basic UNIX here, and I'm gonna stop and explain why I run some of these commands; note that I'm also editing these things for brevity and content, and so if you just copy and paste these things without understanding how they work, then come and ask me for help, I will know. Don't do that.
pi@effigy:~ 2017 π mkdir zetathustra-prime
pi@effigy:~ 2018 π cd zetathustra-prime
pi@effigy:~/zetathustra-prime 2019 π install -m755 /dev/stdin run <<'EOM'
heredoc> #!/bin/sh
heredoc> exec chpst -e env \
heredoc> pocoirc conf.yml
heredoc> EOM
pi@effigy:~/zetathustra-prime 2020 π mkdir env
pi@effigy:~/zetathustra-prime 2021 π perl -Mlocal::lib
(output elided)This is to figure out what environment variables the Perl interpreter is gonna need. I use local::lib to keep things sorta segregated, and it spits out the things it wants set.
pi@effigy:~/zetathustra-prime 2022 π for i in MODULEBUILDRC PERL_MM_OPT PERL5LIB PATH ; do
for> echo ${$i?wat} ; done
zsh: bad substitution
pi@effigy:~/zetathustra-prime 2023 π for i in MODULEBUILDRC PERL_MM_OPT PERL5LIB PATH ; do
for> eval "echo \${$i:?}" ; done
(output elided)
pi@effigy:~/zetathustra-prime 2024 π for i in MODULEBUILDRC PERL_MM_OPT PERL5LIB PATH ; do
for> eval "echo \${$i:?}" > env/$i ; doneSteal all of those variables from the current environment. This uses a bit of weird shell trickery, and my first renditions didn't even work. Don't try this at home, kids.
pi@effigy:~/zetathustra-prime 2025 π cat env/MODULEBUILDRC
/home/pi/perl5/.modulebuildrc
Sanity check. Now I realized that my runscript kinda sucked and wasn't even right, so I arrow up through my history and fix it:

pi@effigy:~/zetathustra-prime 2026 π install -m755 /dev/stdin run <<'EOM'
#!/bin/sh
exec chpst -u pi:pi -e env \
sh -c "pocoirc -cf conf.yml || exec perl -e sleep; exec pocoirc -f conf.yml"
EOMThere's a bit of subtlety here; if the config file doesn't syntax-check, perl is used to make the runscript fall into an infinite sleep. Note how both things are being exec'd here, too. If you don't exec the final program, all of the sv stuff fails to work right because it controls the shell. Also, if your thing daemonizes, it won't work right either. Think about why for a second. (runsv cannot tell 'the thing daemonized' apart from 'the thing launched and immediately caught fire').

Anyway, it's time to create a config file:
pi@effigy:~/zetathustra-prime 2027 π cat > conf.yml << 'EOM'
heredoc> nick: zetathustra
heredoc> username: zetathustra
heredoc>
heredoc> global_plugins:
heredoc> - [CTCP]
heredoc> - [Hailo, { Hailo_args: {brain_resource: "brain.sqlite"} } ]
heredoc>
heredoc> networks:
heredoc> anthrochat:
heredoc> server: irc.anthrochat.net
heredoc> local_plugins:
heredoc> - [AutoJoin, { Channels: ['#hackerfurs', '#saladtongs'] } ]
heredoc> - [BotTraffic]
heredoc> EOM
pi@effigy:~/zetathustra-prime 2028 π ./run
Server for network 'default' not specified
^C
pi@effigy:~/zetathustra-prime 2029 π sed -i~ conf.yml -e s,anthrochat,default,
Meanwhile in another window I trained the thing with this:
tar Oxvzf Downloads/furcast.tar.bz2 | ssh effigy \
'irchailo-seed -f irssi | hailo --brain brain.sqlite -t -'I'd like to say I got this to run right the first time (after chucking it into /service/zetathustra and waiting for runsvdir to pick it up), but there were a few other things I hadn't considered:
  • Hailo didn't like being run as a global plugin. Fixed that up by doing the obvious: repeating myself in each thing's local_plugins block. It also defaults to weird things like talking in notices. Solution: RTFM-and-fix.
  • There's a bunch of other modules that are really interesting. I set those up. Again, RTFM'd.
  • The weirdest thing it doesn't do is randomly reply on its own. I want to make it reply based on the channel chattiness somehow.
  • The last thing seems like it should be pretty easy to solve with judicious application of POE::Component::IRC::Plugin
Anyway, that's all yak-shaving for now. I think there's enough here that you can figure out how this might work with deploying a persistent webapp. Note that /service usually runs things as root, so you'll have to be root to call sv on things underneath there, but you can nest runsvdirs arbitrarily. On some systems I run a /service/pi-runsvdir with an appropriate runscript. Here's some other neat things:
  • when I want to restart the IRC bot: sv h /service/zetathustra
  • if i want to shut it down for a while: sv d /service/zetathustra
  • a good status report: sv s /service/*
  • since runsvdir starts at boot, this thing persists across reboots without any stinky @reboot/every-15 cronjob turds.
  • if the thing dies, runsv automatically restarts it. this is usually a good thing.
  • tail /service/zetathustra/main/current shows you the latest logs. Read the manpage for svlogd to configure how it rotates.
  • stderr output goes to the runsvdir log in the process title. Use ps auxww (most likely; other UNIXes use different arguments) to read it.

The cronjob-turd thing reminds me of that time I saw some guy write an IRC bot using PHP and sockets (groan, groan). He started the thing by opening the URL it was on (i am not shitting you). It also called whatever "timeout" function you call to delay the PHP interpreter killing your process. The guy lost control of it somehow (I think he locked himself out of the admin commands), and couldn't kill the shared apache in order to kill the bot. It was also the kind that didn't die when it was network-killed, either. Hilarity ensued.

Also, I assumed earlier that you've gotten runsvdir installed and running. If not, then fuck off.

Edit: I forgot to actually include the svlogd run script:

pi@effigy:~/zetathustra-prime 2030 π mkdir log main; install -m755 /dev/stdin log/run <<'EOM'
#!/bin/sh
# normally i'd be doing chpst -u lognull or equivalent, here, for privilege separation's sake.
exec svlogd -tt ../main
EOM

unix, irc, hacks

Previous post Next post
Up