farid | empanada: nice | 01:00 |
---|---|---|
farid | can have just sombrero fridays and call it done | 01:00 |
empanada | farid \o/ | 01:00 |
empanada | great idea | 01:00 |
*** Syed__ has quit IRC | 01:25 | |
*** valw has joined #craton | 01:48 | |
*** valw has quit IRC | 01:52 | |
*** VW has joined #craton | 02:52 | |
*** VW has quit IRC | 02:56 | |
*** VW has joined #craton | 03:17 | |
*** VW has quit IRC | 04:05 | |
*** VW has joined #craton | 04:05 | |
*** valw has joined #craton | 04:46 | |
*** valw has quit IRC | 05:12 | |
*** VW has quit IRC | 05:13 | |
jimbaker | sulo, https://review.openstack.org/#/c/427032/ hopefully is all *set* for you to *get* (terrible attempt at humor about this ;) | 05:59 |
jimbaker | one other thing - i briefly worked on getting deletion working; plus having names work in addition to IDs to improve ergonomics. but not enough time. maybe thurs? :) | 05:59 |
jimbaker | but the usual overrides, etc, work. so it's pretty nice in that way | 06:00 |
jimbaker | also need to fix up PEP8 and some unit tests. btw, i also fixed `craton host-list` (and cells) so that it doesn't require region to be specified; and the region id is now listed. which broke at least some of the unit tests. pretty minors, but may want to separate in a different change | 06:04 |
*** valw has joined #craton | 07:12 | |
*** jimbaker has quit IRC | 07:16 | |
*** valw has quit IRC | 07:17 | |
*** jimbaker has joined #craton | 07:19 | |
*** jimbaker is now known as Guest43455 | 07:19 | |
*** valw has joined #craton | 08:14 | |
*** valw has quit IRC | 08:18 | |
*** valw has joined #craton | 12:15 | |
*** valw has quit IRC | 12:20 | |
*** VW has joined #craton | 12:45 | |
Guest43455 | sulo, were you able to try out https://review.openstack.org/#/c/427032/ ? | 13:05 |
Guest43455 | (nice, nick problem, one moment) | 13:05 |
*** Guest43455 is now known as jimbaker | 13:06 | |
*** jimbaker has quit IRC | 13:06 | |
*** jimbaker has joined #craton | 13:06 | |
*** ChanServ sets mode: +o jimbaker | 13:06 | |
jimbaker | sulo, ok, that is better | 13:06 |
*** VW has quit IRC | 13:25 | |
tojuvone | Hi Cratoners. Is there a demo today? | 13:26 |
jimbaker | tojuvone, yes. at the usual time | 13:27 |
jimbaker | in terms of our tues meeting | 13:28 |
tojuvone | jimbaker, Great :) | 13:28 |
sulo | jimbaker: i have not yet, i am still working on network cli stuff | 13:28 |
jimbaker | sulo, no worrie | 13:28 |
sulo | will be trying it out shortly though | 13:29 |
jimbaker | i'm fixing up that WIP change so it passes the gates | 13:29 |
sulo | cool .. lets get it merged in | 13:30 |
jimbaker | also i will see about fixing the column reordering problem with pretty printing. not certain if you have noticed, but host-list etc reorders columns on every pass. at least on python35 | 13:30 |
sulo | yeah i have | 13:30 |
jimbaker | sulo, i don't think it can be merged in as is | 13:30 |
sulo | k | 13:31 |
jimbaker | but soon | 13:31 |
jimbaker | certainly this week | 13:31 |
*** valw has joined #craton | 13:48 | |
*** valw_ has joined #craton | 13:57 | |
*** valw has quit IRC | 13:59 | |
jimbaker | sulo, updated patch. there was a missing file. and it now works on 2.7, without extraneous prints | 14:19 |
jimbaker | all gates currently pass, except pep8 | 14:19 |
jimbaker | (just missing doc strings, will do another pass to get those) | 14:20 |
jimbaker | also the included CLI snippet in the commit message for the review is executable as-is, assuming the usual fake data has been generated | 14:20 |
*** valw_ has quit IRC | 14:23 | |
*** VW has joined #craton | 14:34 | |
*** valw has joined #craton | 14:41 | |
sulo | jimbaker: ok i have uploaded the network-X commands cli | 15:20 |
jimbaker | sulo, cool, i will check out | 15:20 |
sulo | those 3 patches needs to merge with your patch for the demo | 15:20 |
jimbaker | sulo, should we just do this via gerrit dependencies? | 15:21 |
jimbaker | maybe have a patch that depends on all 4 in gerrit? | 15:21 |
jimbaker | just to simplify mgmt | 15:21 |
sulo | well my patches have a dependency chain. | 15:22 |
sulo | networks -> net device -> net interface | 15:22 |
jimbaker | ok, then half the battle | 15:22 |
jimbaker | have you tried out the vars commands yet? | 15:22 |
sulo | nope i cant get all these patches to merge locally | 15:23 |
jimbaker | ah, ok | 15:23 |
jimbaker | then let me try | 15:23 |
sulo | oh i think i was making it too complicated ... | 15:25 |
sulo | simply git pull worked on top of my last commit | 15:25 |
jimbaker | sulo, here are my notes on some additional cli/client stuff we need to fix - fix arbitrary (2.7)/randomized (3.5) sort order of <resource>-list; delete variables; parent/children; labels; --format=json | 15:25 |
jimbaker | could be worthy things for thomasem to look at as well | 15:26 |
jimbaker | a couple of these have reported bugs, others need to do so | 15:27 |
jimbaker | or rather, have such bugs reported | 15:27 |
*** valw has quit IRC | 15:27 | |
sulo | jimbaker: ok the vars stuff works nicely | 15:28 |
jimbaker | thanks! | 15:28 |
sulo | jimbaker: https://gist.github.com/sulochan/beb26f68a3846458ae33d4bc91fa5f03 | 15:30 |
sulo | vars and network commands | 15:30 |
jimbaker | now we just need to add vars to network resources! but not before the demo, it's good enough | 15:30 |
*** valw has joined #craton | 15:31 | |
sulo | yes one of them have it .. need to add it to network-interface | 15:31 |
sulo | and net-devices | 15:31 |
sulo | there is actually a bug right now due to this in craton | 15:32 |
jimbaker | although i suppose a combo patch that combines would be easy enough to do. probably no more than 30 min to actually implement, given the VariableMixin | 15:32 |
sulo | i have local fix that makes it work | 15:32 |
sulo | yeah | 15:32 |
jimbaker | sulo, ahh, for rest api support for those resources? | 15:32 |
sulo | yeah | 15:32 |
sulo | but they are one line changes | 15:32 |
jimbaker | got it. they have been that, haven't they? :) | 15:33 |
jimbaker | the "almost works" because so much is tested. but not a critical end-to-end aspect | 15:33 |
sulo | yeah | 15:33 |
sulo | i dont have func tests for networks yet | 15:33 |
sulo | so didnt catch faults there | 15:33 |
jimbaker | right | 15:34 |
sulo | the cli is not perfect yet | 15:34 |
sulo | need to circle back maybe later today after the demo and stuff | 15:34 |
jimbaker | and we will want to finally get integration testing going against cli/client with service | 15:34 |
jimbaker | now that the functional testing stuff gives us the appropriate framework to build upon | 15:34 |
sulo | but need to get this sorted today/tomorrow ... there are a few things we need to add for Thursday | 15:35 |
jimbaker | right | 15:35 |
sulo | jimbaker: we need to put --format=json for all cli commands :) | 15:37 |
jimbaker | sulo, yes, we most certainly do | 15:54 |
jimbaker | and generalize accordingly | 15:54 |
*** VW has quit IRC | 15:56 | |
jimbaker | sulo, yes, we most certainly do want --format=json for everything. let's get that done by thurs. should be easy to do in a general fashion | 15:56 |
jimbaker | may want to do a metadecorator to apply common options | 15:57 |
jimbaker | "metadecorator" :) | 15:57 |
jimbaker | also it would be nice to support csv, env, to avoid having to write complex pipelines with jq | 15:57 |
jimbaker | but json is most important | 15:57 |
*** VW has joined #craton | 16:01 | |
sulo | search by vars is broken :( | 16:03 |
jimbaker | in rest, or client/cli? | 16:04 |
sulo | api | 16:04 |
jimbaker | so that's a priority fix. plus functional testing to stay good | 16:05 |
*** VW has quit IRC | 16:05 | |
*** VW has joined #craton | 16:05 | |
jimbaker | also, hopefully impl this using json indexing on mysql | 16:05 |
jimbaker | i wonder when mysql will go out of preview | 16:06 |
jimbaker | mysql 8.0, that is | 16:06 |
sulo | jimbaker: so its weird, its half working https://gist.github.com/sulochan/72ae2206cbc58a14d618d9ed4fdd36e7 | 16:13 |
sulo | so a:x does not exist to its giving nothing back which is good | 16:13 |
sulo | but a:b should have only returned one region back.. its returning both | 16:14 |
*** klindgren_ has quit IRC | 16:14 | |
sulo | its almost like when the var key is present it doesnt care which id its for :? | 16:14 |
sulo | we havnet changed anything in models have we ? | 16:14 |
*** Syed__ has joined #craton | 16:15 | |
Syed__ | Hey everyone | 16:15 |
Syed__ | Can anyone kindly tell me when is the demo ? | 16:15 |
*** klindgren has joined #craton | 16:24 | |
thomasem | o/ | 16:27 |
thomasem | Syed__: in 30 minutes | 16:28 |
jimbaker | Syed__, we are having it during our usual 11a CT dev call | 16:28 |
Syed__ | Cool | 16:32 |
Syed__ | Thanks | 16:32 |
*** VW has quit IRC | 16:32 | |
thomasem | You bet! | 16:32 |
*** VW has joined #craton | 16:32 | |
thomasem | jimbaker: I'd be happy to look at any. Got links handy? I didn't see any that obviously relate in the launchpad bugs list. | 16:45 |
jimbaker | thomasem, i'm actually going through launchpad bugs because we need some cleanup there | 16:46 |
jimbaker | i will add accordingly | 16:46 |
jimbaker | but here's the first one for you: https://bugs.launchpad.net/craton/+bug/1648626 | 16:47 |
openstack | Launchpad bug 1648626 in craton "Projects should support variables, which other entities use in resolution" [Wishlist,New] | 16:47 |
thomasem | jimbaker: Thanks! I'll assign myself. | 16:47 |
jimbaker | thomasem, probably want to coordinate a bit with git-harry on the rest api aspects. i would hope that we can make the rest api addition of working with variables something that can be readily mixed in to any resource where it makes sense | 16:48 |
jimbaker | i have tried to do with the recent wip vars work on the cli/client side as well. it's also true of the data model | 16:49 |
jimbaker | already | 16:49 |
jimbaker | so the data model part is trivial. getting it end-to-end, some more work | 16:49 |
jimbaker | it will also be good guidance for similar work on mixing in scoped role assignments for rbac | 16:50 |
thomasem | Goootcha. Alright, I'll dig in. Out of curiosity, I was reviewing the functional tests patch. Would I be able to run functional tests after just pulling down the repo, or do I need to have an API/DB running for them to work? | 16:50 |
jimbaker | https://blueprints.launchpad.net/craton/+spec/craton-rbac-support | 16:50 |
jimbaker | thomasem, tox -e functional, assuming you have docker set up. you do have docker set up, right? ;) | 16:51 |
jimbaker | thomasem, fyi, tox -e functional only works on ubuntu for some reason | 16:51 |
thomasem | Depends on what you mean by having Docker set up? | 16:51 |
jimbaker | thomasem, just the basics, just the basic | 16:51 |
jimbaker | s | 16:51 |
jimbaker | ;) | 16:51 |
thomasem | I have a Docker daemon running. I set up a dev environment with a separate DB, network, and API service running. | 16:52 |
jimbaker | yep, that's what you want | 16:52 |
thomasem | Not the all-in-one thing from the Dockerfile yesterday | 16:52 |
jimbaker | so i run all three setups | 16:52 |
jimbaker | 1. tox -e functional. let sulo's good work on this, work for us | 16:52 |
jimbaker | 2. use the instructions in the dockerfile. useful for some basic debugging. i will post my slightly more robust gist of the command i run in a moment | 16:53 |
jimbaker | then i can use docker logs -f craton-api; docker exec -it craton-api mysql -ucraton -pcraton craton; docker exec -it craton-api bash, etc | 16:53 |
jimbaker | 3. run a complete setup. this is what i run if i'm hacking on the schema for example | 16:54 |
jimbaker | thomasem, we also need to run 4. an actual productized cluster | 16:54 |
jimbaker | new guy on the team, i wonder what he can work on? ;) | 16:54 |
thomasem | Filed this BP yesterdaym btw: https://blueprints.launchpad.net/craton/+spec/docker-compose-dev-environment | 16:54 |
thomasem | Yeah, got it. I didn't realize the tests and the all-in-one container were so coupled. | 16:55 |
jimbaker | thomasem, yeah, that BP looks awesome. very much related to #4 | 16:56 |
thomasem | So, that's where my confusion was. I wasn't sure if it was just set a couple vars and the tests will just work as long as they're pointed at the correct things. | 16:56 |
jimbaker | we certainly want to containerize the actual prod setup | 16:56 |
thomasem | Or if the tests made assumptions about the environment like that. | 16:56 |
jimbaker | thomasem, that Dockerfile is purely for testing | 16:56 |
thomasem | Gotcha | 16:56 |
jimbaker | i hope the use of password=craton etc makes that clear :) | 16:57 |
thomasem | Not really. Could be a little more explicit, lol. That could just as easily be simply a dev environment. | 16:57 |
thomasem | Or an example | 16:57 |
jimbaker | right, or for dev/example. just not for real usage | 16:58 |
thomasem | Yerp | 16:58 |
thomasem | Anyway. So, it sounds like set up using the checked-in Dockerfile and then run the functional tests (tox -e functional)? | 16:58 |
jimbaker | ok, not enough time to file more bugs | 16:58 |
jimbaker | thomasem, so tox -e functional iirc simply uses that top-level Dockerfile | 16:59 |
jimbaker | via docker-py | 16:59 |
thomasem | Interesting, it was bombing for me. I'll dig in a bit more in a bit. | 16:59 |
thomasem | After demo | 16:59 |
jimbaker | ok, meeting in 30 seconds everyone! | 16:59 |
thomasem | I was wanting to test the functional test patches you put up to review them. See y'all in Vidyo. | 16:59 |
*** VW has quit IRC | 17:00 | |
thomasem | Or that were put up, can't remember if that was specifically you. :) | 17:00 |
*** VW has joined #craton | 17:06 | |
*** valw has quit IRC | 17:08 | |
*** jovon has joined #craton | 17:09 | |
thomasem | Wonder if tox -e functional only works on Ubuntu because Docker for Mac wraps the daemon in a thin VM. | 18:00 |
sulo | yeah it probably wont work on mac | 18:00 |
thomasem | I'll file a bug to look at that. That's going to be a drag going forward, at least for me. | 18:01 |
sulo | but not sure ... i've always done it on my linux box | 18:01 |
sulo | ok | 18:01 |
thomasem | Yeah, I gotcha. Haha, I used to run a Linux box exclusively for work, but then... well, let's just say security cracked down and I lost the ability to do a lot of things since some tooling was fighting with Docker, like a lot. | 18:02 |
jimbaker | thomasem, awesome if you can get that to work. as for the other stuff, wfh can be nice :) | 18:02 |
sulo | i'd think it should work on mac as well actually | 18:02 |
sulo | docker on mac exposes docker api right | 18:03 |
sulo | and docker-py is simply talking to it | 18:03 |
thomasem | It does, but the IP is different. | 18:03 |
sulo | there maybe some catch on networking | 18:03 |
sulo | yeah | 18:03 |
thomasem | Yeah, the daemon runs in a thin VM (I forget the name of it) | 18:03 |
thomasem | and gets a separate network stack and such | 18:03 |
thomasem | Caused a ton of issues with Carina when we were getting CI/CD set up. | 18:03 |
thomasem | Especially because I developed the stuff on a Linux box, and it bombed when folks went to run it on their Macs. | 18:04 |
jimbaker | thomasem, please file a bug on mac tox -e functional, i don't think that has been done | 18:04 |
thomasem | jimbaker: will do! | 18:04 |
jimbaker | at least the usual dockerfile stuff works just fine on mac | 18:05 |
jimbaker | so it's probably something minor | 18:05 |
tojuvone | Thanks guys, nice demo :) | 18:05 |
thomasem | Yep, probably | 18:05 |
thomasem | It was just a bit of environment introspection to fix it for Carina, so, might be something similar here. | 18:06 |
thomasem | Not a biggie, just might look at it if I'm feeling especially productive on a Saturday or something | 18:06 |
thomasem | In the meantime, I suppose I'm going to spin up a separate Ubuntu box and forklift my configs over. | 18:07 |
*** VW has quit IRC | 18:07 | |
jimbaker | thomasem, https://gist.github.com/jimbaker/e74a7b98bc60519033fd455a22163ad2 is a robust version of what's in the Dockerfile for starting up a craton service, with fake data | 18:07 |
jimbaker | or reasonably robust | 18:07 |
thomasem | jimbaker: perfect. Thanks for the assist! | 18:08 |
jimbaker | tojuvone, thanks! hopefully you can see how we can start adding maintenance support | 18:08 |
tojuvone | jimbaker, yes, indeed. | 18:09 |
sulo | ok heading out for now | 18:09 |
thomasem | Cheers, sulo! | 18:09 |
jimbaker | i'm thinking that maybe we can use namespaces + json schemas to get this sort of functionality | 18:09 |
jimbaker | it would also help address what toan was asking about in terms of making it more robust in terms of what can be done (or not) | 18:09 |
jimbaker | so if a namespace could had some additional enforcements... that could be interesting | 18:10 |
jimbaker | eg, only valid transitions between states as recorded in variables in that namespace | 18:11 |
jimbaker | then add notifications on any variable change... | 18:11 |
tojuvone | yes | 18:11 |
jimbaker | which is the most important part of auditing | 18:11 |
jimbaker | for craton, that is | 18:12 |
tojuvone | build "own" logic specific to namespace | 18:12 |
jimbaker | exactly | 18:12 |
tojuvone | would it be to buidl some code with plugin mapping to that or something | 18:13 |
jimbaker | because this would just go through normal variables for the client, everything we showed today would just work with host-set-vars, etc | 18:13 |
jimbaker | $ craton host-set-vars my.host.example.com foo/baz=true | 18:14 |
jimbaker | so foo/ is the namespace | 18:14 |
tojuvone | ok, like that | 18:15 |
tojuvone | cool | 18:15 |
jimbaker | the only part that doesn't work on the client is the lookup for the host; but that's easy enough to fix and should this week | 18:15 |
*** VW has joined #craton | 18:15 | |
jimbaker | then on the service side, we add the namespace support, which can enforce, etc | 18:15 |
jimbaker | rbac will work on this, because it's just a variable. same with notifications. etc. | 18:16 |
jimbaker | with thomasem's work, this could be applied to the project. it would also work with regions, cells, now, and other types of resources as we add them | 18:17 |
jimbaker | with standard resolution/overrides applying of course | 18:17 |
tojuvone | ok. Yeah, availability zone was mentioned already as "grouping hosts". but there are other things coupling hosts to, like chaining services | 18:18 |
jimbaker | tojuvone, so we have labels for that | 18:18 |
jimbaker | but need to expose to cli/client. there is some support in the rest api, i need to double check how robust it actually is. in the python layer, it works great | 18:19 |
jimbaker | "python object model" layer, which is the craton.dbapi stuff | 18:19 |
*** VW has quit IRC | 18:20 | |
jimbaker | so far we have just needed minor fixups as we have been going through first functional testing (to doublecheck rest api); and then next, integration testing (to doublecheck pythonclient/cli against craton service) | 18:20 |
thomasem | Reading scrollback | 18:21 |
jimbaker | thomasem, assigned you more stuff ;) | 18:21 |
thomasem | lol | 18:21 |
jimbaker | nahh, just kidding | 18:21 |
thomasem | :P | 18:21 |
tojuvone | jimbaker, Ok. Thanks, I will see what learned today towards what I have thought at. | 18:22 |
jimbaker | tojuvone, right, very good brainstorming, based on toan's feedback | 18:26 |
jimbaker | i like simple, well rounded concepts. namespaces are starting to make sense | 18:26 |
jimbaker | need to open up a blueprint! | 18:26 |
jimbaker | we also need one for distributed consolidation | 18:26 |
jimbaker | not quite a warehouse | 18:27 |
jimbaker | oops, there is in fact one for that. but still needs revisiting: https://blueprints.launchpad.net/craton/+spec/craton-warehouse | 18:28 |
jimbaker | tojuvone, https://blueprints.launchpad.net/craton/+spec/craton-notifications | 18:31 |
jimbaker | tojuvone, https://blueprints.launchpad.net/craton/+spec/craton-namespaces | 18:42 |
*** VW has joined #craton | 18:43 | |
*** VW has quit IRC | 18:47 | |
tojuvone | jimbaker, Thanks, day started 5am is coming to an end 9pm. | 18:51 |
jimbaker | tojuvone, got it! please enjoy the rest of your evening :) and do get some rest! :) | 18:52 |
tojuvone | jimbaker, The CFP deadline also approaching, if we want to propose something together | 18:52 |
jimbaker | i also made an early start, but glad to do so | 18:52 |
jimbaker | tojuvone, yep, let's discuss further tomorrow. if not, we can bring this into an operator session instead. so at least 2 options | 18:52 |
tojuvone | jimbaker, yes, seen your last post in 8am my time | 18:52 |
jimbaker | also still need to figure out op summit | 18:52 |
tojuvone | yes | 18:53 |
jimbaker | yes, up late, up early | 18:53 |
jimbaker | what it takes | 18:53 |
jimbaker | ok, see you tomorrow! thanks again! | 18:53 |
tojuvone | jimbaker, Yep, have a good rest of the day! This was a great evening for me with the demo and all | 18:54 |
jimbaker | indeed, i'm quite happy how it went! lots of good discussion. and it all worked! | 18:55 |
*** VW has joined #craton | 18:55 | |
tojuvone | dome with effect, but no demo effect :) | 18:55 |
jimbaker | ;) | 18:56 |
tojuvone | dome = demo | 18:56 |
jimbaker | yep, humor still worked. we did have a couple of typos after all during the dome, but still worked just fine | 18:57 |
jimbaker | ;) | 18:58 |
jovon | as it relates to networks in our schema. what does "nss" stand for? | 19:45 |
*** valw has joined #craton | 20:31 | |
klindgren | nss is networks is usually "network segmentation size" or aka mtu. | 20:46 |
*** valw has quit IRC | 20:56 | |
*** rainya has joined #craton | 21:23 | |
*** valw has joined #craton | 21:30 | |
*** VW has quit IRC | 21:51 | |
*** VW has joined #craton | 21:51 | |
*** valw has quit IRC | 21:53 | |
*** VW has quit IRC | 21:55 | |
*** rainya has quit IRC | 21:57 | |
*** valw has joined #craton | 22:02 | |
*** VW has joined #craton | 22:03 | |
*** VW has quit IRC | 22:08 | |
*** VW has joined #craton | 22:09 | |
thomasem | Filed that bug regarding functional tests on OS X: https://bugs.launchpad.net/craton/+bug/1660827 | 22:20 |
openstack | Launchpad bug 1660827 in craton "functional tests fail on mac os x" [Undecided,New] | 22:20 |
thomasem | And set up a separate Ubuntu box for testing and am getting different errors there. Investigating... | 22:20 |
thomasem | Seems to be getting a 500 on container start... wonder if this is something to do with it being Docker 1.13.0? | 22:22 |
thomasem | docker.errors.APIError: 500 Server Error: Internal Server Error ("b'{"message":"oci runtime error: container_linux.go:247: starting container process caused \\"exec: \\\\\\"tools/docker_run.sh\\\\\\": permission denied\\"\\n"}'") | 22:22 |
thomasem | Hmmm, interesting | 22:22 |
thomasem | Ohhhhhhh, I think I know why. | 22:23 |
thomasem | my rsync probably didn't retain file permissions XD | 22:23 |
thomasem | lame | 22:23 |
thomasem | saddyface, okay. I'll fix this | 22:24 |
*** valw has quit IRC | 22:25 | |
jimbaker | no worries | 22:26 |
*** jovon has quit IRC | 22:50 | |
*** rainya has joined #craton | 23:12 | |
*** rainya_ has joined #craton | 23:14 | |
Syed__ | thomasem: is this bug for functional testing happening on OS-X ? | 23:14 |
Syed__ | thomasem: because i just checked with ubuntu and works fine with couple of failures because of regions | 23:14 |
*** rainya has quit IRC | 23:16 | |
*** VW_ has joined #craton | 23:46 | |
*** VW has quit IRC | 23:50 | |
*** VW_ has quit IRC | 23:51 |
Generated by irclog2html.py 2.14.0 by Marius Gedminas - find it at mg.pov.lt!