=== daker__ is now known as daker
_mup_ensemble/states-with-principals r308 committed by kapil.thangavelu@canonical.com00:16
_mup_agent tear down uses relies on base class for zk tree cleanup, also increase status test timeout for running with security00:16
=== otubo[AFK] is now known as otubo
=== otubo is now known as otubo[AFK]
=== daker_ is now known as daker
* hazmat yawns11:21
_mup_Bug #820892 was filed: machine_data is a formless blob <Ensemble:New> < https://launchpad.net/bugs/820892 >12:05
=== otubo[AFK] is now known as otubo
doitdistributedHi there13:25
doitdistributeddoes anybody know if ensemble only works with AWS so far? Or is it possible to use it with other providers as well13:26
fwereadedoitdistributed: we're working on orchestra support, to use it on bare metal with cobbler13:28
fwereadedoitdistributed: it's not ready for primetime yet, but we have a sprint next week and we hope to make some good progress there13:28
fwereadedoitdistributed: right now though, if you want to play with it, AWS is the way to go13:29
doitdistributedyes I'm already done ;-)13:29
doitdistributedI like it and as well the architectural concept13:29
fwereadedoitdistributed: cool, I hope it's working nicely for you :)13:29
fwereadedoitdistributed: awesome :D13:29
doitdistributedI try to figure out if it could be part of my Ph.D. thesis as well, but therefore the multicloud approach must be supported ;-)13:30
hazmatdoitdistributed, the ec2 api also works against openstack and eucalyptus for private cloud providers13:31
doitdistributedI think I will give an introduction about ensemble in the next AWS User Group meetup I'm hosting13:31
=== otubo is now known as otubo[AFK]
hazmatdoitdistributed, at the moment we don't support cross cloud communications 13:32
doitdistributed@hamat cool I will try it with EUCA13:32
hazmatfor a single environment13:32
doitdistributedand openstack13:32
hazmatdoitdistributed, cool, let us know if you have any issues13:32
fwereadehazmat: ha, yes, the API makes me think of them as basically AWS ;)13:32
doitdistributedI will give you a feedback and as well what the AWS Users think. 13:33
fwereadedoitdistributed: thanks very much!13:35
doitdistributedno problem ;-) 13:35
doitdistributedHey, are you interested in an article about Ubuntu Cloud or ensemble in our Cloud Computing magazine? 13:43
doitdistributedhere are the links http://issuu.com/symposiajournal13:44
doitdistributedI think it would fit good13:45
fwereadedoitdistributed: I bet we would be :)13:48
fwereadedoitdistributed: unhappily, my german was not very good 10 years ago, and is now almost gone, so I'm making only very slight sense of those pages ;)13:50
doitdistributed;-) No problem 13:50
doitdistributedmaybe we could refresh it sometimes with a beer or so13:51
fwereadedoitdistributed: I'd be delighted -- but I don't suppose you're in Malta? ;)13:55
doitdistributednot daily ;-)13:55
jcastrook everyone, here's the ensemble report for the week, I think I've covered most everything this week: http://pad.ubuntu.com/ensemble-report13:55
jcastroany feedback would be appreciated13:55
fwereadedoitdistributed: yeah, it's not exactly on the beaten track ;013:55
doitdistributedBut mayby there  http://cloud-devcon.com 13:56
fwereadedoitdistributed: hey, that looks cool13:57
doitdistributedYeah I'm one of the organizer 13:58
doitdistributedit will be a great event, with cool people, a big party and all inclusive13:58
fwereadedoitdistributed: awesome, I will try to figure out if I can make it, all I can remember is that my travel plans are confused for the next few months ;)13:59
fwereadejoining Canonical has been a bit of a shock to the system on that front ;)14:00
doitdistributedWould be great!!! And we could have a beer or two ;-)14:00
fwereadedoitdistributed: absolutely :)14:01
doitdistributedDo you think the price is ok? I mean we are new to the "business" and we want to make no business ;-) We only want cool events from the community to the community14:05
niemeyerHello Ensemblers!14:19
kirklandniemeyer: morning14:19
niemeyerkirkland: Yo14:19
=== otubo[AFK] is now known as otubo
RoAkSoAxfwereade: howdy!14:35
fwereadeRoAkSoAx: heyhey!14:35
RoAkSoAxfwereade: how's it going today?14:35
fwereadeniemeyer: and hey :)14:35
niemeyerfwereade, RoAkSoAx: Hey lads!14:35
fwereadeRoAkSoAx: good, I think, the structure for the shared shutdown stuff is on the tip of my tongue (fingers?)14:36
fwereadeRoAkSoAx: how about you?14:36
RoAkSoAxfwereade: go for it if your finger tips are itching :P14:37
fwereadeRoAkSoAx: I'm back in thinking mode, but I've got some stuff that looks very similar, it's just a matter of drawing the boundaries in the right place, and hoping it doesn't end up too baroque14:38
RoAkSoAxfwereade: well the shutdown stuff should be pretty simple14:39
RoAkSoAxfwereade: btw.. this would be the connect.py http://paste.ubuntu.com/658669/14:40
fwereadeRoAkSoAx: it is, the tricky bit is making that and the ec2 stuff work in the same way so we don't end up missing features on one side or the other14:40
RoAkSoAxfwereade: i'll take a look at it later today if you want and maybe I can contribute some more ideias on how to do it14:40
fwereadeRoAkSoAx: thanks :)14:40
RoAkSoAxfwereade: anywa,s  I have one question about the connect stuff, _wait_for_initialization that client.exists_and_watch("/initialized") where's that at? that's done by the zookeeper?14:41
fwereadeRoAkSoAx: I've got the impression that your additions to cobbler.py are pretty close to the ec2 interface, which is really handy14:41
fwereadeRoAkSoAx: my understanding is that when we initialise the admin, the last thing it does is create /initialized14:42
fwereadeRoAkSoAx: and so when that's there we the system is ready14:42
fwereadewe know^^^14:42
RoAkSoAxfwereade: ok, so that does not need to have any changes thne14:43
RoAkSoAxfwereade: as it should work exactly the same way as with ec214:43
fwereadeRoAkSoAx: yep, exactly14:43
RoAkSoAxfwereade: now, the only thing is that we cannot use _check_machine_age as it seems that machine.launch_time comes from ec2, correct?14:43
fwereadeRoAkSoAx: yeah, that's right14:43
RoAkSoAxfwereade: the only way we could provide that information would be to pass it the time on when the command was executed and *supposed* to launch a machine with orchestra14:44
RoAkSoAxfwereade: which might be suboptimal14:44
fwereadeRoAkSoAx: yeah, it doesn't feel right14:45
RoAkSoAxfwereade: alright, I guess i'll take note of this one too 14:46
RoAkSoAxfwereade: I think that in the future we'll have to make orchestra server (or cobbler) a bit smarter xD14:47
fwereadeRoAkSoAx: yeah definitely ;)14:47
RoAkSoAxfwereade: ok, so iterate.py, accessor.py and connect.py should be done14:49
RoAkSoAxfwereade: however, all of that needs to be tested with deploying machine14:49
RoAkSoAxfwereade: which is something i'm gonna work on next14:49
RoAkSoAxfwereade: after that I'll provide you with one branch for you to review, and start making smaller branches14:50
RoAkSoAxdoes that sounds good?14:50
fwereadeRoAkSoAx: cool, shadow-trunk should be up to date (including the stuff you wanted yesterday)14:50
fwereadeRoAkSoAx: sounds like a plan14:50
RoAkSoAxfwereade: yeah just pulled from there14:54
fwereadeniemeyer: how set in stone is the MachineProvider interface? I'd quite like to change shutdown and shutdown_machine15:02
niemeyerfwereade: Nothing is set on stone.. what would you like to achieve there?15:03
fwereadeniemeyer: I'm not totally sure yet... but it feels like shutdown_machines, taking a list of machines, is going to make everything else fit better15:03
fwereadeniemeyer: plain old shutdown would actually be unchanged, it's just get all machines and pass them to shutdown_machines15:04
niemeyerfwereade: Sounds quite reasonable.. how do we have to change MachineProvider for that?15:05
fwereadeniemeyer: those are part of MachineProvidr's interface15:06
fwereadeniemeyer: I'll experiment, hopefully I'll have something to show soon15:07
niemeyerfwereade: Wait.. duh, ok15:07
niemeyerfwereade: Yeah, happy with that15:07
niemeyerfwereade: When you said MachineProvider, in my mind I thought about the Machine interface itself15:08
niemeyerMy bad15:08
fwereadeniemeyer: no worries :)15:08
_mup_ensemble/states-with-principals r309 committed by kapil.thangavelu@canonical.com15:10
_mup_add another security check around removing units, fix an old service test that running (missing inlinecallbacks)15:10
=== daker is now known as daker_
_mup_ensemble/states-with-principals r310 committed by kapil.thangavelu@canonical.com15:54
_mup_subsume some of the module level helper functions into the security adapter class.15:54
hazmatbcsaller, niemeyer, fwereade team meeting in a few minutes15:55
bcsalleryep :)15:55
niemeyerOuch.. forgot to have lunch15:56
fwereadeis that google+ then?16:01
niemeyerOkay, is it time?16:03
* niemeyer starts a hang out16:03
niemeyerfwereade: Just invited you16:04
niemeyerbcsaller: and you16:04
niemeyerhazmat: and you16:04
fwereadelater all16:55
_mup_ensemble/states-with-principals r311 committed by kapil.thangavelu@canonical.com17:09
_mup_move otp consumption onto the security adapter.17:09
niemeyerLunch time.. biab17:10
_mup_ensemble/states-with-principals r312 committed by kapil.thangavelu@canonical.com17:17
_mup_remove an unused group api method, move some otp helper api implementation from its class to the security adapter.17:17
_mup_ensemble/states-with-principals r313 committed by kapil.thangavelu@canonical.com17:22
_mup_additional test for ACL grants multiple times against the same node version.17:22
_mup_ensemble/states-with-principals r314 committed by kapil.thangavelu@canonical.com17:56
_mup_add an environment variable to allow for testing the entire system with security enabled, security integration with relation state creation.17:56
_mup_ensemble/trunk-merge r274 committed by kapil.thangavelu@canonical.com18:19
_mup_merge trunk18:19
niemeyerMan.. open source is truly awesome..18:25
niemeyerI can't emphasize that enough18:25
niemeyerfeedbooks.net is using mgo to serve all of their book covers, in production, today.18:26
niemeyerfeedbooks.com, sorry18:26
niemeyerI feel more confident our repository will work fine with it now.. ;-)18:27
_mup_Bug #821074 was filed: security integration, sequence nodes or topology dependencies require explicit acl application, otp principal integration with state creation <Ensemble:In Progress by hazmat> < https://launchpad.net/bugs/821074 >18:29
niemeyerhazmat: Ugh.. 2.5k lines of diff18:56
hazmatniemeyer, ugh.. i forgot the prerequiste branch spec18:57
hazmatniemeyer, fixed, diffstat shows just under 700 lines18:59
niemeyerhazmat: Phew, that's awesome, thanks18:59
hazmatniemeyer, that should be the last/only large branch for the security work19:00
RoAkSoAxniemeyer: are there any more orchestra-related branches yet to be merged to trunk?19:12
niemeyerRoAkSoAx: There are19:12
_mup_ensemble/security-policy-rules r285 committed by kapil.thangavelu@canonical.com19:12
_mup_evaporate branch, to be resurrected latter in the pipeline.19:12
niemeyerRoAkSoAx: This should always provide a snapshot of what is going on: http://ensemble.ubuntu.com/kanban/dublin.html 19:13
RoAkSoAxniemeyer: ok, cool I was hoping to see ensemble deploying from trunk by tomorrow :)19:14
niemeyerRoAkSoAx: If you see branches from fwereade in the center column on in In Progress, there's likely something to be merged19:14
niemeyerRoAkSoAx: Sweet!19:14
niemeyerRoAkSoAx: I'm doing some spec writing ATM, but I hope to clean up that review queue by today still, so that William has it ready by the time he wakes up19:14
RoAkSoAxniemeyer: cool! I will submit my work to him for tomorrow when he wakes up to make sure is according to standards and then I guess those branches will be proposed for merging19:15
niemeyerRoAkSoAx: Woot19:15
RoAkSoAxniemeyer: cause I have it deploying already from shadow-trunk19:17
RoAkSoAxwhich is the branch I'm working on top of19:17
niemeyerRoAkSoAx: That's awesome news indeed!19:17
niemeyerRoAkSoAx: How's the Cobbler side of things?19:17
RoAkSoAxniemeyer: its good for now. there's some things that I'd like to discuss at the sprint to get the interaction improved19:18
niemeyerRoAkSoAx: Cool19:18
niemeyerRoAkSoAx: Do we have existing hacks still to be merged, or is that trunk interaction already working with stock Cobbler from Ubuntu?19:19
RoAkSoAxniemeyer: it is working with stock cobbler, but, there's some changes in preseeds and stuff like that yet to be merged into orchestra meta-package (probably orchestra-ensemble)19:20
RoAkSoAxniemeyer: that will land next week19:21
RoAkSoAxniemeyer: and autoconfiguration of a webdav server as well19:21
niemeyerRoAkSoAx: Aha, gotcha19:21
niemeyerRoAkSoAx: You rock dude19:21
RoAkSoAxall of that will be done in orchestra19:21
RoAkSoAxniemeyer: heh... thanks but SpamapS openned the door and fwereade did an awesome job witht he refactoring19:22
niemeyerRoAkSoAx: Yeah, other folks rock too :-)  We wouldn't be where we are without all of these fitting together.19:23
niemeyerAwesome team work19:23
niemeyersmoser should be in that list too19:24
niemeyerSpamapS, bcsaller, hazmat, RoAkSoAx, m_3, jcastro, all: Quick bikeshed19:25
niemeyerWe need a prefix for formulas in the repo..19:25
jcastrolike what, a designation that it's .... ?19:25
niemeyerI don't want to use lp: to avoid confusion between the formula namespaces and the branches19:25
RoAkSoAxniemeyer: indeed19:25
niemeyerWe need something like foo:oneiric/formula19:25
niemeyerWhat's "foo"?19:25
SpamapSensemble:oneiric/formula ?19:27
niemeyerensemble deploy ensemble:... doesn't look nice19:27
jcastroI was just thinking form, frm, or just formula19:27
niemeyerfrm.. hmmm19:27
SpamapSbeing palindromic.. I like recursion19:27
jcastrobecause that's what you're thinking in your head19:27
niemeyerfrm is nice19:27
jcastroensemble deploy $formula from $here19:27
SpamapSthis is the prefix that says "use the default repositories" ?19:27
niemeyerSpamapS: No, this is the prefix that says "this is about the repository"19:28
niemeyerrepo: might also apply19:28
niemeyer"frm".. "repo"...19:28
niemeyerWhat else?19:28
SpamapSso if its not there.. what do you get?19:28
RoAkSoAxefr =ensemble formula repository19:28
hazmatniemeyer, ensemble deploy ubuntu:xyz ?19:28
niemeyerSpamapS: We're sorting the naming convention only.. the spec with details is coming19:29
niemeyerhazmat: ubuntu..19:29
niemeyer"ubuntu", "frm", "repo", "efr"..19:29
RoAkSoAxniemeyer: i'd would agree with hazmat  too19:29
niemeyerAnything else?19:31
hazmatalthough perhaps that doesn't capture distro.. but it could be a nice symbolic for default distro latest and qualified with ubuntu:oneiric, ubuntu:natty etc19:31
SpamapSniemeyer: mmk. Given that limited context, repo seems generic and at the same time memorable enough.19:31
jcastro"forma" is latin for form.19:31
SpamapSubuntu: has special meaning in bzr now too.. its an alias for lp:ubuntu/19:31
niemeyer"ubuntu", "frm", "repo", "efr", "store"..19:31
niemeyerjcastro: Feels too close to formula.. reads like a typo almost19:32
niemeyer"fr", along the lines of RoAkSoAx suggestion (Formula Repository)19:32
jcastrorepo or store seems easiest to remember, we use "ubuntu" everywhere, so that might be confusing, frm and efr are just acronyms and would be harder to remember. 19:32
SpamapShave to step out for a bit, but repo: is, I think, my vote19:32
niemeyer"ubuntu", "frm", "repo", "efr", "fr", "store"..19:32
niemeyerSpamapS: Cool, thank you19:33
niemeyerI'll likely send this to the list19:33
* jcastro agrees with SpamapS for "repo", straight forward, easy to remember19:33
bcsallerwith a fallback to the environment?19:38
bcsallerre: the distro19:38
niemeyerbcsaller: Hm?19:39
bcsallerI was thinking about what hazmat was saying about ubuntu:natty or whatever, I don't know that you'd want that in the repo naming so much as in the environment you're deploying to 19:40
bcsallerbut using it the name of the package like in the email is fine 19:40
bcsallerwhen is it not this magic token?19:41
bcsallerwouldn't that be the only time we'd need it?19:41
bcsaller_:formula where _ is only needed when its not the default19:41
bcsallersurprised no on listed principia: as well19:42
niemeyerbcsaller: This is just about the prefix really.. the details semantics will be posted to review 19:42
jcastroI thought that name was going away19:42
bcsallerjcastro: I think you're right but I'm not sure19:43
jcastronor me19:43
niemeyerRight, principia is being debated.. principia may be finita19:43
niemeyerNone of us is sure, actually19:43
bcsallerniemeyer: I only mean we don't need a prefix for the default which is the place we are trying to name, its only when its not that default that you need a prefix, no?19:44
niemeyerIt's being debated by Elfos..19:44
niemeyerbcsaller: Maybe..19:45
niemeyerbcsaller: That's an interesting point19:45
bcsallerunless I misunderstand what the prefix is, I thought it was the mapping between a namespace of packages and the place to get them from, where you don't name the default 19:45
niemeyerbcsaller: ensemble deploy --repository=/tmp/oneiric deploy foo19:45
niemeyerbcsaller: Where does foo come from?19:45
bcsallerwhats now principa (or the default repo for your environment)19:46
bcsallerbut even in the case in ()'s its only named if you step away from the default19:46
niemeyerbcsaller: Ok.. another issue..19:46
niemeyerbcsaller: ensemble deploy ~bcsaller/foo19:47
niemeyerbcsaller: What does that do?19:47
bcsallerthrow an error, there is no package named that in the namespace19:47
bcsaller--repository is needed to specify a local repo path19:47
niemeyerbcsaller: Yeah, but I was actually talking about a remote formula19:48
niemeyerbcsaller: What does this do:  ensemble deploy repo:~bcsaller/foo19:48
niemeyerbcsaller: Quite obvious, right?19:48
niemeyerbcsaller: So you make an interesting point.. maybe we can get away with the prefix.. but there are a few problems which the prefix solves that I don't have a good answer for myself19:49
bcsallerno? I think it would be namespace:package where that a reference to a name mapping somewhere else like apt sources almost 19:49
bcsallerbcsaller lp:~bcsaller/ensemble in a config file19:50
niemeyerbcsaller: No?  You don't get the idea that repo:~bcsaller/wordpress is bcsaller's wordpress in the repo?19:50
bcsallerthen deploy bcsaller:foo19:50
bcsallerto me that assumes too much lp, but maybe I'm wrong there19:50
niemeyerMaybe.. hmm19:50
bcsallerbecause other SCM systems will still be mapped into lp on publish it could work, but I don't know if the best path fwd19:52
niemeyerI actually like the idea of oneiric/wordpress etc19:52
_mup_ensemble/states-with-principals r316 committed by kapil.thangavelu@canonical.com19:52
_mup_merge conflict from removal of security-policy-rules19:52
niemeyerI don't like joe:oneiric/wordpress too much, though19:52
niemeyerIt's conflicting..19:53
bcsallerhaving indirection there like I suggested in the namespace would create its own set of issues though, mostly that following instructions would be hard if people had different prefix names19:53
bcsallerI think what I just said kills the idea, its less repeatable 19:53
niemeyerYeah.. another issue is that everyone here knows what "bcsaller" is19:54
niemeyerWhat about19:54
niemeyerThat's not nice19:55
niemeyerThat's more obvious19:55
bcsalleryeah, I think the issue that repo: implies 1 to me was the issue19:56
bcsallerwhats the company local repo called that overlays the public one?19:56
niemeyerbcsaller: In which sense (implies 1)?19:57
bcsallerrepo always refers to lp, no?19:57
niemeyerbcsaller: No.. it refers to our repository system19:57
niemeyerbcsaller: It's not necessarily a 1-1 translation19:57
niemeyerbcsaller: Hmm19:58
bcsallerdirectly exposing lp names, but ok, I'll give you that 19:58
niemeyerbcsaller: Maybe we can break the proposal in half19:58
_mup_ensemble/security-policy-with-topology r317 committed by kapil.thangavelu@canonical.com19:58
niemeyeroneiric/wordpress, but personal:bcsaller/oneiric/wordpress19:58
_mup_policies with topologies19:58
niemeyerbcsaller: No, it's not directly exposing _lp_ names19:59
niemeyerbcsaller: It's not a 1-1 translation19:59
niemeyerbcsaller: Multiple repo names can refer to the same branch, for instance19:59
niemeyerbcsaller: The precise semantics will be in the spec, and will be up for debate19:59
bcsallerniemeyer: ok, I can see how that works, but what about the company local repo? It seems like there will be 'main', some companies collection and then maybe an developers private repo on top of that 20:00
_mup_Bug #821109 was filed: security policies need to have an accessor for topology and utilized with a modified topology <Ensemble:New> < https://launchpad.net/bugs/821109 >20:00
bcsallerit could be that those are merged under the repo: prefix by configuring access to that service though. just thinking out loud20:01
niemeyerbcsaller: Yeah, the companies collection can be put on a custom namespace20:01
niemeyerbcsaller: Maybe even referred to by URL20:01
bcsallerniemeyer: I know you have a plan for this, I don't mean to make you explain it all here 20:01
niemeyerbcsaller: Same way Bazaar enables lp: but full blown URLs too20:01
niemeyerbcsaller: Well, maybe I don't have a good plan yet..20:02
niemeyerbcsaller: What's your specific concern regarding company repos?20:03
niemeyerbcsaller: Seriously, I'm not being factitious20:03
bcsallerI just want it to be clear and convenient to specify that you want a more custom version from another repo than the one in main 20:04
niemeyerbcsaller: Just saying I'd like to debate semantics in the context of the spec, since there are more explanations written down, but still interested on your idea of why company prefixes are problematic20:04
niemeyerbcsaller: Cool, sounds good20:04
niemeyerbcsaller: Ok, thanks a lot20:07
niemeyerbcsaller: I think there's a very good middle path there that we can follow based on your idea of avoiding a prefix when feasible20:08
niemeyerbcsaller: Will try to put it down in the spec20:08
bcsallerniemeyer: happy to talk about it next week if you want20:08
niemeyerbcsaller: Absolutely20:09
_mup_ensemble/security-policy-rules-redux r317 committed by kapil.thangavelu@canonical.com20:18
_mup_resurrect security-policy-rules20:18
_mup_ensemble/security-policy-rules-redux r318 committed by kapil.thangavelu@canonical.com20:21
_mup_bring back some additional parts of security-policy-rules20:21
_mup_ensemble/security-policy-rules-redux r319 committed by kapil.thangavelu@canonical.com20:22
_mup_yank accidental add of merge file20:22
niemeyerbcsaller: Posted an answer in the list about the intermediate plan.. please let me know if it's along the lines of what you had in mind20:42
niemeyer(and solves the issues you've foreseen)20:42
bcsallerniemeyer: that looks good20:44
niemeyerI'm tempted to start s/repository/store/ too across the board.. such an easier word to speak about :)20:46
_mup_ensemble/security-agents-with-identity r301 committed by kapil.thangavelu@canonical.com20:57
_mup_provisioning agents launching machines with machine agent identities/principals20:57
niemeyerI feel like I'm writing a book..21:35
niemeyerMaybe I should start sending individual sections for review21:35
robbiewjcastro: ping21:45
jcastrorobbiew: pong21:45
_mup_ensemble/security-policy-rules-redux r320 committed by kapil.thangavelu@canonical.com21:53
_mup_resurrect policy w/ topology, got lost in the merge.21:53
=== otubo is now known as otubo[AFK]
_mup_ensemble/security-policy-rules-redux r321 committed by kapil.thangavelu@canonical.com22:17
_mup_update security rules to latest api.22:17
niemeyerOk, a couple of pieces pushed22:18
_mup_ensemble/security-policy-rules-redux r322 committed by kapil.thangavelu@canonical.com22:26
_mup_merge and resolve conflict.22:26
niemeyerWe need a review..22:37
niemeyerAnyone is up for it: https://code.launchpad.net/~fwereade/ensemble/webdav-storage22:37
niemeyerThat's the actual URL, actually22:38
_mup_ensemble/security-connection r289 committed by kapil.thangavelu@canonical.com23:01
_mup_address review comments [1][2]23:01

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