/srv/irclogs.ubuntu.com/2012/12/11/#juju-dev.txt

davechen1yhttp://paste.ubuntu.com/1424439/00:10
davechen1y^ improvement ?00:10
davechen1yffs - tuesday is leaf blowing day in my block of units02:01
davechen1y3 fucking hours it takes the gardener02:01
davechen1ythe place is honestly not that big02:01
TheMueMorning06:25
davechen1ymorning / evening06:28
dimiternmorning :)07:40
dimiternanyone up for a review? https://codereview.appspot.com/6924043/07:41
TheMue_dimitern: Morning, will take a look after I've handled the review I've got by fwereade_07:45
dimiternTheMue_: thanks!07:47
rogpeppe1TheMue_, dimitern, davechen1y, fwereade_, mramm: morning!08:11
TheMue_rogpeppe1: Morning.08:12
dimiternrogpeppe1: morning!08:23
dimiternrogpeppe1: you too, wanna take a look? https://codereview.appspot.com/6924043/08:25
rogpeppe1dimitern: will do08:25
dimiternrogpeppe1: thanks!08:25
fwereade_morning everyone -- dropped laura at school, busses were somewhat unhelpful08:49
dimiternfwereade_: morning08:52
fwereade_rogpeppe1, TheMue_, I would appreciate comments on https://codereview.appspot.com/6906046/ which has been out for a few days09:00
fwereade_dimitern, (heyhey)09:00
TheMue_fwereade_: Hey, will take a look09:01
fwereade_rogpeppe1, TheMue_: "this is awful, there's no way you can do that" is not an unreasonable response, but if you feel that way I would appreciate advice re better approaches to the change09:01
rogpeppe1fwereade_: sorry, i must have missed it, will take a look after i've finished on dimitern's review09:01
fwereade_TheMue_, btw, nice work on the firewaller, I'm much more comfortable with it now, I think the unit port initialization is the only major thing I have quibbles about09:01
fwereade_rogpeppe1, most of those days have been weekends tbh :)09:02
TheMue_fwereade_: Hehe, thx, changed it and now the test breaks. Have to look what I've missed.09:02
fwereade_TheMue_, heh, it may be something I've missed09:02
TheMue_fwereade_: I'll see, but indeed, thx to your critical review it looks by far better now.09:03
fwereade_morning Aram09:09
Aramhi.09:09
dimiternAram: morning09:09
TheMue_fwereade_: Removing the changes of initializing the unitData.ports and the ports in its watchLoop() with OpenedPorts() lets everything work again.09:09
TheMue_Aram: Hiya.09:09
fwereade_TheMue_, sorry, missed that message09:31
fwereade_TheMue_, would you expand? you're saying the suggestion breaks everything, right?09:32
TheMue_fwereade_: NP, just looking for another one so I'll come back to you later.09:32
fwereade_TheMue_, I'd like to figure out why if possible :)09:32
fwereade_TheMue_, but whenever works for you is fine by me09:32
TheMue_fwereade_: Two global tests are breaking when initializing the unitData and its watchLoop ports with unit.OpenedPorts()09:33
TheMue_fwereade_: But now I've changed it back and possibly I missed something because a test hangs. So let me figure that out and we can talk about the unit port init again.09:34
fwereade_TheMue_, great, just grab me when you feel like it :)09:38
TheMue_fwereade_: Yep, will do so.09:39
dimiternrogpeppe1: how is it?10:26
dimiternrogpeppe1: i hope not too bad for a second phase of the http implementation :)10:26
rogpeppe1dimitern: generally good. i'm just finishing writing up a few ideas for how it might be simplified10:26
dimiternrogpeppe1: great!10:26
rogpeppe1dimitern: you've got some comments10:31
dimiternrogpeppe1: thanks10:34
rogpeppe1dimitern: BTW, i forgot to mention, i think your current handler will panic if you give it the url "/v2"10:34
dimiternrogpeppe1: hmm, I left the panic temporarily there for the time being, I'll fix that10:36
rogpeppe1dimitern: no, it'll panic with an out-of-range-index error10:36
dimiternrogpeppe1: I see, ok, I missed that then10:36
rogpeppe1dimitern: but rather than fix it, i suggest using http.ServeMux instead, if you think it's feasible10:37
dimiternrogpeppe1: ok10:38
dimiternrogpeppe1: and about the templating - wouldn't it be confused by the { } in the JSON? That's why I didn't use it - was not sure it'll work10:38
rogpeppe1dimitern: no - it requires {{ }} not { }10:39
rogpeppe1dimitern: hmm, except10:39
rogpeppe1dimitern: well, it might be ok as it is. but you can change the delimiters too10:40
dimiternrogpeppe1: ok, I'll give it a go10:40
rogpeppe1dimitern: see http://golang.org/pkg/text/template/#Template.Delims10:41
dimiternrogpeppe1: 10x, looks promising10:42
rogpeppe1dimitern: ${ }$ maybe?10:42
dimiternrogpeppe1: yeah10:43
dimiternrogpeppe1: could you explain more about what table-based approach you'd use instead of the nested switch statements in handleFlavors?\10:43
rogpeppe1dimitern: well, i think ServeMux gives you a lot of what you need10:44
rogpeppe1dimitern: that gets rid of one level of the switch10:44
dimiternrogpeppe1: so handleFlavors and handleFlavorsDetail as separate things?10:44
rogpeppe1dimitern: but i don't know if it's appropriate for all the requests you need to handle10:44
rogpeppe1dimitern: yes10:44
rogpeppe1dimitern: but...10:44
rogpeppe1dimitern: not necessarily10:45
rogpeppe1dimitern: only if you think it works out well10:45
dimiternrogpeppe1: ok, I'll try a few solutions to see which one looks best10:45
niemeyerMorning all!11:18
dimiternniemeyer: morning!11:19
rogpeppe1fwereade_: you've got a review11:22
rogpeppe1niemeyer: yo!11:22
fwereade_rogpeppe1, cheers11:22
fwereade_niemeyer, heyhey11:22
niemeyerBtw, right now I'm fully on battery + 3G11:23
niemeyerI should have a few hours still.. hopefully it'll come back before then11:24
niemeyerHuge storm last night11:24
TheMue_niemeyer: Hiya, hope no damage at your home.11:35
niemeyerTheMue_: Heya! All good here luckily..11:36
niemeyerOnly a ton of wind and noise11:36
fwereade_incidentally, if anyone feels life a spot of light reading, I'd appreciate a sanity check on the lifecycle stuff I wrote last night11:36
TheMue_niemeyer: Phew, I always have much respect for those natural powers.11:36
fwereade_and perhaps a discussion on where I should be putting such things long-term11:36
fwereade_maybe we do want a doc/ dir?11:37
TheMue_fwereade_: I would prefer a google doc.11:37
=== TheMue_ is now known as TheMue
niemeyerfwereade_: Where's that?11:38
niemeyermramm: Has the meeting time shifted again?11:39
fwereade_niemeyer, sorry, lp:~fwereade/+junk/juju-braindump11:39
niemeyerfwereade_: np, cheers11:39
mrammniemeyer: I think the tuesday version of the meeting just never got shifted11:39
mrammperhaps I'm wrong though, it is too early and I have not had my coffee yet this morning11:40
fwereade_niemeyer, it has a few bits and pieces I also wrote for evilnick a while back as, er, kinda proto-documentation11:40
niemeyermramm: I thougth we had agreed to 13UTC and 22UTC for the time beeing11:40
niemeyerbeing11:40
mgzfwereade_: ah, have you updated that? I read through when you first posted it and found it really useful11:40
fwereade_mgz, cool :D11:41
fwereade_mgz, there's one new document describing lifecycles11:41
mrammright, and I just shifted it from 12:00 utc to 13:0011:41
fwereade_mgz, it's more a statement of intent than a description of current state, though11:41
mrammat least that's what I thought I did ... looking again11:41
niemeyerfwereade_: I think the way to put that kind of discussion is indeed in a branch, preferably up for review11:42
dimiternmramm: so it's going to be in a bit more than an hour from now, not in 20m?11:42
mrammyea11:42
niemeyermramm: It's at 12UTC right now11:42
niemeyermramm: in 20 minutes11:43
fwereade_niemeyer, fair enough -- I'm just not quite sure where I should be targeting11:43
mrammI just updated it to be 1 hour from now11:43
niemeyerfwereade_: Hmm.. where you should be targeting?11:43
mrammabout 10 minutes ago11:43
fwereade_niemeyer, do we want a doc/ directory in juju?11:43
niemeyermramm: Ah, thanks11:43
mrammI thought your message was in response to that update e-mail11:44
mrammbecause it came *right* after I did the update11:44
mrammvery confusing ;)11:44
mrammcorrelation does not imply causation11:44
niemeyerfwereade_: We already have the sphinx docs somewhere.. we could integrate there, but that seems less important than just being able to discuss the proposal in the first place11:44
fwereade_niemeyer, (the other issue is that that branch is definitely not polished and not really quite right for actual documentation -- it's useful, I hope, but not quite something we want to call "official")11:45
fwereade_niemeyer, the main point is to capture the stuff that's in my head and maybe not anywhere else11:45
mgzthat kind of doc is still far better than not having any11:45
fwereade_niemeyer, still, codereview is indeed a good discussion vector11:46
niemeyerfwereade_: That's what we used to call a draft in the old system11:47
niemeyerfwereade_: There's no cut-off for drafts11:47
fwereade_niemeyer, ok, a proposal for juju-core/doc/draft then?11:48
niemeyerfwereade_: Sounds good.. at least that'll give us the ability to comment/respond comfortably11:49
niemeyerfwereade_: Even if we later disagree on the end location11:49
fwereade_niemeyer, ok, great11:49
rogpeppe1fwereade_: in your comment here (https://codereview.appspot.com/6902070/diff/2001/state/api/serve.go#newcode65), what's your reason for asking for a defer? a simple statement seems fine for that straightforward logic to me.11:55
rogpeppe1fwereade_: (i think that dfc's remark is a red herring - lis.Close can't panic, 'cos we've checked the listener's ok elsewhere, and even if it does, the panic takes out the whole system, so the defer doesn't help at all11:57
rogpeppe1)11:57
fwereade_rogpeppe1, it just feels that little bit more "correct" -- you never know when some tricky sod will recover() :)11:58
fwereade_rogpeppe1, I'm easy on that one though11:58
rogpeppe1fwereade_: you do here - it's in a go func() { } !11:58
fwereade_rogpeppe1, ha! good point :)11:58
fwereade_rogpeppe1, consider my +1 decremented then :)11:59
niemeyer:)11:59
* niemeyer switches to fast network connection again12:02
=== niemeyer_ is now known as niemeyer
davecheneyheh hey12:08
davecheneycan someone send me the hangout code12:08
AramI believe it's in one hour.12:09
davecheneythe meeting time was for 11pm aud12:09
Aramperhaps I am mistaken with these things, as I usually am, but <mramm> right, and I just shifted it from 12:00 utc to 13:0012:11
dimiterndavecheney: it was changed from 12 UTC to 13 UTC just 20m ago12:11
davecheneyjesus fuck people, this is importnat12:12
niemeyerdavecheney: Heya! The meeting was mischeduled 1h too early.. the first one is still at 13UTC as last week12:12
niemeyerdavecheney: The mistake was in Google Calendar.. it hadn't been fixed since we agreed on the timings last week12:13
AramI remember something about a calendar where we put or holidays.12:14
Aramdoes anyone else remember that?12:14
Arams/or/our/12:14
niemeyerAram: mramm will know12:14
davecheneyAram: try this http://www.google.com/calendar/embed?src=canonical.com_ia67e1a7hjm1e6s3r2lid9nhs4%40group.calendar.google.com&ctz=Australia/Sydney12:17
davecheneyor in canonical google apps, add "Juju Team Calendar"12:17
Aramthank you sir.12:17
mrammsorry, I'm in a meeting now12:18
mrammI'm very sorry that I didn't get the meeting invite updated12:20
davecheneymramm: shit man, i was at a place with an open bar tab12:22
davecheneymramm: s'ok, timezones are hard, no real harm done12:22
mrammdavecheney: I'll buy you something nice, sorry12:22
mramm;)12:22
TheMuefwereade_: Your firewaller review is commented, the next propose is in.12:26
fwereade_TheMue, cool, I'll take a look12:27
davecheneyTheMue: did you see the data race that the race detector found ?12:27
TheMuefwereade_: Cheers.12:27
TheMuedavecheney: Yes, and I think it's covered now. The unit watcher loop is started after the service access now.12:28
davecheneyTheMue: superb12:28
TheMuedavecheney: But I still have to learn how to read the race analysis output. ;)12:28
davecheneyTheMue: >> the manual >> http://code.google.com/p/go-wiki/wiki/RaceDetector12:29
TheMueSo, quick lunchtime before we'll meet. BIAB.12:29
Arammramm: please add me to the hangout, when you make it.12:57
mrammAram: I added the hangout link to the meeting invite12:58
mrammI think I also got everybody added to the invite list13:01
mrammbut if you aren't on the list, the link is in the invite13:01
rogpeppe1Aram: you lose, i'm afraid13:02
mrammwell, meeting is now full13:02
davecheneybzzt13:02
davecheneyAram: don't worry, someone will drop off in a few minutes13:02
davecheneyif previous experiences are any guide13:02
Aramwhat's the point of two meeting if everyone wants to be in the first one?13:05
mrammyea13:06
mrammthat's a problem13:06
mrammbut I don't think this will happen regularly13:06
mrammunless the AU guys are always up at midnight13:06
mrammdidn't happen last week...13:06
davecheneymramm: it won't happen again13:06
davecheneyonce you fix the meeting invite13:06
davecheney*subtle hint*13:06
mrammI will also try to dig into the meeting invite thing13:06
mrammdavecheney: is it still wrong?   I thought I got it fixed this morning.13:07
davecheneymramm: i can confirm it said 23:00 hours as of 22:00 hours tonight13:08
Aramwell, even if we manage to balance the meetings, I still don't understand the point. I thought we had this meeting so that everyone gets familiar with other team member's work. what's the value in becoming familiar with only half the work from people changing each week?13:09
Aramor does this meeting have any other purpose?13:09
mrammdavecheney: yea, that was my fault, I thought I updated the meeting in perpetuity, but only ended up updating the one on thursday last week13:09
mrammthen when I checked this morning it was already just after 23:00 :(13:10
davecheneymramm: you have now sent a meeting invite for an hour earlier than the time that it wasn't already13:15
davecheneyJuju Team Meeting13:15
davecheneyWhen13:15
davecheneyWeekly from 22:00 to 22:25 on Tuesday Eastern Time - Melbourne, Sydney13:15
mrammhmm.  Something strange going on, I will dig in after the meeting.13:15
rogpeppe1Aram: you can join now if you like13:24
rogpeppe1Aram: one free slot :-)13:24
davecheneymramm: sorry, i had to leave13:25
davecheneyi was given an unequivical command13:25
mrammdavecheney: no problem13:25
mrammdavecheney: you have to take care of your self, and your relationships -- far more important than this meeting13:26
Arammgz: jam: Launchpad bug 106957013:26
jambug #106957013:26
dimiternno bug bot here it seems13:27
Aramhttps://launchpad.net/bugs/106957013:27
jamAram: if you are able to reproduce it, I think maas would love to get the feedback on the bug. Essentially Julian/Diogo/Raphael can't reproduce it on their hardware, so need more details.13:28
AramI can reproduce it 100% of the time, nothing works because of it.13:29
AramI can reproduce it in different deployments.13:29
Aramvirtual and physical.13:29
jamAram: just to check, what version of Ubuntu and Maas are you using?13:29
niemeyerjam, dimitern: Now we do13:30
Aram12.10, packaged maas.13:30
dimiternniemeyer: good, let's try that: bug 106957013:30
jamAram: you may want to try: https://launchpad.net/~maas-maintainers/+archive/daily-qa-ok as they've put forth effort of a bunch of fixes that are planned to be SRU'd to 12.1013:31
_mup_Bug #1069570: 1 MAC Address, two IPs - DNS is "out of sync" with DHCP leases databases, I think... <MAAS:Incomplete> <maas (Ubuntu):Incomplete> < https://launchpad.net/bugs/1069570 >13:31
dimiterncool :)13:31
AramI will try that version.13:31
jam(I'm guessing it may not fix the immediate issue, but it is likely it may fix other bugs that you might run into.)13:32
jamSarah Bartlett <sarah.bartlett@canonical.com>13:33
niemeyer_jam: Let's try to get "juju submit -tarmaq" working somehow13:48
niemeyer_(or whatever, really)13:48
jamniemeyer_: you mean 'lbox submit -tarmac' right?13:53
niemeyer_jam: Duh, sorry, yes13:54
=== niemeyer_ is now known as niemeyer
niemeyerLunch time here too14:15
niemeyerbiab14:15
fwereade_TheMue, btw, the big question I meant to ask was about the unitData ports-setting only when the service is exposed14:36
fwereade_TheMue, because ISTM that that is just papering over a bug in reconcileGlobal (which doesn't take account of service exposure) and is not in fact correct14:37
fwereade_TheMue, because otherwise we have no way to figure out what ports should be opened on a machine whose units have previously opened ports but whose services have just become exposed14:38
fwereade_TheMue, sensible?14:39
TheMuefwereade_: Sounds to me as two ways to approach the same situation.14:40
fwereade_TheMue, let's go through how it works14:41
TheMuefwereade_: The unitData's ports shall represent which ports the unit wants to have.14:41
fwereade_TheMue, machine m has a unit u of service s14:41
fwereade_TheMue, u has opened port 8014:41
fwereade_TheMue, s is not exposed14:41
fwereade_TheMue, when you collect this data and run initGlobal, u's ud has no ports14:42
fwereade_TheMue, u does not change again14:42
fwereade_TheMue, but s becomes exposed14:42
TheMuefwereade_: Yes. So when ud is started it doesn't add port 80, but when s is exposed it will get notified.14:42
fwereade_TheMue, how do we know to open port 80?14:42
fwereade_TheMue, explain the mechanism14:42
fwereade_TheMue, it *will* happen, by accident, if you're lucky enough to get an intervening change to u14:42
TheMuefwereade_: Will do, one moment.14:43
TheMuefwereade_: No14:43
TheMuefwereade_: The services exposed flag is watched.14:44
fwereade_TheMue, indeed so14:44
TheMuefwereade_: And this change will be sent to the FW loop.14:44
fwereade_TheMue, when we get a service change, do we rescan all the units?14:44
TheMuefwereade_: And it retrieves the services units and flushes them ( fw.flushUnits() ).14:44
fwereade_TheMue, agreed14:44
fwereade_TheMue, how does the unit know what ports are open?14:45
fwereade_TheMue, AIUI, the unit should know what ports are open because they're set on the unitData14:48
fwereade_TheMue, but actually they're not, because you trashed them ;p14:48
TheMuefwereade_: One moment, have to follow the logic again.14:48
TheMuefwereade_: Where?14:49
fwereade_TheMue, lines 165-16914:49
fwereade_TheMue, ok, technically you didn't trash them, you just never got them14:49
fwereade_TheMue, the impact is the same :)14:49
TheMuefwereade_: Maybe you should rephrase it.14:50
fwereade_TheMue, do you agree that you only set ports on the ud when the service is exposed?14:51
TheMuefwereade_: At start time when it's exposed. And it's meant to react later on the exposed events. I've got to compare it to the old code to see what has got lost.14:53
fwereade_TheMue, we can figure it out right here I think14:54
rogpeppe1wouldn't it be nice if the canonical "My Leave" page could at least show leave ordered by date?14:54
TheMuefwereade_: Please give me some moments, I have to see code in parallel.14:54
fwereade_TheMue, I honestly think it will be simpler to consider just the code that exists14:57
TheMuefwereade_: Port changes effect the unitData in line 101.14:57
fwereade_TheMue, what makes you think you're going to get a ports change before the service exposure change?14:58
TheMuefwereade_: And line 347 collects thos per machine.14:58
fwereade_TheMue, yeah, line 347 is great14:58
fwereade_TheMue, I'm asking why line 213 isn't doing the same thing14:58
fwereade_TheMue, look, it's even simpler14:59
fwereade_TheMue, ISTM that the unit ports data is *wrong* if you discard it based on lack of service exposure14:59
TheMuefwereade_: When a UD is started it represents its valad status at this time. If then ports change or its services exposed flag is changing it is reacting, regardles what is first.15:02
tasdomashi15:03
tasdomasI'm having problems setting up a juju environment15:03
tasdomaslocally, using lxc15:04
tasdomasafter setting up the environments.yaml file and running juju bootstrap, I get:15:04
tasdomaserror: environment "local" has an unknown provider type "local"15:04
fwereade_TheMue, when a UD is created for a unit that has opened port 8015:05
fwereade_TheMue, and the UD's ports field is empty15:05
fwereade_TheMue, is this correct?15:05
TheMuefwereade_: Sorry, doesn't sound logical to me.15:07
fwereade_TheMue, ok, but that's what you're doing, right?15:07
TheMuefwereade_: You mean a started UD with a U with open port 80 but S is not exposed has no ports? Then yes.15:07
fwereade_TheMue, then why does a change in the unit's actual ports update the UD's ports regardless of service exposure?15:08
fwereade_TheMue, if you believe this is a bug, you will need to explain how you;re meant to get the open ports for 100k units when the service is exposed :)15:08
TheMuefwereade_: So you think a UD should always represent all open ports and only reconcileXyz or the processing of the servicesses exposed event have to take care?15:10
fwereade_TheMue, not exactly15:11
fwereade_TheMue, I think that service exposure tracking and unit port tracking are orthogonal15:13
fwereade_TheMue, and that the only connections between the two are (1) that service watches are started and stopped based on the existence of at least one unit of that service15:13
TheMuefwereade_: That's what I IMHO said.15:13
fwereade_TheMue, and (2) that a units ports only contribute to its machine/environment when the relevant service is exposed15:13
fwereade_TheMue, I'm not sure whether I've managed to communicate the problem15:15
fwereade_TheMue, is it your position that UDs' ports fields should only contain ports when the service is exposed?15:15
TheMuefwereade_: Sounds like several places in the code you want to be changed again, especially lots of the old logic we began with.15:16
fwereade_TheMue, nope, it's all new logic that I'm complaining about15:16
fwereade_TheMue, that doesn't fit with the old logic15:16
TheMuefwereade_: OK, then I did get those (1) and (2) wrong, because in the statement before it has been more clear to me.15:17
fwereade_TheMue, ok, will you look at line 346?15:17
TheMuefwereade_: And that indeed is only in the new parts.15:17
fwereade_TheMue, and explain what it does?15:17
TheMuefwereade_: Got it15:18
fwereade_TheMue, (that's old code AFAIK and it looks to me like it's doing the right thing -- for your position to be consistent, that line must I think be redundant)15:18
fwereade_TheMue, line 346 is I think in flushMachine -- are we maybe looking at different versions or something?15:19
TheMuefwereade_: No, just said, I got your point. Will change it.15:19
fwereade_TheMue, ah sorry -- I misunderstood15:20
fwereade_TheMue, ok, I'll send my comments, there are a couple of other minors15:20
rogpeppe1niemeyer: ping16:12
niemeyerrogpeppe1: pongus16:15
rogpeppe1niemeyer: wanna chat about the API?16:15
niemeyerrogpeppe1: Yeah, G+?16:15
rogpeppe1niemeyer: sounds good, will try and regain ownership of the mac, one mo16:15
niemeyerrogpeppe1: COol :)16:15
niemeyerI'll grab some coffee meanwhile16:15
TheMueSo guys, have to step out, drive to the neighbour town for a concert (Night of the Proms). CU tomorrow.16:27
TheMuefwereade_: The changed CL is in.16:27
fwereade_TheMue, cool, looking16:29
TheMuefwereade_: Cheers.16:29
rogpeppe1niemeyer: invite out16:30
rogpeppe1http://paste.ubuntu.com/1425552/16:37
rogpeppe1it's time for me to go.18:30
rogpeppe1g'night all18:30
rogpeppe1oh yeah, i'll be in late tomorrow morning, as i've got to go into town for an errand18:34
=== carif_ is now known as carif
niemeyer_I'm stepping out as well, but will be back later for the evening meeting today19:26
niemeyer_Well, evening for me anyway :)19:26
=== niemeyer_ is now known as niemeyer
niemeyerIsn't it meeting time?22:05
niemeyerdavecheney, mramm?22:05
* davecheney waves22:07
davecheneywhere is mramm ?22:07
niemeyermramm: pingous22:11
niemeyerdavecheney: We should meet anyway22:18
niemeyerdavecheney: I'll fire the chat22:18
davecheneyok22:19
niemeyerEverybody is invited22:19
wallyworlduse the hangout url in the invite?22:20
mrammdavecheney: pong22:33
davecheneymramm: https://plus.google.com/hangouts/_/ff8fbcfc0274167525781f024d8e2131cc3b4972?authuser=1&hl=en22:40

Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!