/srv/irclogs.ubuntu.com/2011/06/16/#ubuntu-ensemble.txt

jimbakerniemeyer, that fixes one test, thanks for the tip00:02
jimbakerstill seeing a problem on ensemble.control.tests.test_upgrade_formula.ControlFormulaUpgradeTest.test_upgrade_formula_service_using_latest00:02
jimbaker(was that fixed by the trivial earlier?)00:03
SpamapSkirkland: I'm testing deploying all of principia w/o ifconfig00:04
jimbakerlooks like line 18 should have been fixed in that trivial earlier, http://paste.ubuntu.com/627679/00:05
jimbakerhazmat, ^^^00:06
kirklandSpamapS: cool00:15
kirklandSpamapS: point me to the diff?00:15
SpamapSkirkland: yeah when its ready. Have to fix some stuff in memcached00:18
SpamapSkirkland: and this is bringing to light the fact that the munin formula needs to not just copy/paste everything. ;)00:19
SpamapSwell.. the munin formula needs to be a machine formula.. but thats another matter entirely. :-P00:19
hazmatjimbaker, yeah.. i think that00:25
hazmatis a fallout from a trivial fix i did earlier today00:25
hazmatjimbaker, it should be a one liner to fix it with the merge if your game00:25
jimbakerhazmat, yeah, just didn't have this one additional change of adding the % id00:25
jimbakerhazmat, absolutely i can make that change, i will work on it in next 20 min or so00:26
_mup_ensemble/expose-provision-service-hierarchy r297 committed by jim.baker@canonical.com00:31
_mup_Removed debugging00:31
SpamapSkim0: hey I made a post tagged ubuntu-cloud (and cloud) and its not showing up on cloud.ubuntu.com01:17
jimbaker`bcsaller, hazmat, niemeyer - i need a trivial on lp:~jimbaker/ensemble/trivial-test-upgrade-formula; the diff is here: http://paste.ubuntu.com/627698/01:18
jimbaker`this fixes the broken test in trunk01:18
niemeyerjimbaker`: hahaha01:18
niemeyerjimbaker`: That assertion is great :-)01:19
niemeyerjimbaker`: +1!01:19
jimbaker`niemeyer, yes, it's kind of funny seeing that %r in the test, it explains a number of rather trivial things ;)01:19
bcsallerlooks good 01:19
_mup_ensemble/trunk r257 committed by jim.baker@canonical.com01:24
_mup_[trivial] Fixes broken test introduced by trivial in r254 [r=bcsaller,niemeyer]01:24
_mup_ensemble/standardize-log-testing r261 committed by jim.baker@canonical.com01:25
_mup_Merged trunk01:25
_mup_ensemble/trunk r258 committed by jim.baker@canonical.com01:29
_mup_merge standardize-log-testing [r=niemeyer,hazmat][f=795233]01:29
_mup_Removed usage and definition of save_logging, reset_logging, and01:29
_mup_assertInDefaultLog from codebase in favor of standard log testing.01:29
SpamapSkirkland: re working w/o IP.. all of the formulas had at least one commit, some two.. the latest formulas from principia have everything except munin removed from using ifconfig. Works *perfectly*01:30
SpamapSbbl01:30
_mup_ensemble/expose-provision-service-hierarchy r298 committed by jim.baker@canonical.com02:10
_mup_Removed unnecessary import from test_provision02:10
_mup_ensemble/set-transitions r241 committed by bcsaller@gmail.com02:27
_mup_merge trunk02:27
=== almaisan-away is now known as al-maisan
=== al-maisan is now known as almaisan-away
=== almaisan-away is now known as al-maisan
_mup_Bug #798115 was filed: Ensemble is too slow to startup <Ensemble:New> < https://launchpad.net/bugs/798115 >11:03
=== al-maisan is now known as almaisan-away
=== almaisan-away is now known as al-maisan
niemeyerMornings!14:32
kim0morning :)14:35
niemeyerkim0: Hey, how're things going there?14:36
kim0hey .. going fine .. how about yourself14:37
niemeyerWaking up from a late night14:38
kim0hope it late fun .. :)14:39
kim0it was*14:39
kim0I just discovered why status takes 5 seconds .. it isn't ssh'ing around the globe .. ensemble itself needs time14:40
m_3morning gang14:40
kim0I filed a bug14:40
kim0m_3: morning :)14:40
niemeyerkim0: Time for what?14:41
kim0start up14:41
kim0check Bug #79811514:41
_mup_Bug #798115: Ensemble is too slow to startup <Ensemble:New> < https://launchpad.net/bugs/798115 >14:41
niemeyerkim0: This is not startup.. this is status working!?14:43
niemeyerkim0: Ensemble is certainly doing more than establishing an ssh connection.. :-)14:43
kim0hmm14:43
kim0would reading the remote data require that much time14:44
niemeyerkim0: Reaching it several times to communicate over zookeeper with a high-latency connection, yes14:44
kim0a ha14:44
kim0perhaps the protocol is chatty :)14:45
kim0if there's any optimizations you guys can do .. that's be great14:46
kim0that'd*14:46
niemeyerkim0: Agreed :)14:46
m_3I've been feeling that one too... we've been on mobile broadband the past few days.  Cable guy due at the new apartment this morning!14:47
m_3es has even been timing out on me14:47
niemeyerstatus is particularly sensitive, as it obtains information about everything14:49
kim0my RTT is 100ms .. it must need 50 round trips :)14:49
kim0and only the bootstrap node was up14:49
niemeyerkim0: Assuming non-existing of the world, yes14:51
niemeyernon-existence14:51
kim0how so ?14:51
niemeyerkim0: It takes 100ms to send an empty packet and doing nothing with it14:51
kim0heh yeah, all I'm saying is it's perhaps worth a good look into where that time is spent, and if there's some quick wins14:52
niemeyerkim0: Making status fast isn't a priority right now.. if we don't make Ensemble more useful, no one will be interested in knowing the status.14:54
niemeyerkim0: So let's say this is a problem we're keen on having, for the moment ;-)14:54
kim0hehe :) I suppose status is not the only thing that's slow .. but yeah, it sure is low priority14:55
niemeyerkim0: It's likely the slowest14:56
niemeyerkim0: By a significant margin14:56
m_3user perception thing... you expect bootstrap and deploy to be slow... and status to be fast14:56
kim0yeah, my uneducated guess was about the opposite :)14:56
m_3but it's the opposite14:56
niemeyerkim0: After removing the constant factors, of course (ssh, etc)14:56
kim0m_3: exactly14:56
m_3I agree, it's not high priority right now, but good to mention14:56
niemeyerm_3: Well.. it's _really_ perception, because they _are_ the slowest14:57
niemeyerm_3: The difference is that the command line isn't hooked up14:57
m_3yup14:57
niemeyerWhich means there isn't a guy bashing the enter key and screaming "FASTER! FASTER!" on the other side.14:58
kim0niemeyer: would having an interactive ensemble tool help14:58
niemeyerkim0: A bit.. not much14:59
niemeyerkim0: Reducing the number of roundtrips is the real win14:59
kim0yeah14:59
m_3it certainly seems like it'd be cool to have an 'ensh' interactive shell15:03
m_3but I don't know the real utility of that other than blocking commands to give the user feedback and maybe sense of control15:04
kim0maybe it could have a replica of the zk environment ? would that help a lot overcome high latency networks ?15:05
m_3not important15:05
* kim0 never used zk, and is getting ready for random things to be thrown at him :)15:05
m_3zk docs even call them zk "ensembles"15:06
kim0hehe15:06
niemeyerkim0: Brilliant stuff in the tutorial15:10
kim0yeah more exposure to docs basically15:11
niemeyerjimbaker`: ping15:30
jimbaker`niemeyer, hi15:31
niemeyerjimbaker`: Hey man15:31
niemeyerjimbaker`: What's up there?15:31
jimbaker`niemeyer, looks like it's another nice day here in colorado15:32
niemeyerjimbaker`: Nice :-)15:33
niemeyerjimbaker`: I'm review the expose branches, and would just like to bring up an idea about function naming15:33
jimbaker`niemeyer, sounds good15:34
jimbaker`definitely would like to hear any ideas on such things, the provision code had to come up with a number, and they probably can be improved15:35
niemeyerjimbaker`: If I tell you something like.. hmmmm.. "Can you please check the schedule?", what kind of assumption can you make?15:35
jimbaker`we are probably dealing with issues around time, or more generally events15:36
niemeyerjimbaker`: Right, but it's pretty hard to figure what I'm trying to figure, right?15:36
niemeyerjimbaker`: Same thing as.. "Hey, can you please go down and check the street?"15:37
niemeyerjimbaker`: This an "empty" request, if you see what I mean15:37
niemeyerIt's an15:37
jimbaker`niemeyer, correct, the work "check" is one of those words that feels like a crutch word15:37
jimbaker`extremely vague15:38
niemeyerjimbaker`: Yeah..15:38
niemeyerjimbaker`: It'd be much easier to say, "Is there traffic in the street?"15:38
jimbaker`so ideally it would not be used. so the question is, what replaces it to be more precise15:38
niemeyerjimbaker`: Or, "Ensure our slot is booked in the schedule"15:39
niemeyerjimbaker`: This is detailing the intended _outcome_, rather than how one will do it15:39
niemeyerjimbaker`: check_firewall_settings, watch_service_changes, ... they have that feeling15:39
niemeyerjimbaker`: open_close_ports() is a much better name than check_firewall_settings, as an example15:40
jimbaker`niemeyer, sounds like a great suggestion for that function name15:41
jimbaker`watch_service_changes of course parallels the existing watch_machine_changes15:41
niemeyerjimbaker`: They are both bad as well15:42
niemeyerjimbaker`: For the same reasons15:42
jimbaker`so there was some convention already existing, but as you mention, bad15:42
niemeyerjimbaker`: and worse, they look like a request to watch..15:42
niemeyerjimbaker`: Which isn't the case15:42
niemeyerjimbaker`: Agreed.. consistency is better than nothing15:43
jimbaker`niemeyer, agreed, going outside of the narrow scope of this particular file, the larger convention is watch means to actually *watch*15:43
niemeyerjimbaker`: But we can as well change both, consistently :)15:43
niemeyerjimbaker`: Right, exactly15:43
niemeyerjimbaker`: and for the same reasons above, this is vague15:43
niemeyerjimbaker`: Watch for what?  Will have to read the doc/code to know15:44
jimbaker`niemeyer, sure, i can definitely make that change15:44
jimbaker`in both names15:44
niemeyerjimbaker`: E.g. watch_expose_flag is a good name for watch_service_changes15:46
jimbaker`the first is to at least use our cb_ prefix to indicate callbacks15:46
niemeyerjimbaker`: I'm ambivalent about it.. they are generally good hints when we can't figure something better that actuall describes the intention15:47
niemeyerjimbaker`: Otherwise, twisted is all about callbacks.. we'll go crazy :)15:47
niemeyerjimbaker`: Note that we generally use cb_<watcher function name>, if I remember correctly15:48
jimbaker`niemeyer, certainly twisted is always about the callback, fortunately inlineCallbacks can make it more linear15:48
jimbaker`but that's another line of thought15:48
niemeyerjimbaker`: Which means we have the same problem as above.. the function name has no hints about its intention15:48
niemeyerjimbaker`: Perhaps a good way to put the distinction is that one is "this is why someone is calling me" and the other is "this is what I'm going to do"15:49
niemeyerjimbaker`: The latter is generally more useful when reading the code15:49
jimbaker`niemeyer, indeed15:50
jimbaker`my 10 year old daughter just got into this in her robotics camp last week. i looked at the function names she was writing, and they were very explicit on what the function was going to do15:51
jimbaker`(this was in C, she told me on the 2nd day she wanted to be a programmer. i told her that in the future, all professionals will be programming in some way ;) )15:51
niemeyerjimbaker`: I'm not entirely sure.. I had that feeling in the early 90s, but nowadays it feels like it's getting harder to get people interested in the details of the problem15:52
niemeyerJust too easy to be a user, I guess15:53
jimbaker`i consider building a spreadsheet model to be programming, or similar tasks. it can be done visually or with code, or both15:54
jimbaker`but again the aspect of functions that describe concrete functionality, and that we can effectively reason about them because we have good names, that was very clear in my daughter's code and ideally in any code we all write15:55
niemeyerjimbaker`: COol15:55
niemeyerjimbaker`: Re. [3], can you extend a bit on why you think it's not doable?15:56
jimbaker`niemeyer, this is the collapsing together of both dictionaries15:56
niemeyerjimbaker`: Yeah15:56
jimbaker`so certainly doable, the question was whether it would make things harder to read15:57
niemeyerjimbaker`: Agreed.. I had the impression it'd make them easier15:57
niemeyerjimbaker`: So I'm interested in your perspective15:57
jimbaker`i need to track two distinct things here. whether or not a watched service is exposed or not. if it is exposed, we then start a watch on its service units15:59
jimbaker`and then what watches have been established for each service unit15:59
jimbaker`self._watched_services tracks the first; self._watched_service_units the second16:00
niemeyerjimbaker`: Yes, as I understand it, you need to track: a) Whether a service is exposed or not; b) What units in this service are being watched16:00
niemeyerjimbaker`: Is that correct?16:00
jimbaker`niemeyer, not quite16:01
niemeyerjimbaker`: Ok.. that may be the detail I'm missing then.16:01
jimbaker`niemeyer, because i need to track two watches for a service, because that's the api i'm working with16:01
jimbaker`1) watching the service's exposed flag; 2) watching its service units16:01
niemeyerjimbaker`: Isn't that a and b above?16:02
jimbaker`niemeyer, sorry, it was a little ambiguous16:03
jimbaker`niemeyer, for each service unit, we need to watch its ports16:03
jimbaker`so that's the watch per service unit16:03
niemeyerjimbaker`: Ok, so.. it feels like we're talking about the same thing16:05
niemeyerjimbaker`: So, objectively..16:05
niemeyerjimbaker`: self._watched_services tracks which services are watched.. and it's really a set rather than a dictionary16:05
niemeyerjimbaker`: It's values aren't used for anything16:06
jimbaker`so _watched_services manages watches at the granularity of one watch per service (watch_exposed_flag, watch_service_units); _watched_service_units tracks at the granularity of a service unit16:06
niemeyerjimbaker`: self._watched_service_units is a defaultdict, which means the information of whether a key exists or not is not being used in any good way16:06
jimbaker`niemeyer, actually _watched_services value is used to indicate whether the watch_service_units watch has been started16:07
niemeyerjimbaker`: Make the latter a real dict, and use presence information in a good way16:07
niemeyerjimbaker`: This way you don't need two dictionaries, nor the clean up you have in other functions16:07
jimbaker`False - only watch_exposed_flag; True - also started watch_service_units16:08
niemeyerjimbaker`: I understand.. can you please point out the place in the code that invalidates the suggested design?16:09
jimbaker`niemeyer, i think what you are suggesting is something like the following:16:10
jimbaker`the presence of keys in _watched_service_units indicates that it is exposed; the corresponding value may be None (or whatever value is useful) if there is no watch on its service units; when that watch is established, change to a set, which collects all the watches on the corresponding service units' ports16:12
jimbaker`niemeyer, i can certainly implement such a design. it just seemed more complicated16:12
jimbaker`niemeyer, if you have another design in mind, i don't see it16:13
niemeyerjimbaker`: Maybe it's more complicated, but I'm trying to understand why..16:14
niemeyerjimbaker`: It feels like you have double bookkeeping, e.g.16:14
jimbaker`niemeyer, alternatively i can use a multi-level dict or equivalently an object to represent this mapping16:14
niemeyer+                self._watched_services[service_name] = False16:14
niemeyer+                self._watched_service_units.pop(service_name, None)16:14
jimbaker`niemeyer, agreed, that is an implication of the design16:15
niemeyerjimbaker`:16:15
niemeyer+            self._watched_services.pop(service_name, None)16:15
niemeyer+            self._watched_service_units.pop(service_name, None)16:15
jimbaker`on the other hand, there is no need to do any conditionals on what the value of _watched_service_units is16:15
niemeyerjimbaker`: Yeah, and I'm trying to understand why the complication is necessary.16:16
niemeyerjimbaker`: Sure, because you're always doing it in a different dictionary that you maintain sideways :-16:16
niemeyer)16:16
jimbaker`so you make that one tradeoff in a couple of places where the parent key (so to speak) is deleted and one's maintaining referential integrity (so to speak). but arguably resulting in simpler code16:17
niemeyerjimbaker`: I don't see the tradeoff.. you're effectively discarding presence information in one and using only presence information in the other16:18
niemeyerjimbaker`: Either way, never mind16:18
niemeyerjimbaker`: I should have just tried out.. it'll be easier16:18
niemeyerjimbaker`: You may well be right.. I'm just missing the "This is a better design, because ..." sentence.16:19
jimbaker`niemeyer, no worries, just wanted you to know i thought through the implications of your question16:19
jimbaker`and looked at the implementation. it seemed more complicated, at least at what i tried, vs the relative simplicity of what's being done now16:20
jimbaker`but again at the cost of two dicts16:20
niemeyerjimbaker`: If it's simpler, let's keep it.16:20
niemeyerjimbaker`: I'm just missing the "This is simpler, because ..." explanation.. but it's just me failing to get it.16:21
jimbaker`again, i think the lack of conditionals makes it simpler. instead we trade that for invariants (hence the use of code like self._watched_service_units.pop(service_name, None) - it may be there, it may not, it doesn't matter)16:22
jimbaker`my concern was that there was enough logic in this code already, i didn't want to increase its level16:23
niemeyerjimbaker`: Yeah, no conditionals is simpler.. why would we need conditionals? (rhetoric question)16:24
jimbaker`niemeyer, ;)16:24
niemeyerjimbaker`: This is rhetoric in the sense that this is the kind of thing that can make a long conversation about design short..16:24
niemeyerjimbaker`: "I need to track the foobar of the boodoom." finishes such conversations in no time.16:25
jimbaker`niemeyer, sure, that's absolutely right16:25
niemeyerjimbaker`: "Code without conditionals is simpler." gives no hints.16:25
jimbaker`also having dictionaries state this is what i track, and my invariant is maintained, that's nice too16:26
jimbaker`naively, it would be nice if it would nice if it were possible to avoid all such extra state, it is possible to introspect for a watch, but that's not really going to work as i understand it16:27
=== al-maisan is now known as almaisan-away
niemeyerMan..16:50
niemeyerThis whole inlineCallback thing is tricky..16:50
niemeyerWhile it brings back the nice feeling of straight code back, it also introduces concurrency issues which are very easy to ignore.16:51
niemeyerjimbaker`: This is what I mean16:58
niemeyerjimbaker`: http://paste.ubuntu.com/628037/16:58
niemeyerjimbaker`: Untested..16:58
niemeyerjimbaker`: But theoretically it shouldn't break the tests, if they are not deeply dependent on the implementation16:58
niemeyerjimbaker`: There are also a couple of points inlined in the diff worth noting16:59
niemeyerjimbaker`: I'll step out for lunch.. please let me know what you think16:59
niemeyerjimbaker`: About the approach, not lunch ;-)16:59
jimbaker`niemeyer, enjoy your lunch. i certainly have food opinions, but they are to express remotely17:00
jimbaker`hard to express17:00
jimbaker`niemeyer, i'll take a look at the diff thanks17:00
jimbaker`niemeyer, still taking a look at you diff to see why it doesn't work17:34
hazmatjimbaker`, i was looking at the zookeeper test setup, and was curious how the contextmanager and generator here works with the test setup... it looks like a nice way for us to do fixtures17:38
hazmatjimbaker`, if you have a few minutes to discuss i'd like to do an audio chat17:38
jimbaker`hazmat, i'm looking at that code again, one moment17:40
jimbaker`hazmat, this is a basic example of a context manager. sure, we can talk now if you'd like. mumble? skype?17:42
niemeyerjimbaker`: Thinking over lunch, I understand why you preferred the other approach.. the first dictionary is actually a three-state one17:42
jimbaker`niemeyer, correct17:42
niemeyerjimbaker`: So _watched_services[name] = False is actually not entirely correct17:43
niemeyerjimbaker`: The service _is_ being watched17:43
jimbaker`sure, it's not just being watched for its service units. but it does correspond to being exposed or not, hence the boolean17:43
niemeyerjimbaker`: Yeah, booleans are lovely.. :-)17:44
niemeyerjimbaker`: I'm happy with either approach, but it needs clarification.. I'll see if I can make tests pass with this and compare17:45
jimbaker`niemeyer, yes, they say exactly what i mean them to be ;) i hope17:45
niemeyerjimbaker`: _watched_services[foo] being False means the service is not watched.17:45
jimbaker`niemeyer, yeah, obviously there's still one ref to watched_service_units in your diff, but there's more to it than that17:45
niemeyerjimbaker`: No other way to interpret it17:45
niemeyerjimbaker`: Yeah, leave that with me17:46
jimbaker`niemeyer, so maybe it should mean - _watching_service_units or something like that and _watching_service_unit_ports, although this seems too wordy17:46
jimbaker`but again a tweak on the names can make this clearer17:46
niemeyerjimbaker`: If the single design doesn't work, we can come up with something like _watched_services[foo] = Exposed/Unexposed17:47
niemeyerjimbaker`: Erm.. single dict design17:47
jimbaker`niemeyer, that's also a good choice. maybe they can define nonzero too17:47
jimbaker`;)17:48
niemeyerjimbaker`: nonzero?17:48
jimbaker`niemeyer, i believe it's __nonzero__ to be precise, as called by bool17:48
jimbaker`new objects that act just like booleans!17:48
niemeyerjimbaker`: Heh17:49
jimbaker`biab, i'm going to get some coffee17:50
niemeyerEnjoy17:51
negronjlniemeyer:  where is the ensemble documentation?  I used to have it but, can't find it now.17:54
niemeyernegronjl: Should be in https://ensemble.ubuntu.com/docs17:55
negronjlniemeyer:  perfect!  thanks!17:55
niemeyernegronjl: np!17:55
negronjlniemeyer: does ensemble take care of the security groups in AWS?  ie:  if I have a service that requires port 8112 open, would it take care of opening that port and closing whatever is left ?17:58
niemeyernegronjl: We're working on that _right now_, literally :-)17:59
niemeyernegronjl: Both me and jimbaker` are hacking on it as we speak17:59
negronjlniemeyer:  perfect.  thx17:59
niemeyernegronjl: The idea will work like this:17:59
niemeyernegronjl: The formula declares what ports it needs open17:59
niemeyernegronjl: Via a call to, say, open-port 80/tcp 17:59
niemeyernegronjl: That doesn't actually _open_ the port directly, though18:00
niemeyernegronjl: The admin is in control of which services are exposed18:00
niemeyernegronjl: So you can do something like18:00
niemeyernegronjl: ensemble expose myblog18:00
niemeyernegronjl: This command will make Ensemble check which ports the formula declared as open, and will open the firewall for them, specifically18:00
negronjlniemeyer:  that's great 18:01
niemeyernegronjl: So the ports that are punched through the firewall are those that both: a) Have been declared as open-port by the formula; and b) Have been exposed18:01
niemeyernegronjl: What we have in trunk right now is "everything is open party"18:02
negronjlniemeyer:  I noticed. hence the question :P18:02
niemeyernegronjl: One jimbaker` finished the last few bits, we'll have the full feature18:02
negronjlniemeyer:  perfect.18:02
niemeyernegronjl: I'm just assisting jimbaker`18:02
niemeyernegronjl: Once jimbaker` finishes the last few bits, we'll have the full feature18:03
niemeyer(that was the real sentence :-)18:03
kim0I wonder if "open port" means open to the general Internet .. is it possible to open to some other service only ? like mysql being accessible from mediawiki only18:22
jimbaker`kim0, that's certainly a fair question - for now open-port doesn't mean that, it's the exposed setting that means open to the internet (and interprets opened ports accordingly)18:24
jimbaker`kim0, hope that makes sense18:24
* kim0 scratches head18:24
kim0so it's not possible today to open to a certaing sg right ?18:25
jimbaker`niemeyer just went over how these two pieces fit together with negronjl, fwiw18:25
jimbaker`kim0, there is no current open design work to do what you ask18:25
kim0yeah got it18:25
jimbaker`kim0, but i can imagine that we could leverage open-port as you describe to get at different security zones along the lines of what SGs in general can do18:26
niemeyerkim0: In a way, open-port actually means exactly that.. it tags which port _should_ be open to whoever is consuming that service18:26
niemeyerkim0: As jimbaker` points out, we're not working on inter-service-unit handling of that now, though18:27
kim0yeah got it .. thanks18:27
niemeyerYeah, what jimbaker` says18:27
jimbaker`kim0, we should certainly capture this in a bug18:28
_mup_txzookeeper/session-event-handling r44 committed by kapil.foss@gmail.com18:35
_mup_managed zk cluster api18:35
=== daker is now known as daker_
_mup_txzookeeper/session-event-handling r44 committed by kapil.foss@gmail.com18:49
_mup_managed zk cluster api18:49
negronjlok guys.  so I have hadoop-master set up in ensemble but, I have a question before I move forward with the slave nodes.  Any way of changing the instance type to m1.large ( or anything else for that matter )?18:56
hazmatnegronjl, not at the moment18:58
negronjlhazmat:  thx.  no worries.  I'll deal with it.18:58
niemeyerhazmat: Hmm18:59
niemeyerhazmat: What about default-instance-type?18:59
hazmatwe've talked before about using a separate ebs volume per unit instead of an ebs instance, which would allow for some sort of expansion.. but that's really post lxc isolation 18:59
hazmatnegronjl, as  niemeyer points out you can switch the default instance type for the entire environment if you wish, but not per unit/machine atm18:59
negronjlhazmat:  where would I change that ?18:59
hazmator service for that matter..18:59
hazmatnegronjl, in ~/.ensemble/environments.yaml19:00
negronjlhazmat:  perfect!  thx.19:00
hazmatnegronjl, https://ensemble.ubuntu.com/docs/provider-configuration-ec2.html19:01
negronjlhazmat: perfect! thx.19:01
niemeyerhazmat++ for actually documenting it :)19:02
hazmatniemeyer, it was getting hard to remember ;-)19:02
niemeyerYo compiz!  Gimme my cursor back!19:05
niemeyerNo game :(19:06
kim0I'll give unity another chance by 11.10 :)19:07
hazmatkim0, when it comes to compiz its underlying unity and classic.. so its hard to escape from its bugs..19:07
kim0oh yeah .. I do run gnome without unity .. rock solid19:08
kim0without compiz I mean19:08
niemeyerjimbaker`: http://paste.ubuntu.com/628096/19:08
niemeyerjimbaker`: All tests pass19:08
hazmatkim0, how do you set that up.. if i login under classic, i still have compiz as the window manager afaics19:09
niemeyerjimbaker`: Sorry, let me add a proper comment on the dict19:09
hazmati'm still averaging a reboot about every 6hrs.. or some sort of re-login after the xsession crashes19:09
jimbaker`niemeyer, ok, i like that much better19:10
kim0hmm .. I am indeed running metacity .. no idea how to configure it though 19:11
jimbaker`niemeyer, it reads better than my version, so thanks19:11
kim0hazmat: perhaps gconf-editor → desktop -> gnome -> applications -> window_manager and set to metacity19:12
niemeyerjimbaker`: No problem19:14
niemeyerjimbaker`: Here is the version with the comment: http://paste.ubuntu.com/628102/19:14
hazmatkim0, awesome thanks.. i'll try that out19:15
niemeyerjimbaker`: I was glad to dive in as well.. the overall logic feels good, even though I'm still a bit concerned with concurrency issues19:16
jimbaker`niemeyer, comment is also good, and i like how the dict is maintained19:16
jimbaker`niemeyer, i understand your concern, but after being in that code for a while, i think the concurrency aspects are solid19:16
niemeyerjimbaker`: I'm not entirely sure.. I'm concerned in general, not just with that one piece of code19:17
niemeyerjimbaker`: We haven't been considering locks, etc, very often.  Twisted makes us lazy in that regard, but every yield in a function is putting control away from the function, and the world can change at that point.19:18
jimbaker`niemeyer, yeah, that's definitely what i think whenever i have a yield19:18
niemeyerjimbaker`: As an example, in that same diff, look at the original cb_check_service_units function19:18
niemeyerjimbaker`: You were making assumptions about the state of the world within it19:18
niemeyerjimbaker`: because you've _tested_ it19:19
niemeyerjimbaker`: But every time you "yield", the world can change19:19
jimbaker`niemeyer, the world may change. not completely arbitrary19:19
niemeyerjimbaker`: Concrete example:19:19
niemeyer-                if unit_name not in self._watched_service_units[service_name]:19:19
niemeyerjimbaker`: What guarantees that the service wasn't unexposed on the yield within the for loop?19:19
niemeyerjimbaker`: Not arbitrary, but hard to keep the world state in mind..19:20
negronjlany way to ssh into the instances to get a better view of what's going on ?19:20
niemeyernegronjl: ensemble ssh <machine number>19:21
niemeyernegronjl: Or,19:21
jimbaker`niemeyer, thanks that is in fact an invalid assumption19:21
niemeyernegronjl: ensemble ssh $UNIT_NAME/$N19:21
negronjlahh...perfect!  thanks niemeyer19:21
niemeyerjimbaker`: It's hard.. I don't blame you19:21
niemeyernegronjl: np!19:21
niemeyernegronjl: You may also be interested in "ensemble debug-hooks"19:22
niemeyernegronjl: It's quite fun19:22
negronjlniemeyer:  I'll make sure to check it out19:22
niemeyernegronjl: A bit like "gdb for hooks" :-)19:22
negronjlniemeyer:  perfect!  exactly what I'm looking for19:22
kim0negronjl: check out https://ensemble.ubuntu.com/docs/write-formula.html#debugging-hooks and let me know how to improve it :)19:23
jimbaker`niemeyer, in your new code you ignore this transition from the set to NotExposed (or deleted), because it's safe to setup such watches, they will simply terminate immediately19:23
jimbaker`niemeyer, so keeps things simple19:23
jimbaker`niemeyer, and correct19:23
negronjlniemeyer:  hadoop-master and hadoop-slave is done.  Would you point me to how to submit this for you guys?19:24
negronjlniemeyer:  I pressume that I would submit this to principia ??19:24
negronjlniemeyer:  now that I have a better understanding, I plan on porting all of the other orchestra-modules to ensemble.19:25
kim0negronjl: check out https://ensemble.ubuntu.com/Principia19:25
negronjlkim0:  perfect!  thx19:26
niemeyernegronjl: Woah, that's awesome!19:27
negronjlthx niemeyer19:27
niemeyernegronjl: Man, can't wait to deploy my first hadoop cluster with Ensemble19:28
niemeyerhazmat: Have we missed the weekly meeting timing?19:34
niemeyerhazmat: Or did I get it wrong?19:34
=== almaisan-away is now known as al-maisan
niemeyerkim0: Have you been merging your branches?19:42
kim0nope19:42
niemeyerkim0: Ok, please let me know when you do the suggested FAQ tweaks then, and I'll comit19:42
niemeyercommit19:42
kim0niemeyer: that was the branch https://code.launchpad.net/~kim0/ensemble/updating-faq19:43
kim0niemeyer: don't know if it's merged or not19:43
niemeyerkim0: I know, I just reviewed it19:43
niemeyerkim0: https://code.launchpad.net/~kim0/ensemble/updating-faq/+merge/6467919:44
kim0ah ok .. will update the branch19:44
kim0Is there any scientific explanation to a browser tab spinning/loading for 30mins! I mean tcp should either timeout, or retry right19:51
niemeyerkim0: Long polling is one of them19:53
niemeyerkim0: I.e. its constantly retrying to wait for updates from the server19:54
niemeyerit's19:54
kim0like gmail .. I dont think it keeps spinning in that case19:54
niemeyerkim0: There are different implementations possible19:55
niemeyerkim0: http://tools.ietf.org/html/rfc620219:55
kim0thanks!19:56
kim0although I'm actually inclined to think it's more of a bug than a website feature .. since refreshing the page, would finish loading in a couple of seconds19:57
kim0any way nvm19:59
niemeyerkim0: Possibly20:04
SpamapSkim0: did you get my msg about my post not syndicating onto cloud.ubuntu.com ?20:54
=== al-maisan is now known as almaisan-away
kim0yeah just replied21:08
* kim0 mostly afk 21:08
negronjlniemeyer:  Filed bugs #798421 (hadoop-master) and #798422 ( hadoop-slave).  Feedback is well appreciated.21:43
_mup_Bug #798421: new-formula (hadoop-master) <new-formula> <Principia Ensemble:New> < https://launchpad.net/bugs/798421 >21:43
_mup_Bug #798422: new-formula (hadoop-slave) <new-formula> <Principia Ensemble:New> < https://launchpad.net/bugs/798422 >21:43
niemeyernegronjl: Awesome, thanks a lot!21:44
negronjlniemeyer:  np.  I'll be working on the rest of 'em shortly.21:44
hazmatnegronjl, this is the hdfs name node and job tracker re hadoop-master?21:58
negronjlhazmat:  I don't quite get your question21:59
hazmatnegronjl, i'm just trying to understand what bits are managed by the hadoop-master formula21:59
* hazmat digs through the source21:59
negronjlhazmat:  I have to go to a meeting now.  Do you mind if we talked about this in a while ( 30 minutes or so )22:00
hazmatnegronjl, sounds good22:00
SpamapSinteresting22:00
SpamapS3 interfaces, does that work?22:00
SpamapSnegronjl: have you deployed these yet?22:03
negronjlSpamapS:  I have22:03
hazmatSpamapS, any reason you thought they wouldn't work?22:04
SpamapSThe only confusing part is the 3 interfaces22:04
SpamapSensemble-log "Point your browser to http://${public-hostname}:50070"22:04
SpamapSAlso the variable public-hostname isn't ever set22:04
hazmathmm.. yeah.. three interfaces under one name is a bit strange22:04
hazmatnot sure that's valid22:04
SpamapSWell there's really no reason for 3 interfaces22:04
SpamapSnegronjl: can you explain what you were trying to accomplish there?22:05
SpamapSnegronjl: (BTW this is *really* cool)22:05
negronjlSpamapS:  let me get through my meeting and I'll work with you guys on this22:05
SpamapSm_31: ping, we're discussing hadoop, you should be paying attention. :)22:05
SpamapSnegronjl: ahh yes! when you have time then, just ping us22:05
hazmatnegronjl, only the last interface will survive, its over-writing a duplicate key else22:06
hazmatnegronjl, ttyl22:06
SpamapSahh more abuse of the "what is my IP" paradigm. I feel quite personally responsible for that.22:06
hazmatnegronjl, and i agrew with SpamapS this is very cool22:06
hazmatSpamapS, almost as much i ;-)22:07
SpamapSI'm sure hostnames will suffice for the places where IP is being used.22:07
hazmatSpamapS, i thought you'd switched out principia to getting things off ifconfig?22:07
SpamapSThe one place where I'm resolving them in the formula into IP's, is memcached because I don't want web requests blocking on DNS.22:07
hazmatinstead of the md server.. but i guess the dns name still needs the md server or external actor providing this info22:07
SpamapShazmat: just yesterday I switched almost everything to getting things from DNS22:08
hazmatSpamapS, sure... but they get cached typically so the per request overhead should still be neglible22:08
SpamapSI'm looking into whether or not to also include running a local caching name server as well.22:08
SpamapShazmat: they don't get cached by PHP very effectively. :-P22:09
SpamapShazmat: it does the equivilent of nscd .. cache it "forever"22:09
SpamapShazmat: but yeah, it may not be worth it to resolve in formula even in that case.22:10
SpamapSI think I'll add a principia proof warning about querying the metadata service22:14
m_3negronjl: just branched them... awesome!22:17
_mup_ensemble/status-dot-output r259 committed by bcsaller@gmail.com22:20
_mup_fix for Bug #792448, unsafe labels in dot graph22:20
_mup_ensemble/status-dot-output r260 committed by bcsaller@gmail.com22:21
_mup_example of previously bad input, used by tests22:21
negronjlahh...meeting is going long guys.  I've been reading SpamapS about the three interfaces and I think I can get it all done with just the one interface.  give me a few minutes to fix22:21
_mup_ensemble/relation-get-eval r228 committed by bcsaller@gmail.com22:26
_mup_remove shell variable prefix, its now implicit22:26
SpamapSOk I just added a check in principia's proof command that warns if you use the metadata service directly...22:29
* SpamapS now starts cleaning all of those up22:29
negronjlSpamapS:  can you elaborate on using metadata service directly?22:32
negronjlSpamapS: I'm new to this hence all the stupid questions22:32
SpamapSnegronjl: I feel a lot more stupid trying to grok hadoop than you do asking about my cryptic communication style. ;)22:33
SpamapSnegronjl: Basically that would mean the formula would be undeployable outside of EC222:33
SpamapSnegronjl: in addition, that information is available in DNS. The one thing that isn't is the public hostname, but thats really something we need to make ensemble provide.22:34
negronjlSpamapS: ahh...it all makes sense now.  I remember the very "nice" conversation on one of the channels about ipaddr22:34
SpamapSnegronjl: "nice" :)22:34
SpamapSnegronjl: the appropriate thing to do is send around hostnames, and if you *MUST* resolve it to an IP, resolve it where you are going to use it, not where you are sending it from.22:35
negronjlSpamapS: I can always ifconfig ...... awk .... echo .. .sed ..etc. :)22:35
SpamapSThat way you can take into account whether or not you have IPv6 .. and any search domains22:35
SpamapSnegronjl: nooo thats the next evil hack I'm going to add a warning for. :)22:35
SpamapSnegronjl: hostname -f gives you the FQDN of your machine. Send that.22:35
negronjlSpamapS: I knew that would get a kick out of ya :)22:35
negronjlSpamapS:  Would it be better to use hostname instead of IP?  Also, where do I get the Public DNS from if not from the meta-data ?22:54
SpamapSnegronjl: yes, hostname -f should always be resolvable from any node that can reach you directly..22:55
SpamapSnegronjl: for the public hostname, you can get it from 'whatismyip.com' .. 22:56
SpamapSnegronjl: just kidding btw.. I think we need Ensemble to provide a machine info tool that works accross any machine provider.22:56
negronjlSpamapS:  so, for now, I'll use the hostname -f for internal and meta-data for external ( until I get something better )22:57
SpamapSnegronjl: when do you *actually* need the public hostname, programattically?22:57
SpamapSnegronjl: the only space I see you attempting to use it is to print, into the debug log, the hostname people should use to access the server.22:57
SpamapSnegronjl: which you can get from 'ensemble status'22:57
negronjlSpamapS:  I'll do that instead.22:58
negronjlSpamapS:  taking it out22:58
SpamapSnegronjl: \o/22:58
SpamapSNow if we only had an LXC machine provider...22:58
negronjlSpamapS:  I pushed all of the changes we discussed here (one interface instead of three, hostname -f instead of meta-data, remove the public-dns bit )23:00
SpamapSpulling23:01
jimbakerSpamapS, want to discuss bug 766317 ?23:01
_mup_Bug #766317: debug-log should show relation settings changes <Ensemble:In Progress by jimbaker> < https://launchpad.net/bugs/766317 >23:01
negronjlSpamapS:  deploying ( and praying a bit )23:02
SpamapSnegronjl: principia proof reports this:  W: all formulas should provide at least one thing23:02
jimbakerbasically this addresses observability of formulas. obviously i can readily write a utility to grab this zk info and show how it changes23:02
SpamapSnegronjl: for hadoop-slave .. the reason is, if it doesn't provide anything, how can other services consume what it does?23:02
jimbakerw/in the constraints of any applied security on zk, of course23:02
negronjlSpamaps:  you don't consume anything out of the hadoop-slave nodes23:02
SpamapSjimbaker: Right, I'd prefer that we not log all that data (even though we are now.. thats something I think we should change and not log these credentials.23:03
negronjlSpamapS:  ... your own wordpess formula (/usr/share/ensemble/examples/wordpress ) doesn't provide anything either :D23:03
jimbakerSpamapS, debug-log is certainly not intended for actual logging23:03
SpamapSnegronjl: yes, thats a bug, it should provide 'website'23:03
jimbakerof course as it is right now, it's just going through ZookeeperHandler, so it has the potential to leak to other handlers i suppose23:04
SpamapSnegronjl: interesting though.. these essentially just contact the master and "help" it..23:04
negronjlSpamapS: I guess I can provide some dummy interface if I have to but, you are correct...they just help the master do it's thing 23:04
SpamapSjimbaker: the log file that I'm concerned about is the formula log, which seems to be related to debug-log23:04
SpamapSnegronjl: well it may be that this is an exception worth making.23:05
SpamapSnegronjl: can the master do anything useful without the slaves?23:05
negronjlSpamapS:  not really23:05
SpamapSnegronjl: so maybe flip them.. master requires: hadoop-slave23:06
jimbakerSpamapS, correct as i recall debug-log is effectively collating what goes into agent logs like the formula log, through the standard log handler mechanism in python23:06
SpamapSand provides .. whatever it is that other services consume from it.23:06
SpamapSnegronjl: the reason I wrote that "everything must provide one thing" is because conceptually (while maybe not pragmatically), its true.23:06
negronjlSpamapS: let me see if I understand it.  Let me play with it for a bit23:07
jimbakerSpamapS, i don't have enough log-fu to know if it is possible to ensure that some things are never written to a specific handler23:07
SpamapSnegronjl: before you go too far down that rabbit hole..23:07
negronjlSpamapS:  yeah?23:07
SpamapSnegronjl: This seems like just the beginning. How do other services utilize the master?23:08
jimbakerSpamapS, but we could make it such that by default it is not written to such formula logs, that should be doable23:08
negronjlSpamapS:  they upload files to it  (jar files and such) for hadoop to process23:08
SpamapSnegronjl: also one other mistake your formulas have, that is not always obvious, is that sometimes your 'relation-get' won't return anything, because the other side won't have done its 'relation-set' just yet... you have to test that the values are actually set.23:09
jimbakerSpamapS, anyone who could overwrite this presumably can sub in arbitrary code in anyway23:09
jimbakerSpamapS, so maybe that will address your concern?23:09
negronjlSpamapS:  should I trust that ensemble will re-run the script when the relation-set part gets done?23:10
SpamapSjimbaker: I'd rather just never see values logged by ensemble. Its far simpler for formula authors to choose when they do that, if somebody needs more observability, they should use debug-hooks or just alter the formula.23:10
SpamapSnegronjl: yes23:10
jimbakerSpamapS, well at some point there's going to be a utility written for this because it's rather useful in my experience23:11
SpamapSnegronjl: if you look, a lot of the  -changed formulas do relation-get, and if all the values aren't set, just exit 023:11
negronjlSpamapS:  ok.  I can do that23:11
SpamapSjimbaker: useful and secure are often at odds. :)23:11
jimbakergiven the ease of access to ZK, even if it's simply third party23:11
jimbakerSpamapS, agreed on how security is always getting in the way ;)23:12
SpamapSjimbaker: I don't mind that the data is in zookeeper at the time. But I'm considering instances where people may exchange something like tokens or encryption keys and then delete them, but they might be useful for decoding sniffed traffic later.23:12
SpamapSjimbaker: http://dev2ops.org/storage/WallOfConfusion.png23:13
jimbakerSpamapS, yeah, that's a good one for scenarios like this23:13
SpamapSnegronjl: I *love* that the heavy lifting is all done in debconf23:13
negronjlSpamapS:  we have iamfuzz to thank for that :)23:15
SpamapSjimbaker: Maybe if the agents didn't log this *by default* (they seem to log at DEBUG level right now) I'd be more inclined to support it.23:15
SpamapSnegronjl: so why aren't these in the Ubuntu archive?23:16
jimbakerSpamapS, for stuff like that it's just a matter of choosing appropriate levels and handlers23:16
negronjlSpamapS:  they currently depend on [sun|oracle]-java23:16
negronjlSpamAps:  currently working with cloudera to fully support openjdk23:16
SpamapSnegronjl: multiverse would allow for that23:16
jimbakerSpamapS, so we could simply have the policy that debug-log captures debug, but the default level is INFO or higher, something like that23:17
negronjlSpamapS:  I think it's going into partner but, I'm not sure.23:17
SpamapSjimbaker: Right. the problem is that i'm fairly certain I have no way of changing the debug log because of the way unit agents are started. ;)23:17
SpamapSnegronjl: partner has the added benefit of being turned on by default. :)23:18
negronjlSpamapS:  true that :)23:18
SpamapSnegronjl: ok, so people "upload" stuff to these as jars. Is there a standard way to do that?23:18
jimbakerSpamapS, i need to run, ttyl23:19
SpamapSlike, WebDAV, scp, ftp?23:19
negronjlSpamapS:  not really...you have to create a directory then, change permissions, then change user, then ( and only then ) run your "job"23:19
negronjlSpamapS:  normally I have done it using scp23:19
negronjlSpamapS: and ssh23:19
SpamapSnegronjl: Ok, because thats what the master should end up "providing"23:19
SpamapSlooks like there's a website too23:19
SpamapSnegronjl: so provides website: interface: http .. and then just set the hostname / port.23:21
negronjlSpamapS:  The master has two websites23:24
negronjlSpamapS:  one on port 50030 and another one ( for a different purpose but just as important ) on port 5007023:24
negronjlSpamapS:  so, so far your suggestion is for the slave to provide hadoop-master and for the master to provide website: interface http ?23:25
negronjlSpamapS: If so, can I provide both pages (50030 and 5070)?23:26
SpamapSnegronjl: you don't have to call it 'website'23:30
SpamapSnegronjl: you can do 'website-foo' and 'website-bar'23:30
SpamapSnegronjl: what are the two ports' purposes?23:31
SpamapSnegronjl: the slave should provide hadoop-slave .. the master should require hadoop-slave, and provide those two websites.23:31
niemeyerSpamapS: If the protocol is the same, both interfaces should be named the same way23:31
SpamapSniemeyer: same interface, different relation name23:32
niemeyerSpamapS: Right23:32
niemeyerSpamapS: The interface should be "website", right?23:32
niemeyerSpamapS: That's what we agreed yesterday, at least23:32
SpamapShttp://paste.ubuntu.com/628196/23:33
SpamapSthe interface is just http23:33
SpamapSOr did I forget something?23:33
niemeyerSpamapS: Yesterday we agreed to use 'website' as the interface23:33
SpamapSOh23:33
SpamapSfor what exactly?23:34
niemeyerSpamapS: For an interface which had only "url" as a relation setting23:34
SpamapSOh, I wasn't part of that discussion. Interesting.23:35
m_31do we want to separate out DFS-type services from mapreduce-type services? 23:36
m_31or interpret "website" as "webservice"23:36
SpamapSMakes a lot of sense tho. I like the idea of specifying the actual protocol though. Some url handlers don't handle FTP...23:36
niemeyerSpamapS: You actually were part of it23:37
niemeyerSpamapS: We just didn't understand each other23:37
niemeyerSpamapS: I think "http" is too much detail about what the service provides23:38
niemeyerSpamapS: Most clients that support "http" will also support "https"23:38
SpamapSYeah that I recall23:38
SpamapSI didn't remember that we had settled on URL, but I do like it. 23:38
niemeyerSpamapS: So "website" feels like a good name for a user-oriented view that can be both http or https in a "url" setting23:38
niemeyerSpamapS: That reminds me, we need to put these in the wiki23:39
SpamapSI'd almost say that interface should actually be called "url" .. the website name is just a standard convention for relation name I've been using for web apps.23:39
niemeyerSpamapS: https://ensemble.ubuntu.com/Interface/<name>23:39
niemeyer?23:39
niemeyerSpamapS: That may be too much23:39
niemeyerSpamapS: "url" could be "mongodb://..."23:39
niemeyerSpamapS: To make sense it needs some additional sense to make auto-resolving work23:40
SpamapSyeah website at least implies "web"23:40
niemeyerSpamapS: "website" provides the semantic meaning, without binding to the specific protocol23:40
SpamapSFor the interface docs.. I've been thinking about it too. I was trying to think if there's a way we can express it with a testing framework that could actually verify if something that says it "provides" "website" does.23:41
niemeyerSpamapS: That's pretty interesting.. I think we can do something about that23:42
SpamapSniemeyer: one reason I've been doing http specifically is that haproxy and IPVS don't care about urls.. they care about host and port only.23:42
niemeyerSpamapS: Well.. they do care about whether it's http or not, IIRC23:43
niemeyerSpamapS: haproxy, at least23:43
SpamapSbut I suppose I can just parse that out relatively easily.23:43
niemeyerSpamapS: Agreed23:43
SpamapSurl, and 'check_url' would be a good optional thing to be able to set.. so that load balancers know the specific url to hit for health checking.23:44
niemeyerSpamapS: Definitely.. the interface page in the wiki could document optional settings as well 23:45
SpamapSniemeyer: I'd like to have the interface docs in revision control.. not sure if the wiki's history is enough.23:46
SpamapSso maybe .rst for the interfaces23:47
niemeyerSpamapS: Hmm23:47
niemeyerSpamapS: I thought about the wiki to more easily allow the community to contribute/debate23:48
SpamapSYeah.. I can see both sides.23:52
SpamapSI think as long as we point to one as "the canonical source of documentation for that interface", it will work.23:53
SpamapSJust feels like .rst would be more authoritative.23:53
SpamapSat the expense of community members needing to jump through more hoops to document their interfaces.23:53
niemeyerSpamapS: Sounds good to me23:56
niemeyerSpamapS: We should go with whatever you feel most comfortable with23:57
niemeyerSpamapS: and we can change, of course23:57
niemeyerSpamapS: But this is an area that will need your attention for sure23:57

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