IRC logs for #buildstream for Wednesday, 2018-04-25

*** tristan has joined #buildstream05:06
*** toscalix has joined #buildstream07:53
*** bethw has joined #buildstream07:55
gitlab-br-botbuildstream: merge request (jjardon/codequality->master: Add job to analyze project code quality with Code Climate CLI) #431 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43108:31
*** jonathanmaw has joined #buildstream08:36
skullmanjuergbi: I looked at the tar cache, but didn't have anything to start with to look at CAS. I'll do some research on CAS to see if this is going to be a problem.09:06
gitlab-br-botbuildstream: merge request (372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes->master: Resolve "Allow queues to run auxilliary jobs after an element's job finishes") #433 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43309:13
gitlab-br-botbuildstream: merge request (372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes->master: WIP: Resolve "Allow queues to run auxilliary jobs after an element's job finishes") #433 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43309:13
*** dominic has joined #buildstream09:17
gitlab-br-botbuildstream: merge request (getting-started-section->master: WIP: Getting started section) #418 changed state ("closed"): https://gitlab.com/BuildStream/buildstream/merge_requests/41809:32
*** jjardon has quit IRC09:34
*** jjardon has joined #buildstream09:34
gitlab-br-botbuildstream: merge request (372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes->master: WIP: Resolve "Allow queues to run auxilliary jobs after an element's job finishes") #433 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43309:39
gitlab-br-botbuildstream: merge request (372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes->master: WIP: Resolve "Allow queues to run auxilliary jobs after an element's job finishes") #433 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43309:53
gitlab-br-botbuildstream: merge request (jjardon/codequality->master: Add job to analyze project code quality with Code Climate CLI) #431 changed state ("merged"): https://gitlab.com/BuildStream/buildstream/merge_requests/43109:54
gitlab-br-botbuildstream: merge request (135-expire-artifacts-in-local-cache->master: WIP: Resolve "Expire artifacts in local cache") #347 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/34709:54
gitlab-br-botbuildstream: merge request (135-expire-artifacts-in-local-cache->master: WIP: Resolve "Expire artifacts in local cache") #347 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/34709:56
*** aday has joined #buildstream10:09
gitlab-br-botbuildstream: merge request (372-allow-queues-to-run-auxilliary-jobs-after-an-element-s-job-finishes->master: WIP: Resolve "Allow queues to run auxilliary jobs after an element's job finishes") #433 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43310:39
gitlab-br-botbuildstream: merge request (jennis/136-clean-remote-cache->master: WIP: jennis/136 clean remote cache) #421 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42110:55
Nexustristan & juergbi: regarding #376, what would we do in the situation where the latest tag is newer than the `ref` commit?10:59
tristanNexus, we need a checkout of the exact ref; to yield the intended `git describe` result for "that ref"11:01
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42511:01
tristanNexus, where a ref is a given commit sha11:01
tristanNexus, so in this context, what we mean is the latest tag in the history leading up to that commit sha (not the latest tag in the repository)11:02
Nexusah i see11:02
juergbiNexus: in case you're not familiar with it, you can use `git describe --tags --abbrev=0 SHA` to get that tag11:15
juergbi--tags is to also support unannotated tags. we probably need to first try without --tags and only if that yields no match, try with --tags11:16
jjardonanyone around to review https://gitlab.com/BuildStream/buildstream/merge_requests/425 ? The MR says "No changes to code quality" :)12:07
tlaterjuergbi: You mentioned that the scheduler will need reworking for CAS - as far as I can tell this is so that we can schedule changes to the pipeline after pulling.12:09
tlaterI'm in the middle of refactoring the scheduler anyway, maybe we should sync up on what you'd need to change for that?12:09
juergbitlater: I wouldn't call it reworking, just adding a feature, hopefully without a big conflict12:11
juergbitlater: What I need for CAS is just to be able to queue an Element later on if it was not in the originally queued plan12:11
juergbii.e., completely remove build-only dependencies from the initial plan and add them only when the need arises12:12
tlaterAh, ok12:13
juergbithese elements would always be added to the first non-track queue12:13
* tlater is considering adding a Scheduler.schedule_job function12:13
tlaterBecause other schedule-after-initial-pipeline jobs will need to be launched somehow12:13
juergbithere is one tricky aspect with regards to build-only dependencies that are part of the elements that are tracked12:14
juergbiideally, we remove them from the pipeline after the track queue and re-insert them into the pull/fetch queue when/if needed12:14
juergbihowever, master doesn't have this optimization right now, so it wouldn't be a regression if we postponed this for later12:15
tlaterI think that could be quite easy to implement12:15
juergbisounds good12:16
tristantlater, try to keep a clear roles and responsibilities of where things are being scheduled12:16
tristantlater, as it stands now, the queue holds the jobs, and the scheduler pops them off in sched()12:16
tristanif you add schedule_job(), then there is now two places where the jobs live12:17
juergbiYes, that's a bit of an issue for the CAS part. Not sure yet how to handle that best.12:17
juergbiRight now the Pipeline class handles initial queueing12:17
juergbiHowever, the Pipeline class is not necessarily involved in dynamic queueing12:17
tristanRight, it sets up the Queues, I want to change what's doing that but it doesnt change that the scheduler is "given queues"12:18
tlatertristan: In my mind the scheduler is given jobs, and delegates them to the correct queues12:18
tristanTo clarify, what I want is: A.) A class which is responsible for initializing/loading elements, and providing functions for creating lists from the loaded build graphs12:18
tristanThis will probably remain "Pipeline"12:18
tristanThen I want B.) A sort of main which you can give these lists to, which does the build, fetch, track, etc... and *it* takes the lists which pipeline has let you set up12:19
tristantlater, right, some cleanup is a bit needed there12:20
tristantlater, maybe, if it's unclear; the roles are currently a bit mixed... the reflection I had when last looking at the scheduler and fixing it for private data was this:12:21
tristanI asked myself: Hmmmm, Queue.active_jobs member is public, that sucks12:21
tristanThe Queues currently handle the callbacks of complete jobs, and ask the scheduler to retrigger stuff as a result12:22
tristanand the scheduler has to look deep into the Queue's private details for the purpose of suspend and terminate mostly12:22
tristantlater, however you could equally be right and I could be looking at this backwards12:22
tlaterSo, this may be crazy talk, but could we consider moving what the queues do to jobs?12:23
tristantlater, what we want to avoid, is another _pipeline.py disaster12:23
tlaterNow that the Jobs interface is abstract anyway, we can have things like TrackJob instead of a generic element job12:24
tlaterAnd have the scheduler sort out in which order jobs have to be run12:24
tristanI dont want to lose queues here12:24
tristanQueues are required, especially the moving of elements from one to another12:24
tristanHowever, abstracting the custom work in Job subclasses instead of Queue subclasses might be alright12:25
tristanI'm not sure what it buys us, but you might know what it buys us12:25
tlatertristan: My concern has been with how we know what manages jobs submitted to anything that's not a queue12:26
tristanRight12:26
tlaterBecause are growing jobs that aren't part of a specific queue12:26
tristanIt might be that queues become things which the scheduler asks to produce jobs12:27
tristanI.e. "Do you have any more jobs for me ?"12:27
tristanlet's run em'12:27
tristanInstead of letting the Queue objects manage a list of "active_jobs"12:28
tristantlater, that would significantly impact how retries are managed, note.12:28
* tlater doesn't see why here12:29
tlaterCurrently the jobs figure out how many times/how they are retried12:30
tristanI think that Queues currently retain their processing "token" until the retries are up, and relaunches jobs itself12:30
tristanDo they ?12:30
tristanAh tlater, you are right12:30
tristanslipped my mind12:30
tristanthat's convenient yes12:31
tristanI think the bigger question is how side effects are managed12:31
tlaterWell, with this approach of asking the queues what to do I think that's answered too12:32
tristanSo you have the Scheduler asking the queues for jobs... and... we know that in every circumstance where we might scheduler additional jobs, it's a result of a queue activity12:32
tlaterBecause in essence, the queues will just have to also submit a different kind of job12:32
tristantlater, good point, at face value this sounds good12:32
tristanI think that changing the Queue specifics to Job specifics is an unnecessary change12:34
tlaterPerhaps, but looking at the result of making jobs abstract, it just seems odd that queues still manage what the jobs *do*12:34
tristanIt might amount to the same thing, either way... specific Queue implementations which use ElementJob Jobs, or one Queue implementation which uses different ElementJob subclasses12:35
*** toscalix has quit IRC12:35
*** toscalix has joined #buildstream12:36
tristanHmmm12:36
tristantlater, seems like a good point12:36
tristantlater, I wonder if the Queue has more context available than a Job, but I guess not; in one sense though there is a difference12:37
tristanThe difference being that, A.) The queue has some measure of control on "what happens next"... and B.) The queue produces side effects in the main process data model12:37
tristanIf we move that to Job only, then Job might only be able to do (B), it's unclear if it needs more control in terms of (A)12:38
tristanAt least we know that Jobs always complete in the main process and produce serialized side effects (i.e. not concurrent)12:38
tlatertristan: If you consider the queue class that wraps the jobs their manager it still has control over "what happens next"12:39
tlaterI'm just unsure where to go with the multiple queues - they are still necessary at least for the frontend12:40
* tlater takes a look at this in code and will come back with questions once there's a bit more of a concrete implementation12:44
tristantlater, we might want a single "queue manager" thing which we give to the scheduler, which itself consumes the concept of job tokens and moving elements through queues12:48
tristantlater, remember also that if the scheduler asks the queues (or queue manager) for jobs, it has to also give them back when they complete12:49
tristanthe flow for the scheduler might be: A.) Wake up when a job completes... B.) Give the job back... C.) Ask for more jobs... D.) Run jobs... E.) Sleep12:51
tristanWhere it originally starts at (C) in Scheduler.run()12:52
tlatertristan: If we remove the specialization from the queues, do they essentially become lists, or am I missing something?12:52
tristanThe token consumption12:53
tristanlemme check12:53
tlaterThat is already managed by the queue manager in my implementation, I think12:53
tlaterOh, no, it's managed by the generic queue class, ah!12:53
tlaterHm, that's lists with a purpose attached12:54
* tlater thinks the manager could handle this better12:54
tristanYes12:54
tristanWell I dont know, the manager might become quite complex; it could still do with a Queue class to separate some logic12:54
tristantlater, also, they would gain the knowledge of which kind of Job to spawn12:56
* tlater doesn't like the idea of making classes purely to be an enum12:57
tristantlater, so with a shift like this, you might have a generic Queue() object with A.) The bookkeeping, including action names and failed/processed/skipped elements12:57
tristanB.) The way type of the Job to launch12:57
tristantlater, they might be simple classes... we prefer those as they are more coherently readable than dictionaries12:58
tristanI.e. it might be one simple Queue class that takes it's token type, action name and job type as a constructor12:58
tlaterHm, well, this is a detail anyway, this can be changed if it seems too simple12:59
* tlater has a look at whether he can get to this architecture in the first place12:59
tristantlater, I'm still a bit skeptical here about making that shift to be honest13:00
tristanthe more I think about it13:00
tristanQueues need to implement Queue.status()13:00
tristanwhich tells if an element should wait, be skipped, or is ready13:00
tristanwhich informs the processing loop which pulls elements through queues13:00
tristantlater, if we were to move that to specific ElementJob() subclasses, the job implementations seem to do more than just a the job13:01
tlaterHm, that's true13:01
tristanalso those properties would not be shared by non-element-processing jobs13:01
tristanI think that a queue manager would still be a good idea, the remove some of the burden from Scheduler13:04
tristanthe tokens and the loop which moves elements through queues13:04
tristanand maybe have the scheduler manage the active jobs itself13:05
tlaterI still like the idea of asking the queues for jobs13:05
tristanjust proxying the job completion callbacks back through the manager and to their respective queues13:05
tristanRight, that's pretty much what I'm saying13:06
tlaterYep, that seems fine13:06
tristanIf we get this all into a queue manager, we could implement that flow in the scheduler13:06
tristanAlso, we could implement side effects outside of the scheduler13:07
tristan(in the form of additional jobs becoming available for processing)13:07
*** gokcennurlu has joined #buildstream13:56
gokcennurluhi all!13:56
gokcennurluI have a question about the cleanup part in bubblewrap-sandbox, specifically here: https://gitlab.com/BuildStream/buildstream/blob/master/buildstream/sandbox/_sandboxbwrap.py#L21013:58
gokcennurluIn this line, shouldn't the if condition be "if existing_basedirs[basedir]" instead of "if not existing_basedirs[basedir]"13:59
gokcennurluBecause, buildstream prefers to preserve those directories if they already exists before bwrapping.14:01
*** tristan has quit IRC14:05
*** tristan has joined #buildstream14:08
tristangokcennurlu, hmmm, you would appear to be correct :)14:11
tristanor no wait14:12
tristanconfusing :)14:12
* Nexus is interested in this also14:12
tristan"if it did not exist before, we shall skip removing it"14:12
tristanis what we're doing14:12
tristan"if it did exist before, we shall skip removing it" indeed seems correct14:13
tristanthis must have gotten lost in translation somewhere14:13
tristanI sort of wish bubblewrap would take care of this part14:14
tristanor wait... no14:16
gokcennurluTo clarify, "we should clean it, only it was created during/in/due to  bubblewrap"14:16
tristanyes, the double negative is a bit maddening14:17
gokcennurluand "Not do anything, if they already exist just before we start bwarp - because maybe user wants to keep them around"14:17
tristanSo, a good thing would be to add an integration test using the alpine image14:18
tristanif the image contains one of those dirs, we could use a self transforming script element to test it14:18
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: WIP: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42514:19
tristanand assert that existing directories dont get removed from a self transformation script14:19
tristanI think that you are right that 'not' needs to be removed, though14:19
gokcennurlugot it :)14:19
gokcennurlushould I create an issue, than maybe a MR with that fix + integration test?14:20
tristangokcennurlu, that would be great :)14:20
gokcennurluwill do, thank you14:20
cs_shadowtlater: just fyi ^^^ was the thing that was causing the "bug" I mentioned earlier14:21
tlatercs_shadow: Ah, right, that was resolved pretty quickly then :)14:23
cs_shadowtlater: yeah, and our base image was also wrong in the sense that it shouldn't have had those dirs in the first place but it was kinda good that I messed up that part. As we won't have noticed this bug otherwise :)14:24
tristancs_shadow, :)14:25
tristannice catch14:25
gitlab-br-botbuildstream: merge request (tristan/separate-junction-refs->master: Separate junction refs) #434 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43414:42
tristangrrr gitlab15:08
tristanhttps://gitlab.com/BuildStream/buildstream/pipelines/21079144 says it's running... https://gitlab.com/BuildStream/buildstream/-/jobs/64972890 says it's done15:09
* tristan wants to slap the tv set and see a clearer image15:09
tlatertristan: ctl+f5 sometimes helps15:09
tlaterI think they handle client-side caching poorly15:10
tlaterSo browsers end up showing outdated content15:10
tristanoh well would you look at that15:10
tristangitlab still thinks the pipeline is running though15:11
tristaneven will all jobs green15:11
tlaterHm, odd15:11
tristanI'm quite annoyed that my actual code change did not make *any* change in code quality though :-S15:12
tristanhttps://gitlab.com/BuildStream/buildstream/merge_requests/43415:12
tristan" No changes to code quality "15:13
tristanyou'd think that some code changes would have changed *something*, and not be *exactly* the same15:13
tristanwe'll have to see, if we make vast changes to the codebase and the quality never changes, I'm backing out the job :)15:14
tristanhmmm this looks interesting https://www.pydoc.io/pypi/radon-2.0.3/autoapi/cli/tools/index.html#cli.tools.cli.tools.dict_to_codeclimate_issues15:16
dominichow does it determine code quality ooi?15:21
tristandominic, so gitlab decided to hard code another feature instead of letting us just do what we want15:22
tristanit understands a codeclimate.json15:22
tristanwhich is a thing that codeclimate framework generates15:22
tristanApparently, there are a bunch of plugins, and radon is one of them15:22
tristanbut, we just use this black box which gitlab gives us, so we have know clue whatsoever if it works at all15:23
tristanwe're just trying it15:23
tristanat the same time, we *actually run radon* already15:23
dominicahh, OK15:24
tristanSo hopefully, we could feed the `radon cc` results, converted into a codeclimate.json, and circumvent the whole annoying framework which stands in between radon and the results understood by gitlab15:24
gitlab-br-botbuildstream: issue #379 ("_sandboxbwrap.py: Post-bwrap cleanup shouldn't attempt to remove preexisting folders") changed state ("opened") https://gitlab.com/BuildStream/buildstream/issues/37915:43
*** noisecell has quit IRC15:53
*** noisecell has joined #buildstream15:59
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42516:00
*** cs_shadow has quit IRC16:01
*** cs_shadow has joined #buildstream16:01
*** Prince781 has joined #buildstream16:04
*** bethw has quit IRC16:07
gitlab-br-botbuildstream: merge request (jennis/136-clean-remote-cache->master: WIP: jennis/136 clean remote cache) #421 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42116:08
gitlab-br-botbuildstream: merge request (jennis/136-clean-remote-cache->master: WIP: jennis/136 clean remote cache) #421 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42116:08
gitlab-br-botbuildstream: merge request (jennis/136-clean-remote-cache->master: WIP: jennis/136 clean remote cache) #421 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42116:08
gitlab-br-botbuildstream: merge request (jjardon/dependencies->master: .gitlab-ci.yml: Remove redundant declaration of dependencies:) #435 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43516:08
gitlab-br-botbuildstream: merge request (jjardon/another_codequality->jjardon/codequality: WIP: test codequality) #432 changed state ("closed"): https://gitlab.com/BuildStream/buildstream/merge_requests/43216:10
*** jonathanmaw has quit IRC16:11
valentindAre there any project where bzr is used as source plugin?16:13
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42516:14
tristanvalentind, it was originally added to ensure that we can support any conversion from flatpak builder json16:14
gitlab-br-botbuildstream: merge request (jennis/136-clean-remote-cache->master: WIP: jennis/136 clean remote cache) #421 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42116:14
tristanvalentind, if it's not used in freedesktop-sdk, I dont have a current example16:14
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42516:15
tristan(but it's certainly required in order to support flatpak-builder json conversion safely)16:15
valentindAlso I am not familiar with bazaar. But I thought that there was one URL per branch. Though the plugin seems to use the "track" configuration. I am not sure why it is needed to track.16:15
gitlab-br-botbuildstream: issue #361 ("Store junction refs separately to project.refs") changed state ("closed") https://gitlab.com/BuildStream/buildstream/issues/36116:15
gitlab-br-botbuildstream: merge request (jennis/136-clean-remote-cache->master: WIP: jennis/136 clean remote cache) #421 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42116:15
gitlab-br-botbuildstream: issue #361 ("Store junction refs separately to project.refs") changed state ("closed") https://gitlab.com/BuildStream/buildstream/issues/36116:15
gitlab-br-botbuildstream: merge request (tristan/separate-junction-refs->master: Separate junction refs) #434 changed state ("merged"): https://gitlab.com/BuildStream/buildstream/merge_requests/43416:15
valentindtristan, OK. So it could be that the plugin is not mature?16:16
tristanvalentind, you might talk to jonathanmaw about that, he wrote the plugin, but seems to be absent16:16
tristanwell, it's just as aggressively tested as the rest, I should hope that it works very well16:16
gitlab-br-botbuildstream: merge request (jjardon/dependencies->master: .gitlab-ci.yml: Remove redundant declaration of dependencies:) #435 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43516:16
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42516:18
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42516:18
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/42516:19
gitlab-br-botbuildstream: merge request (jjardon/dependencies->master: .gitlab-ci.yml: Remove redundant declaration of dependencies:) #435 changed state ("opened"): https://gitlab.com/BuildStream/buildstream/merge_requests/43516:19
tristanok tomorrow is release day I think16:24
tristantime to update freedesktop-sdk and gnome-build-meta to use ninja for cmake, and start revisioning junction.refs in gnome-build-meta16:25
*** Prince781 has quit IRC16:27
*** dominic has quit IRC17:09
*** dominic has joined #buildstream17:12
*** toscalix has quit IRC17:19
*** dominic has quit IRC17:31
jjardontristan: \o/17:32
jjardontristan: MR for those are ready and waiting for the release17:32
*** Prince781 has joined #buildstream17:42
*** Prince781 has quit IRC17:55
tristanyeah the timing is right for a 1.1.3, we're quite stable17:58
tristanwanna do it before landing anything questionable17:59
* tristan hopes 1.1.4 is a release concentrated on artifact expiry18:00
tristanor at least remote expiry18:00
jjardondouble \o/ :)18:02
gitlab-br-botbuildstream: merge request (jjardon/debian-9->master: .gitlab-ci.yml: Run test in current Debian stable (stretch)) #425 changed state ("merged"): https://gitlab.com/BuildStream/buildstream/merge_requests/42518:13
*** valentind has left #buildstream18:20
*** valentind has joined #buildstream18:21
*** xjuan has joined #buildstream18:25
*** Prince781 has joined #buildstream18:37
*** Prince781 has quit IRC19:20
*** Prince781 has joined #buildstream19:26
*** Prince781 has quit IRC19:31
*** cs_shadow has quit IRC19:41
*** xjuan has quit IRC19:51
*** tristan has quit IRC20:27
*** gokcennurlu has quit IRC21:27
*** aday has quit IRC21:40

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