Friday, 2015-11-06

*** pratikmallya has joined #senlin00:11
*** Liuqing has joined #senlin00:43
*** Liuqing has quit IRC01:05
*** lvdongbing has joined #senlin01:05
openstackgerritjunxu proposed openstack/senlin: Fix spelling error for senlin.policy.deletion schema  https://review.openstack.org/24192201:07
*** xuhaiwei has joined #senlin01:11
*** Yanyanhu has joined #senlin01:12
*** pratikmallya has quit IRC01:30
*** Liuqing has joined #senlin01:30
*** elynn has joined #senlin01:30
*** yangyapeng has joined #senlin01:31
elynnmorning01:31
*** yangyapeng has quit IRC01:45
xuhaiweimorning01:49
*** zhenguo has joined #senlin01:50
*** pratikmallya has joined #senlin01:52
Liuqingmorning02:06
Liuqingxuhaiwei,Japan is a crazy country, but i like it..02:07
*** Yanyanhu has quit IRC02:08
*** Yanyanhu has joined #senlin02:10
xuhaiweiLiuqing, you felt good here?02:12
Liuqingno, it's a pity02:19
xuhaiwei:)02:20
*** ldb_ has joined #senlin02:49
*** lvdongbing has quit IRC02:51
*** rebase has quit IRC02:51
*** pratikmallya has quit IRC02:54
*** Yanyanhu has quit IRC03:19
*** rebase has joined #senlin03:19
*** Yanyanhu has joined #senlin03:26
*** Yanyanhu has quit IRC04:02
*** Yanyanhu has joined #senlin04:03
*** Liuqing has quit IRC05:05
*** Liuqing has joined #senlin05:07
*** lixinhui has joined #senlin05:26
*** pratikmallya has joined #senlin05:26
*** pratikmallya has quit IRC05:31
*** heyongli has joined #senlin05:40
*** heyongli has quit IRC05:44
*** heyongli has joined #senlin05:44
*** heyongli has quit IRC05:54
*** heyongli has joined #senlin05:55
*** heyongli has quit IRC06:05
*** heyongli has joined #senlin06:05
openstackgerritMerged openstack/senlin: Fix spelling error for senlin.policy.deletion schema  https://review.openstack.org/24192206:09
*** Qiming has joined #senlin06:12
*** heyongli has quit IRC06:15
*** heyongli has joined #senlin06:15
*** heyongli has quit IRC06:21
*** heyongli has joined #senlin06:21
*** heyongli has quit IRC06:25
*** heyongli has joined #senlin06:25
*** heyongli has quit IRC06:27
*** yonglihe has joined #senlin06:27
*** openstackgerrit has quit IRC06:31
*** openstackgerrit has joined #senlin06:32
*** yonglihe has quit IRC06:35
*** yonglihe has joined #senlin06:36
*** yonglihe has quit IRC06:46
*** yonglihe has joined #senlin06:46
*** yonglihe has quit IRC06:56
*** yonglihe has joined #senlin06:56
*** xuhaiwei has quit IRC07:04
*** xuhaiwei has joined #senlin07:05
*** yonglihe has quit IRC07:06
*** yonglihe has joined #senlin07:06
*** Liuqing has quit IRC07:10
*** Liuqing has joined #senlin07:11
*** yonglihe has quit IRC07:16
*** yonglihe has joined #senlin07:17
xuhaiweihi everyone, I have sent a mail to openstack-dev mailing list, that is about adding container type node, please feel free to comment on it07:26
*** yonglihe has quit IRC07:27
*** yonglihe has joined #senlin07:27
elynnlooking07:32
*** yonglihe has quit IRC07:37
*** yonglihe has joined #senlin07:37
Qimingcurious how magnum guys think about it07:45
Qiminganother way to tackle this is to have senlin invoke docker-py directly to create docker clusters07:45
xuhaiweiso in that way, what should be done in Senlin side?07:46
*** yonglihe has quit IRC07:47
*** yonglihe has joined #senlin07:47
elynnSeems k8s/swarm has their scaling functions, so this proposal means senlin will talk to k8s/swarm to do scaling?07:48
xuhaiweiyes, not talking to magnum07:49
Qimingk8s has proposals doing container layer scaling, so the feature is not there07:51
elynno?07:51
Qimingdocker swarm doesn't have scaling either I believe, but they claim it can be supported using swarm07:51
Qiminghttps://github.com/docker/swarm/issues/67607:52
Qimingthe issue 676 is talking about scaling machines though07:53
QimingI don't think we will take over the scaling of containers themselves07:53
Qimingk8s proposal is here: https://github.com/kubernetes/kubernetes/blob/release-1.0/docs/proposals/autoscaling.md07:55
elynnSo adding container support needs to wait for these features go into k8s/swarm?07:55
Qimingscaling interface is tracked here: https://github.com/kubernetes/kubernetes/issues/162907:56
xuhaiweiso how do you think senlin should do for support container auto-scaling?07:56
Qimingxuhaiwei, I don't think it is a wise move to compete with k8s/swarm directly on container scaling07:57
Qimingat the bare minimum, we are not there yet07:57
*** yonglihe has quit IRC07:57
Qiminghowever, if you were on the magnum-senlin talk, you will realize that what we proposed is a cross-layer interaction07:58
*** yonglihe has joined #senlin07:58
Qimingwe manage the nodes that are used for running containers07:58
Qiminglet the k8s/swarm do their own scaling of containers07:58
Qiminghowever, when the workload is high, adding more containers won't solve the problem07:59
Qimingwe will need to add new nodes (VMs or in future baremetals)07:59
Qimingthat is beyond k8s/swarm scope07:59
Qimingit falls in either magnum or senlin07:59
Qimingthere are guys from magnum (Ton Ngo, Hongbin Lu, Jay Lau) already signing on an autoscaler feature in magnum08:00
*** pratikmallya has joined #senlin08:00
Qimingin their proposal, senlin will be used as the engine I think08:00
xuhaiweiyou mean k8s or docker will use senlin to scale vm and then scale container on the vms?08:01
openstackgerritYanyan Hu proposed openstack/senlin: Update TODO/FEATURE item list  https://review.openstack.org/24076408:02
Qimingk8s/docker with do the container layer scaling by themselves08:02
Qimingwhen scaling the underlying VMs, that's senlin's job08:02
Qiminghttps://blueprints.launchpad.net/magnum/+spec/two-level-auto-scaling08:03
xuhaiweiwhat I am confuing is how does senlin communicate to k8s/docker? they call senlin or senlin calls them?08:05
Qimingmagnum calls senlin08:05
Qimingif senlin communicates directly to k8s/docker, senlin becomes another magnum08:06
Qimingwondering if that is a wise move either08:06
xuhaiweithat's true08:07
*** yonglihe has quit IRC08:08
QimingI have no problem with replacing magnum08:08
*** yonglihe has joined #senlin08:08
Qimingbut I believe a lot people are gonna challenging you that08:08
xuhaiweisince your words in the senlin design summit, I am always thinking about the posibility08:09
Qimingthe potential is there08:09
openstackgerritYanyan Hu proposed openstack/senlin: Update TODO/FEATURE item list  https://review.openstack.org/24076408:10
xuhaiweiso the use case demo you held in the summit is not the normal way magnum uses senlin?08:11
xuhaiweiin other words senlin should not do container auto-scaling08:11
xuhaiwei?08:11
Qimingyes, senlin is not gonna replace k8s08:12
Qimingk8s is already doing container scaling itself, so we don't have a play there, true?08:12
Qimingback to the discussion a few minutes ago08:13
Qimingwhen running containers on an openstack cloud08:13
Qimingthere are two layers of entities to be managed, right?08:13
Qimingthe first layer being the containers (or pods) managed by the COEs themselves08:14
Qimingthe second layer being the VMs that are nova servers08:14
xuhaiweiyes, should we push magnum to use senlin to do the second layer scaling?08:16
Qimingwe have been talking to them since Vancouver08:17
Qimingthey don't want to depend on a project on stackforge08:17
Qimingthat is the only concern08:17
*** yonglihe has quit IRC08:18
QimingTon Ngo helped brought up this issue again back in July/August during magnum mid-cycle meetup in CA08:18
Qimingthe feedback remains the same08:18
*** yonglihe has joined #senlin08:18
Qimingthis time in tokyo, the issue was raised again, and they are still watching senlin's progress into big tent08:19
xuhaiweiso after senlin got the openstack project title, we should try again08:19
Qimingit is not our job08:19
Qimingwe have a lot in our plates already, just look at the TODO.rst and FEATURES.rst08:19
Qimingwe would encourage magnum to do this08:19
Qimingafter all, senlin provides more flexible APIs for them to manage VM groups, why model that as a Heat stack anyway?08:20
Qimingmake senses to you?08:20
xuhaiweiyes, quite make sense08:22
Qimingone of the most dangerous states of a project is that it tries to be a little bit of everything08:22
Qimingto be honest, I'm seeing a lot of that happening again in some projects08:22
QimingI'm not naming a specific project, but I do see that project scope defined as this:08:26
xuhaiweiyes, got it08:27
Qimingfeature1, feature2, autoscaling, autohealing, monitoring, tosca-conformant, security, auditing, notification, ...08:28
*** yonglihe has quit IRC08:28
*** yonglihe has joined #senlin08:28
yuanyingo_o08:29
xuhaiweiseems many projects want to do autoscaling08:29
Qimingbasically, that project is closing its door to collaborate with others08:29
Qimingxuhaiwei, yep, it is about cloud elasticity08:30
Qimingwithout elasticity, you won't call a group of vms as a cloud08:30
xuhaiweiit snows heavily today in Beijing, do you have problems going home?08:30
Qimingseems it has stopped, won't be a big problem for me08:31
Yanyanhureally big snow08:31
openstackgerritjunxu proposed openstack/senlin: Fix cooldown_inprogress method return reversed values.  https://review.openstack.org/24238908:31
yuanyingI think, docker-swarm doesn't have auto-scale function, you think, swarm will support it?08:31
xuhaiweiI have to go to pick up my daughter now08:32
xuhaiweisee you guys, take care08:32
Qimingnot sure swarm will do it or not08:32
Yanyanhuxuhaiwei, see u08:32
Qimingimo, it should do, yuanying08:32
openstackgerritjunxu proposed openstack/senlin: Fix cooldown_inprogress method return reversed values.  https://review.openstack.org/24238908:33
QimingYanyanhu, in your latest revision, 'oslo.notification' item is gone?08:33
Yanyanhuyes, I think maybe it should be a part of queue/message trigger type support?08:33
QimingI'm not sure08:33
Qimingdon't make decisions this way08:33
Qimingmessage queue could mean zaqar specifically08:34
Qimingthat request was captured from ask.openstack.org, so it is a real requirement08:34
Yanyanhuoh, sorry, now trigger type, should be receiver type08:34
Qimingwe even don't have a receiver design at the moment08:35
Qimingwe will forget this option soon when we are working on some other more urgent patches08:35
Qimingto be honest, I'm not sure they can be combined into the same abstraction08:36
Yanyanhuhmm, that's true. Will we support the receiving of oslo.notification into the receiver design?08:36
Yanyanhuyes, that's my question08:36
QimingI don't want to get into that discussion at the moment08:36
Qimingour focus as the first step, is to have a receiver api that is general enough08:37
Yanyanhuok, I will keep this workitem and to see whether we can combine it work other jobs in future08:37
Qimingwhen we have bandwidth, we can always revisit this item08:37
Qimingyes, that is what I'm suggesting08:37
Qimingdon't throw away something we are not 100% sure yet08:38
openstackgerritjunxu proposed openstack/senlin: Fix cooldown_inprogress method return reversed values.  https://review.openstack.org/24238908:38
*** yonglihe has quit IRC08:38
Yanyanhuok, I see. Keep those things we are not clear in current stage. This is the principle08:38
Qimingright08:38
Qimingwe may have to postpone it forever08:39
Qimingthat is fine08:39
Qiming:)08:39
*** yonglihe has joined #senlin08:39
Yanyanhuunderstand08:39
openstackgerritEthan Lynn proposed openstack/python-senlinclient: Add get_file support for senlinclient  https://review.openstack.org/23959108:39
Qimingalso, CoreOS based container support08:42
Qimingplease keep it there08:42
Yanyanhuok, and also the container/docker cluster support?08:42
Qimingyes, maybe we can combine them later08:42
Yanyanhuok08:42
Qimingthe reason I'd prefer leave it there is that CoreOS is so special08:42
Qimingwe get container support for free08:42
Yanyanhuyes, that's true08:42
Qimingwe can have a special profile type for that08:42
Yanyanhudon't need extra service08:43
Qimingor at least an example08:43
Qimingbefore that happens, we may want to keep it in the list08:43
Yanyanhuok08:44
Qimingthe interaction with containers (so many types of them) is a big problem space08:45
Qimingwe may need some time to go through all potential approaches to make things work08:45
Qimingelynn, about #23959108:46
elynnHi Qiming08:46
Qimingalthough I can see get_file will work if we add a 'get_file' function08:47
QimingI'm still a little bit concerned about this approach08:47
Qimingactually, I dislike the approach in Heat08:47
Qimingit complicates the client code08:48
Qimingthe client side, IMO should not do this kind of parsing08:48
*** yonglihe has quit IRC08:48
*** yonglihe has joined #senlin08:49
Qiminghowever, we do need such kind of a functionality to include external files08:49
Qimingor else the readability of the profile may become terrible08:49
elynnyes, it's a compromise08:49
Qimingwhen I'm reviewing Yanyanhu's patch on TODO/FEATURE08:50
openstackgerritYanyan Hu proposed openstack/senlin: Update TODO/FEATURE item list  https://review.openstack.org/24076408:50
elynnTo be compatible with heatclient08:50
QimingI noticed that we have a todo item of adding support to 'template_url'08:50
elynnOtherwise heatclient can not collect all files that senlin needed.08:50
Qimingso I'm wondering whether it makes sense to explicitly spell it out in the profile what the value is08:51
Qimingtemplate_file: random_string_stack.yaml ?08:52
Qimingtemplate_url: http://server/stack.yaml ?08:52
openstackgerritYanyan Hu proposed openstack/senlin: Update TODO/FEATURE item list  https://review.openstack.org/24076408:52
Qimingugly, uh?08:52
elynnI don't get what you mean.08:53
QimingI was trying to get rid of 'get_file' function08:53
Qimingnot sure if it is a good idea though08:53
elynnyea, I don't think 'get_file' is a good idea, since without it senlinclient still works fine.08:55
elynnI'm thinking of an approach to support senlin resources in heat.08:55
Qiminga crazy but valid yaml I wrote before08:55
Qimingenv: &ENVIRON108:55
Qiming  parameters:08:55
Qiming    len: 1608:55
Qiming  profiles:08:55
Qiming    os.docker: some.path.docker.driver08:55
Qiming  # preserve newline08:55
Qiming  logo: |08:56
Qiming    .--  .--  . .  .    .   . .08:56
Qiming    |_   |--  |\|  |    |   |\|08:56
Qiming    __|  `--  . .  L__ _|_  . .08:56
Qiming  # don't preserve newline08:56
Qiming  description: >08:56
Qiming    Some description about08:56
Qiming    the usage of the stack08:56
Qiming    to be created08:56
Qiming      for example08:56
Qiming      this line08:56
Qiming    back to normal08:56
Qimingtype: os.heat.stack08:56
Qimingspec:08:56
Qiming  template: !include subdir/subdir/my_stack.yaml08:56
Qiming  environment: *ENVIRON108:56
elynnWow, this spec file include so much Logical Operators08:57
Qimingwas trying to teach myself some yaml basics08:57
*** yonglihe has quit IRC08:58
Qimingnot decent, ;)08:59
*** yonglihe has joined #senlin08:59
Qimingokay, let's go with get_file08:59
Qimingit won't be a surprise for existing heat users09:00
elynnBasically , https://review.openstack.org/239591 should work with https://review.openstack.org/#/c/240179/ , to collect all files that senlin needed files and reassemble profile spec.09:00
Qimingits use case is more than just include a YAML into your profile spec, it can be used for including a script I think09:00
QimingI see09:01
Qiminglet me try clear my mind a little bit09:01
elynnI think when we figure out how to go further in senlinclient , we can still have a chance to modify codes.09:01
Qimingyes09:02
Qimingwhen senlinclient sends a profile-create request09:02
Qimingthere should be no 'get_file' in that request, even the profile is about heat stack, right?09:02
elynnyes09:03
Qimingokay, let's keep this as principle 109:03
elynnheat resource will reassemble spec before send a request to senlin API09:03
Qimingpls hold that, it is an implementation specific thing09:04
Qimingwhen heatclient sends a stack-create request to heat server, the request should contain no 'get_file' key, right?09:04
Qimingor ... we are not sure about the second assumption?09:06
elynnIf without get_file support, the spec file pass to senlin resource should contain everything, like https://github.com/lynic/templates/blob/master/senlin/template/senlin-profile.yaml09:06
elynnstack-create request  will contain the get_file key09:07
Qimingokay, maybe I have got the point09:07
elynnheatclient can not remove get_file key in nested files.09:07
*** yonglihe has quit IRC09:07
Qimingsigh ...09:07
Qimingthat is what I hate heat's adhoc extensions09:07
Qimingback to interaction between heat and senlin09:08
elynnIt's the hard part to get these two clients consistent.09:08
Qimingwhen heat sends a profile-create request to senlin, can we avoid include a 'get_file' in that request?09:08
Qimingsince the profile is assembled from heat side09:09
Qimingmaybe that is doable?09:09
elynnyes, I need to write some codes in senlin resource to reassemble spec, and the requrest send to senlin will still like https://github.com/lynic/templates/blob/master/senlin/template/senlin-profile.yaml09:10
Qimingthat one looks good09:10
elynnI still need to convince heat community to let this patch https://review.openstack.org/#/c/240179/ get in after senlinclient support get_file.09:11
Qimingthe thing is whether we really want 'get_file' to appear in a request sent from heat to senlin09:12
*** Liuqing has quit IRC09:12
elynnfrom heat to senlin, get_file key will not present.09:12
Qimingif we can avoid that, we don't need to change senlinclient09:12
elynnIt will be handle by heat side.09:12
Qimingyes, then, let heat handle it09:13
elynnBut the spec used for heat will not be able to handle by senlinclient.09:13
elynnheat guys might say, hey, senlinclient don't support get_file, why do you want https://review.openstack.org/#/c/240179/ in.09:14
Qimingwait ...09:14
Qimingwhy this is getting so messy ...09:16
elynnLet me explain in paste.openstack.org...09:19
Qimingdoesn't matter09:20
QimingI will try understand this09:20
Qimingdon't want to waste your time09:21
Qimingback to the get_file function09:21
Qimingfor senlinclient09:21
Qimingmaybe it is a good thing to have it09:21
Qimingthe only concern I have is that we are again trapped by the heatclient problem ...09:22
elynnhttp://paste.openstack.org/show/478163/09:22
Qimingsuch a spec won't be usable in horizon09:22
elynnYes, heatclient has much traps in it.09:23
*** shu has joined #senlin09:24
Qimingso you understand my concern09:24
elynnOr we don't need to support get_file, totally use url instead.09:25
Qimingyep09:26
Qimingthe best thing about doing something from scratch is that we can revisit the existing design and see if there are room for improvement09:26
elynnThe spec pass to heat will look like http://paste.openstack.org/show/478164/09:27
elynnThen heat resource will try to download the template contents or directly pass this url to senlin and let senlin handle it.09:29
Yanyanhudon't support get_file means user has to put those files they want to use into a place that can be fetched through http request?09:30
Yanyanhulike github09:30
elynnyes, can't think of a better way...09:30
Yanyanhucould cause inconvenience in some cases I think...09:31
Yanyanhuso heatclient has problem about handling 'get_file' defined in nested stack?09:34
elynnNo09:35
Yanyanhunested template09:35
elynnheatclient will parse the yaml header, and only analyse the template with 'heat_template_version' key.09:35
elynna spec file doesn't have one.09:35
*** ldb_ has quit IRC09:36
elynnhttps://github.com/openstack/python-heatclient/blob/master/heatclient/common/template_format.py#L65-L6809:36
elynnSo heatclient will not retrieve the get_file in senlin spec file.09:36
elynnPatch https://review.openstack.org/#/c/240179/ removes that constraint, and let heatclient retrieve get_file's value in any yaml file.09:37
Qimingyes, I noticed that patch09:37
Qimingwe have to illustrate the use case09:38
YanyanhuI see, that's why steve baker said heatclient doesn't have responsibility to handle get_file in a spec which is not a 'heat templated'09:38
Yanyanhutemplate09:38
Qimingyes09:38
Qimingwe may have profile specs that are not heat templates send to heatclient09:39
Yanyanhuif we don't support get_file in senlin09:41
elynnSo what do you think? Get patch  https://review.openstack.org/#/c/240179/  land in heat or just support url instead of get_file?09:41
elynnDon't support get_file in senlinclient won't cause any problem.09:42
elynnJust the spec use for heat may not be supported by senlin.09:42
Qimingwe do support get_file in senlinclient09:43
elynnI hate get_file...sigh...09:43
Qimingthe implementation can be improved for sure09:44
QimingI think we need to dig a little more into the problem09:44
Qimingthere is no easy answer09:44
Qimingwe borrow the 'get_file' processing logic by invoking heatclient utils from senlinclient09:45
Yanyanhuok, I need to read the code to better understand it, I'm a little confused now...09:45
Qimingright, I'm having problem to draw the whole picture at the moment, will do so later09:45
elynnThe initial codes for senlin resources are upload to https://github.com/lynic/templates/tree/master/senlin/heat_resource, it won't need get_file support, feel free to try.09:46
Qimingokay, thanks, will do it09:46
Yanyanhume too :)09:47
Qimingoh, boy, you have profile and cluster all implemented?!!09:47
Yanyanhuand event asg :)09:47
Yanyanhueven09:48
elynnasg haven't implemented...09:49
elynnJust want to try, but got no time..09:49
QimingI see that is a clone of resource group09:49
elynnAnd not sure that handle_update for cluster is correct, still need more test.09:50
Qiminglooks like the logic is correct09:51
QimingYanyanhu, the client interface after revision works correctly now?09:52
Yanyanhuyes, I think so.09:53
Qimingso we are ready to bump the version09:53
Yanyanhuok09:53
*** zhenguo has quit IRC09:58
*** lixinhui has quit IRC10:01
openstackgerritQiming Teng proposed openstack/python-senlinclient: Remove unused methods in client module  https://review.openstack.org/24241510:01
*** Yanyanhu has quit IRC10:04
*** Qiming has quit IRC10:07
*** jdandrea has quit IRC10:15
*** Qiming has joined #senlin10:59
*** pratikmallya has quit IRC11:34
*** lixinhui has joined #senlin11:48
*** Liuqing has joined #senlin11:54
*** elynn has quit IRC12:20
*** Liuqing_ has joined #senlin13:28
*** Liuqing has quit IRC13:31
*** lkarm has joined #senlin13:44
*** lixinhui has quit IRC13:56
openstackgerritLiuqing Jing proposed openstack/senlin-dashboard: Add node detail test  https://review.openstack.org/24249214:08
*** pratikmallya has joined #senlin14:36
*** pratikma_ has joined #senlin14:59
*** jdandrea has joined #senlin14:59
*** pratikmallya has quit IRC15:01
*** Liuqing_ has quit IRC15:18
*** Qiming has quit IRC15:25
*** Liuqing has joined #senlin15:52
*** Liuqing has quit IRC15:55
*** pratikma_ has quit IRC16:07
*** pratikmallya has joined #senlin16:31
*** pratikma_ has joined #senlin16:39
*** pratikmallya has quit IRC16:39
*** pratikma_ is now known as pratikmallya16:43
*** pratikma_ has joined #senlin16:52
*** pratikmallya has quit IRC16:55
*** Jezogwza_ has joined #senlin17:36
*** lkarm has quit IRC17:50
*** lkarm has joined #senlin17:51
*** lkarm has quit IRC17:55
*** lkarm has joined #senlin18:00
*** lkarm has quit IRC18:29
*** lkarm has joined #senlin18:30
*** pratikma_ has quit IRC18:32
*** lkarm has quit IRC18:34
*** lkarm has joined #senlin18:47
*** pratikmallya has joined #senlin19:27
*** pratikma_ has joined #senlin19:29
*** pratikmallya has quit IRC19:32
*** pratikma_ has quit IRC19:53
*** pratikmallya has joined #senlin20:03
*** pratikma_ has joined #senlin20:05
*** pratikmallya has quit IRC20:08
*** openstackgerrit has quit IRC21:01
*** openstackgerrit has joined #senlin21:02
*** lkarm has quit IRC22:17
*** lkarm has joined #senlin22:18
*** lkarm has quit IRC22:22
*** pratikma_ has quit IRC22:22
*** pratikmallya has joined #senlin23:04
*** pratikmallya has quit IRC23:34

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