* davecheney waves at thumper | 00:14 | |
bigjools | arosales: hi | 00:18 |
---|---|---|
bigjools | what governs which tools get picked? | 00:24 |
bigjools | that's not provider-specific is it? | 00:24 |
davecheney | bigjools: it is and it isn't | 00:24 |
bigjools | helpful :) | 00:24 |
davecheney | the version is not provider specific, it is determined by the version rules we have | 00:24 |
davecheney | ie, if x.y.z, y % 2 == 0 then we'll look for stable tools with an exact match | 00:25 |
davecheney | if y % 2 != 0 then it's a devel version and we take the latest .z version | 00:25 |
davecheney | however there is a bigger problem | 00:25 |
davecheney | for each provider, there are two locations to look for tools | 00:26 |
bigjools | http://paste.ubuntu.com/6004647/ | 00:26 |
davecheney | the public (shared) bucket | 00:26 |
davecheney | and private (control) bucket | 00:26 |
davecheney | if no public bucket exists, or does not match the exct version for released tools | 00:26 |
davecheney | i *think* the current behavior is to invoke the juju sync-tools function | 00:26 |
davecheney | copy all the tools from the master bucket in s3 | 00:26 |
davecheney | into your private control bucket | 00:27 |
davecheney | this control bucket will be deleted when you destroy the environment | 00:27 |
bigjools | not sure I really understand tbh | 00:27 |
bigjools | my knowledge of the juju internals is pretty limited | 00:28 |
davecheney | bigjools: two secs, gotta hang out the washing | 00:29 |
davecheney | then I will return and regail you with tails of woe | 00:29 |
bigjools | hanging out the washing ... love it | 00:35 |
bigjools | we've not heavily tested (read: no testing) of using public tools with azure yet | 00:36 |
davecheney | bigjools: +1 for testing | 00:39 |
davecheney | bigjools: i'm probably wrong | 00:39 |
davecheney | but does azure have the concept of a public bucket ? | 00:39 |
bigjools | you can have public containers, if that's the same thing | 00:40 |
bigjools | but I don't think ec2's concepts map directly | 00:40 |
bigjools | nobody uploaded public tools to azure yet I guess | 00:42 |
davecheney | bigjools: nope, if | 00:42 |
davecheney | 1. we do that | 00:42 |
davecheney | 2. provide some sort of link to then in environments.yaml | 00:43 |
davecheney | this will solve the problem | 00:43 |
bigjools | there is config for it | 00:43 |
davecheney | bigjools: so I think what happens is | 00:43 |
davecheney | you manually download the tools from the s3 bucket | 00:44 |
davecheney | then manually upload them to the azure public bucket | 00:44 |
davecheney | you might be able to arrange you environments.yaml to be able to use sync-tools to automate this | 00:44 |
davecheney | wally/jam/gz could probably explain how to do this will less pain | 00:44 |
bigjools | there is no public Canonical storage account in Azure AFAIK | 00:45 |
* bigjools starting to understand | 00:45 | |
bigjools | there's config for public-storage-account-name and public-storage-container-name once tools are uploaded | 00:45 |
bigjools | who generally uploads new tools? | 00:47 |
davecheney | bigjools: unknown | 00:49 |
davecheney | it's handled very ad hockly | 00:49 |
bigjools | so when there's a new release, how does it work? | 00:50 |
davecheney | there is a vague requirement that 'tools should be uploaded as part of the release' | 00:50 |
davecheney | but that assumes I/we/someone knows where all the places tools sohuld be uploaded | 00:50 |
davecheney | at the moment it's just ec2 and hp cloud providers | 00:50 |
davecheney | if you're not one of those | 00:50 |
davecheney | you're probably on your own | 00:50 |
bigjools | \o/ | 00:50 |
davecheney | this is why wallyworld_ and I want to stop doing the public bucket | 00:50 |
davecheney | and distribute the tools as part of the client | 00:50 |
bigjools | well put it like this, we're no longer doing azure, so I don't think it's us who are on our own | 00:51 |
wallyworld_ | the simplestreams stuff i am working on will solve a lot of this | 00:51 |
bigjools | hey wallyworld_ how's the boat race? | 00:51 |
wallyworld_ | not too bad. still fucking ugly | 00:51 |
wallyworld_ | modern medicine isn't that advanced yet | 00:52 |
bigjools | the surgeon didn't give you chiselled good looks then | 00:52 |
wallyworld_ | nah, he said something about silk purse, sow's ear | 00:52 |
* davecheney hands out 'hoff masks | 00:52 | |
bigjools | wallyworld_, davecheney: I won't be around for the first day of the sprint, BTW. I have to drive to Maleny. | 00:52 |
davecheney | bigjools: ok, i don't know where maleny is | 00:53 |
davecheney | but it sounds like a long way | 00:53 |
bigjools | about 100km north | 00:53 |
wallyworld_ | it | 00:53 |
wallyworld_ | 's where he gets his weed from | 00:53 |
davecheney | bigjools: good, that means you won't be around to tell wallyworld_ and I to not drink wine | 00:53 |
bigjools | *cough* | 00:53 |
bigjools | I am sure you guys will cope | 00:53 |
davecheney | bigjools: it would be better if you could bring the choof on the first day | 00:54 |
davecheney | but we'll manage somehow | 00:54 |
wallyworld_ | i'll have to leave the hotel early most days to get my kid from school | 00:54 |
bigjools | he'll miss out on the evening festivities then | 00:54 |
wallyworld_ | i also have soccer in the evenings :-( except for tuesday | 00:55 |
* davecheney thinks this sprint is a wonderful use of our travel budget | 00:55 | |
bigjools | Just send them to the Candy Club | 00:55 |
axw | probably should've just left my induction till October :) | 00:56 |
davecheney | axw: it's not your fault | 00:56 |
davecheney | and waiting to october would be lame | 00:56 |
bigjools | yeah it's not nice to wait that long | 00:57 |
* bigjools not bitter | 00:57 | |
axw | wallyworld_: not sure if you've seen this yet: https://codereview.appspot.com/12926045/ | 01:10 |
wallyworld_ | i haven't will look | 01:10 |
axw | this fixes the all-machines.log spewing bug, but I don't quite understand why :) | 01:10 |
axw | thanks | 01:10 |
davecheney | axw: thanks, looking | 01:11 |
axw | I understand what that line does, but not why its omission would lead to repetition | 01:11 |
axw | davecheney: thanks | 01:11 |
wallyworld_ | axw: does this replace the other work that was done in the previous merge proposal? | 01:13 |
axw | wallyworld_: yes, that was all unnecessary. sorry, I totally misdiagnosed it | 01:13 |
axw | I scrapped that MP | 01:13 |
davecheney | if there are bugs that have been fixed, but not marked as 1.13.2 | 01:23 |
davecheney | https://launchpad.net/juju-core/+milestone/1.13.2 | 01:23 |
davecheney | could you please do so | 01:23 |
wallyworld_ | axw: i can't see why adding that break stops the repetition either, since the next rule doesn't match and there's so subsequent contents in the conf file. but if it works, why not i guess | 01:25 |
davecheney | wallyworld_: lets just hulk smash this fucker | 01:26 |
wallyworld_ | yeah, it seems it fixes the problem, and doesn't do any obvious harm | 01:27 |
axw | wallyworld_: ok. weird. perhaps an rsyslog bug | 01:27 |
wallyworld_ | maybe, who knows. or maybe i'm missing something obvious, which is more likely | 01:27 |
davecheney | why does juju wait til so late in the piece to tell me the env is already boostrapped | 02:19 |
davecheney | http://paste.ubuntu.com/6004960/ | 02:19 |
davecheney | especially after I have taken destructive action in the bucket | 02:19 |
sidnei | file a bug? | 02:20 |
davecheney | sidnei: there is already one one | 02:20 |
davecheney | open | 02:20 |
sidnei | cool, maybe noodles775 can take a look in the morning | 02:21 |
arosales | bigjools, back | 02:26 |
bigjools | arosales: hey | 02:26 |
bigjools | I commented on your bug | 02:26 |
bigjools | you need to use --upload-tools for now | 02:26 |
arosales | bigjools, davecheney I see you guys have had the juju release and tools discussion | 02:26 |
arosales | davecheney, I thought you volunteered to upload tools as part of the release process ;-) | 02:27 |
arosales | bigjools, so I can create a public container in Azure, no problem | 02:27 |
davecheney | arosales: yes sir i did | 02:27 |
davecheney | however you'll remember the caviet 'to all known clouds' | 02:27 |
bigjools | we don't have a tool to do that for azure yet | 02:27 |
davecheney | there is a potentially large set of unknown clouds | 02:28 |
* bigjools waits for the Donald Rumsfeld-like speech | 02:28 | |
arosales | davecheney, ah I was confused by: | 02:28 |
arosales | <bigjools> who generally uploads new tools? | 02:28 |
arosales | <davecheney> bigjools: unknown | 02:28 |
davecheney | bigjools: you are indeeed correct | 02:28 |
arosales | well lets just star with the clouds we know to work with juju atm | 02:29 |
bigjools | \o/ | 02:29 |
davecheney | arosales: the short answer is, i'll upload tools for clouds we know about | 02:29 |
davecheney | which now includes azure | 02:29 |
arosales | lets not solve all the worlds problems, just yet | 02:29 |
davecheney | (note, no credentials to do so btw) | 02:29 |
arosales | davecheney, ack on Azure, we just go the green light to go ahead an test | 02:29 |
bigjools | we need to create a storage account and container on Azure, for public juju tools | 02:29 |
davecheney | wallyworld_: is there any chance simple streams will save us from this pain ? | 02:30 |
davecheney | in the near term ? | 02:30 |
arosales | davecheney, I do think simple streams for juju tools solves the public bucket in all clouds issues | 02:30 |
davecheney | arosales: in what timeframe ? | 02:30 |
wallyworld_ | davecheney: i hope to have something done this week, maybe not for release. but CPCs should still have their own tools container | 02:30 |
arosales | at least just need to uploads tools to one place, and have juju look there | 02:30 |
arosales | time frame is dependent on juju-core and wallyworld_ | 02:31 |
wallyworld_ | arosales: and IS | 02:31 |
* davecheney ages | 02:31 | |
wallyworld_ | they are setting up the repository | 02:31 |
arosales | wallyworld_, have you filed an RT? | 02:31 |
wallyworld_ | arosales: yes, you were cc'ed on it :-) | 02:31 |
arosales | wallyworld_, cool I'll take you word for it. | 02:31 |
wallyworld_ | you didn't see any email? | 02:32 |
arosales | wallyworld_, CPCs need public buckets for faster boots? | 02:32 |
davecheney | arosales: they need it for any boot at all | 02:32 |
arosales | wallyworld_, I am just behind on my mail. | 02:32 |
arosales | davecheney, aside from why tools are needed | 02:32 |
arosales | why they need a local bucket | 02:32 |
wallyworld_ | arosales: yes, a CPC can mirror juju.canonical.com/tools for faster boot | 02:32 |
arosales | wallyworld_, so in theory they could go to juju.canonical.com | 02:33 |
wallyworld_ | once this stuff is done, there will be no need for a public bucket | 02:33 |
arosales | but that would require out of cloud access | 02:33 |
davecheney | arosales: not following your last comment | 02:33 |
wallyworld_ | arosales: yes, it requires out of cloud access. hence clouds should be able to mirror the tools | 02:33 |
wallyworld_ | if they don't want that | 02:33 |
arosales | wallyworld_, so we will still need a public bucket once simple streams is all done | 02:34 |
arosales | but that public bucket would just be a mirror of juju.canonical.com/tools | 02:34 |
arosales | davecheney, sorry I am just trying to get public bucket and simple streams straight in my head. | 02:35 |
arosales | bigjools, for azure in the near term (before simple streams is done) | 02:35 |
davecheney | arosales: i can't help with that :) | 02:35 |
davecheney | i don't have it straight in mine | 02:35 |
bigjools | arosales: --upload-tools is your friend for now | 02:36 |
arosales | bigjools, I can create an public container, but it seem uploading tools to a blob requires some azure api foo | 02:36 |
bigjools | arosales: you can use the web ui as well | 02:37 |
arosales | bigjools, really? | 02:37 |
bigjools | we have a command line tool but I am not sure of its state at the moment | 02:37 |
arosales | bigjools, I didn't find any way to upload a blob via the web, do you have a pointer? | 02:37 |
bigjools | oh wait you're right, you can only download .... gah | 02:37 |
bigjools | I have a tool to upload | 02:37 |
bigjools | as assuming you set up the container in the web ui, we can do it | 02:38 |
arosales | I got a container set up via the azure web ui | 02:38 |
arosales | bigjools, storage name = jujutools | 02:39 |
arosales | container name = juju-tools | 02:39 |
arosales | blobs endpoint http://jujutools.blob.core.windows.net/ | 02:40 |
* arosales not sure how to give access to write to it though . . . | 02:40 | |
bigjools | if you want me to upload something there for you, I need the storage key | 02:40 |
bigjools | you can get it from the management ui | 02:40 |
bigjools | PM it :) | 02:40 |
arosales | bigjools, ack | 02:40 |
davecheney | https://bugs.launchpad.net/juju-core/+bug/1214209 | 02:41 |
_mup_ | Bug #1214209: cmd/juju: add-machine should take a -n param <papercut> <juju-core:Triaged> <https://launchpad.net/bugs/1214209> | 02:41 |
bigjools | bugs with the would "should" in the title need to be instantly marked invalid | 02:41 |
bigjools | word* | 02:41 |
bigjools | can't type today | 02:41 |
davecheney | bigjools: i think you meant | 02:43 |
davecheney | bugs witht he word "should" in the title MUST been instantly marked invalid | 02:43 |
bigjools | you are possibly not wrong | 02:43 |
davecheney | bigjools: i can edit the titile if required | 02:44 |
wallyworld_ | arosales: sorry, was otp. each cpc would have a repository to mirror the tools, but it won't need to be configured as a public bucket in juju | 02:44 |
davecheney | arosales: public buckets in juju are really weird | 02:45 |
davecheney | they are a bastardised version of the private (control) bucket | 02:45 |
wallyworld_ | so no more of that public-bucket-url stuff needing to be configured in each client | 02:45 |
davecheney | so can't be shared across providers | 02:45 |
arosales | wallyworld_, and for cpc we should know what the public bucket is | 02:45 |
davecheney | arosales: why ? how would that information be used ? | 02:46 |
davecheney | axw: w1/0:config-changed % | 02:46 |
davecheney | ^ thanks | 02:46 |
davecheney | works well | 02:46 |
wallyworld_ | arosales: there will be a url used to access the tools, but it will be in the simple streams mirrors definitin, not in juju | 02:46 |
wallyworld_ | so users don't need to care | 02:46 |
axw | davecheney: cool. | 02:49 |
arosales | wallyworld_, so are you saying that juju tools simple stream definition will also list the known cpc public bucket/juju tool mirror locations? | 02:50 |
wallyworld_ | arosales: yes | 02:50 |
arosales | wallyworld_, ok, I think the light is slowly staring to turn on | 02:50 |
arosales | wallyworld_, so you still need info on where a particular cloud is housing the juju-tools, correct? | 02:51 |
wallyworld_ | you = juju folks maintaining the official tools repo | 02:52 |
wallyworld_ | not users | 02:52 |
arosales | correct | 02:52 |
davecheney | arosales: and the code to retrieve the tools from a bucket indicated by simple streams data is provider specific | 02:52 |
wallyworld_ | arosales: so, juju will look locally within a cloud first. failing that it will look at juju.canonical.com/tools and it can always get tools from there. but, if a mirror has been set up, the tools will be fetched locally | 02:52 |
arosales | wallyworld_, yes, sorry for not clarifying | 02:52 |
arosales | davecheney, agreed | 02:53 |
wallyworld_ | tgere will also be user config where a dev/user can set up their own tools | 02:53 |
wallyworld_ | and also their own image metadata | 02:53 |
wallyworld_ | so they can experiment/test etc | 02:53 |
arosales | wallyworld_, ack on the user config | 02:53 |
arosales | wallyworld_, when you say, " juju will look locally within a cloud first." | 02:53 |
arosales | we need to tell juju where to look locally first | 02:54 |
arosales | and that is specific for each cloud | 02:54 |
arosales | and I think we still need to set that up, correct | 02:54 |
wallyworld_ | arosales: for openstack, the cloud admin has the option of setting up keystone catalog items for the tools/image metadata | 02:54 |
wallyworld_ | so juju will look there | 02:54 |
wallyworld_ | but the end user doesn't know or care | 02:54 |
wallyworld_ | arosales: the keystone thing is how we make canonistack work for example | 02:55 |
wallyworld_ | it's not a cpc, but it just works regardless for users | 02:55 |
arosales | wallyworld_, given keystone is configured correct, and given it is an openstack cloud | 02:55 |
arosales | wallyworld_, but how would you handle say a joyent or azure cloud | 02:56 |
arosales | I am guessing we need to still tell juju where the local juju tools mirror is | 02:56 |
wallyworld_ | arosales: i'm not sure what facilities those have for a central config equivalent. but we will be introducing the idea of central, provider based config which will fill the gap there | 02:57 |
wallyworld_ | that last bit is still beig discussed | 02:57 |
wallyworld_ | as to how it will work | 02:57 |
wallyworld_ | arosales: but yes, in the short term, a url may well still be required for defining where local tools are | 02:58 |
wallyworld_ | the tools will always be available centrally | 02:58 |
wallyworld_ | from juju.canonical.com/tools | 02:58 |
arosales | wallyworld_, agreed | 02:58 |
wallyworld_ | for CPCs, no url though :-) | 02:59 |
arosales | I was just trying to tease out how you are handing non-openstack clouds that _need_ a local copy of the juju tools | 02:59 |
arosales | and how you make that just work for the user. | 02:59 |
wallyworld_ | sure, understood :-) | 02:59 |
arosales | sounds like that is still be in solved? | 02:59 |
arosales | wallyworld_, from what I can decipher I think canonical will still need to host a mirror of the juju tools for non-openstack based clouds. | 03:01 |
arosales | and then tell juju what that hosting location is, so juju can look there first before going to juju.canonical.com/tools | 03:01 |
wallyworld_ | arosales: yes, that's what juju.canonical.com/tools will be | 03:02 |
bigjools | ok where can I download the current tools | 03:02 |
arosales | bigjools, http://juju-dist.s3.amazonaws.com/ | 03:02 |
wallyworld_ | http://juju-dist.s3.amazonaws.com/tools | 03:02 |
arosales | wallyworld_, I think we went full circle | 03:03 |
arosales | wallyworld_, :-) | 03:03 |
wallyworld_ | lol, yeah | 03:03 |
arosales | wallyworld_, so ack on juju.c.c/tools being a central _out_ of cloud location | 03:03 |
wallyworld_ | yep | 03:04 |
wallyworld_ | out of cloud is the key. also, it will be master copy | 03:04 |
arosales | but, for Azure, canonical still needs to host a local mirror of the juju tools somplace | 03:04 |
arosales | local == in cloud | 03:04 |
wallyworld_ | within azure? | 03:04 |
arosales | correct | 03:04 |
wallyworld_ | yes, you are right. we do that for HP and AWS | 03:05 |
arosales | and when simple streams is all done and tidy | 03:05 |
wallyworld_ | that's where the mirror def will point to | 03:05 |
arosales | we will still need to host the juju tools mirrors in these locations | 03:05 |
wallyworld_ | yes | 03:05 |
arosales | and then tell juju what these locations are, correct? | 03:05 |
wallyworld_ | so, for hp for example, juju looks at juju.c.com/tools, see there's a local mirror on hp, and gets the tools from there | 03:06 |
wallyworld_ | it's the same public bucket as now | 03:06 |
wallyworld_ | but it's transparent | 03:06 |
arosales | gotcha | 03:06 |
arosales | but we specifically told juju what that public bucket is | 03:06 |
wallyworld_ | yes, in the mirror metadata | 03:07 |
wallyworld_ | but not in user env.yaml :-) | 03:07 |
arosales | agreed | 03:07 |
wallyworld_ | so we need to know, not the user \o/ | 03:07 |
arosales | so canonical still needs to setup and host a juju tools in Azure | 03:07 |
wallyworld_ | yeah | 03:07 |
arosales | and once we know what that is, the juju tools mirror metadata needs to know the location | 03:08 |
wallyworld_ | and allow for public access without credentials | 03:08 |
wallyworld_ | yes, we can update the mirror files | 03:08 |
arosales | wallyworld_, well any writing will needs creds | 03:08 |
wallyworld_ | yes | 03:08 |
wallyworld_ | sorry, i meant read access | 03:08 |
arosales | ack | 03:08 |
arosales | wallyworld_, so a lot of these buckets are a little ad hoc . . . | 03:09 |
arosales | wallyworld_, I would suggest that with the juju.c.c/tools RT | 03:09 |
arosales | we open up the conversation to IS maintaining these local _in cloud_ juju tools mirrors | 03:09 |
arosales | IS maintains the CPC mirrors, so perhaps also having a bucket/container in that mirror also host the juju tools mirror may be wise . . . | 03:10 |
wallyworld_ | agreed. the exact process still needs to be massaged. but yeah | 03:10 |
arosales | wallyworld_, also it sounds like we can change the _in cloud_ endpoint and it will be transparent to users | 03:11 |
wallyworld_ | yes indeed | 03:11 |
wallyworld_ | we still need to sort out signing though | 03:11 |
wallyworld_ | did i copy you on my email reply to (scott i think) on that topic? | 03:12 |
arosales | wallyworld_, you may have . . . . | 03:13 |
wallyworld_ | i basically think that signing right now is adhoc and needs to be centralised | 03:14 |
wallyworld_ | managed via a tool chain and not individually on laptops etc | 03:15 |
arosales | ah I think that was part of the "juju work" thread | 03:15 |
wallyworld_ | maybe, was more than a day ago so my fifo brain has wiped it :-) | 03:15 |
arosales | wallyworld_, btw I also see your RT 63925, for juju.c.c/tools | 03:16 |
wallyworld_ | cool | 03:16 |
arosales | wallyworld_, I just forgot :-/ | 03:16 |
wallyworld_ | np. happens to me all the time :-) | 03:16 |
arosales | wallyworld_, exactly on my fifo brain | 03:16 |
arosales | very limited queue | 03:16 |
wallyworld_ | lol | 03:16 |
wallyworld_ | yeah, me too | 03:17 |
arosales | wallyworld_, so I am going to work with bigjools on setting up a "public bucket" for Azure | 03:17 |
wallyworld_ | excellent | 03:17 |
wallyworld_ | bigjools *loves* Azure :-D | 03:17 |
arosales | I don't think it will be the final one, but I think it will be the one we use until we get an IS official solution. | 03:17 |
bigjools | fuck off | 03:17 |
arosales | lol | 03:17 |
bigjools | and when you get there, fuck off again :) | 03:18 |
wallyworld_ | arosales: right now, the mirrors work is still in review, and i need to do tools to generate the files etc. so there's work to do | 03:18 |
arosales | wallyworld_, once we have what the "public bucket" is we will let you know so you can tool juju tools metadata | 03:18 |
wallyworld_ | ok | 03:18 |
wallyworld_ | bigjools: ok, i've done that, twice. now what? | 03:19 |
arosales | wallyworld_, thanks for the explanation on juju-tools mirroring. I'll work to ensure CPC accounts for some sort of juju-tools _in cloud_ miroring of juju tools and let you know about it. | 03:20 |
wallyworld_ | arosales: np. i'm still in the middle of doing the code for it all. expect a better explanation when it's all done. it's very raw and a wip at the moment | 03:21 |
arosales | wallyworld_, no worries. I appreciate your time. I just want to make sure we have all the bits for Azure as it comes online | 03:21 |
wallyworld_ | understood. will be great to have it all working | 03:22 |
arosales | davecheney, I'll follow up with you on uploads once we know what that is for Azure | 03:22 |
wallyworld_ | bigjools says he want to help maintain it to, so keep him in the loop | 03:22 |
arosales | davecheney, did I miss any other of your questions? | 03:22 |
bigjools | wallyworld_ said he wanted a full run-down next week so he could understand everything to do with azure | 03:23 |
wallyworld_ | nooooooooo | 03:23 |
bigjools | it will be my duty to make sure he's fully up to speed | 03:23 |
* wallyworld_ just puffed on an exploding cigar | 03:23 | |
bigjools | is that a euphemism? | 03:36 |
wallyworld_ | you wish | 03:37 |
* thumper stabs the convuluted use of shit loads of structures in the juju codebase in the face and goes to make coffee | 03:48 | |
arosales | bigjools, 2nd failure on " no reachable servers" with, perhaps the 3rd time is the charm | 04:21 |
bigjools | wallyworld_: is your coffee machine fixed? | 04:53 |
wallyworld_ | bigjools: no :-( | 04:53 |
bigjools | wallyworld_: then I won;t tell you how nice this one is that I just made | 04:53 |
wallyworld_ | i can't have hot liquids for a few days anyway | 04:53 |
wallyworld_ | fo | 04:53 |
bigjools | can you have body temperature liquids? | 04:54 |
thumper | bigjools: you can tell me how good your coffee is and wallyworld_ will be forced to listen | 05:03 |
wallyworld_ | bigjools: you volunteering? | 05:04 |
bigjools | thumper: it is delicious. I was even thinking of wallyworld_ when I did a latte art penis | 05:04 |
thumper | I'm not very good at latte art | 05:04 |
bigjools | it's not hard to do a cock and balls, just ask wallyworld_ | 05:04 |
* thumper snorts | 05:05 | |
thumper | it is bloody hard to unpick the use of exported structures all over the show | 05:05 |
wallyworld_ | it's hard for bigjools to get them small enough if he wants to do a scale model of hos own | 05:05 |
thumper | I'm replacing agent.Conf with an interface | 05:05 |
thumper | oh, smack talk | 05:05 |
wallyworld_ | thumper: you have my pity. i wish we had used interfaces right from the word Go ha ha ha | 05:05 |
thumper | heh | 05:06 |
thumper | funny man | 05:06 |
wallyworld_ | instead of structs everywhere :-( | 05:06 |
thumper | we'd be in a better state if we did | 05:06 |
thumper | no pun intended there | 05:06 |
bigjools | wallyworld_: http://tinyurl.com/n2soctz | 05:06 |
* wallyworld_ nods sadly | 05:06 | |
thumper | as I think the "state" name and package is bollocks | 05:06 |
thumper | it is like having a package called "db" | 05:06 |
thumper | or "ui" | 05:06 |
wallyworld_ | lol. couldn't agree more | 05:07 |
thumper | big +1 though to the new "providers" package | 05:07 |
thumper | now if we could rename the interface | 05:07 |
wallyworld_ | except the name clashes | 05:07 |
wallyworld_ | with what providers will be in the future | 05:07 |
thumper | small steps | 05:08 |
wallyworld_ | sure, but we could have chosen a better name | 05:08 |
wallyworld_ | only do the rename once | 05:08 |
bigjools | wallyworld_: well I was thinking of taking you out for a coffee tomorrow but if you can;t have hot liquids.... | 05:08 |
wallyworld_ | bigjools: i'm sure i could manage a warm one | 05:09 |
bigjools | you could have breakfast with me and jen at the plum? | 05:09 |
wallyworld_ | what would doctors know anyway | 05:09 |
wallyworld_ | \o/ | 05:09 |
bigjools | heading there after school drop off | 05:09 |
bigjools | before I head into the cbd | 05:09 |
wallyworld_ | most excellent :-D | 05:09 |
wallyworld_ | ah yes, good luck with that | 05:09 |
bigjools | will get told how buggered I am | 05:10 |
wallyworld_ | hopefully no too much | 05:10 |
bigjools | hopefully | 05:10 |
bigjools | think I have made a connection - but ETOPIC | 05:10 |
bigjools | hey jam are you around yet? | 05:10 |
jam | bigjools: /wave | 05:10 |
jam | wallyworld_: good to see you around, I didn't think you'd be fully coherent today. | 05:11 |
wallyworld_ | jam: lots to do :-) | 05:11 |
bigjools | how would we tell the difference? | 05:11 |
wallyworld_ | http://tinyurl.com/n2soctz | 05:11 |
bigjools | ahahahaha | 05:11 |
bigjools | jam: hey man, I want to catch up on the tags work you did if you can spare ten minutes? | 05:11 |
jam | bigjools: yeah no problem | 05:14 |
jam | (just reading backlog right now) | 05:14 |
bigjools | jam: it's more maas specific so I shall switch to #maas | 05:15 |
jam | np | 05:15 |
axw | any particular reason why this isn't closed? https://bugs.launchpad.net/juju-core/+bug/806241 | 05:15 |
_mup_ | Bug #806241: It should be possible to deploy multiple units to a machine (unit placement) <production> <juju:Confirmed> <juju-core:Triaged> <https://launchpad.net/bugs/806241> | 05:15 |
axw | isn't this just --to? | 05:16 |
axw | ah sorry, it's --to & -n | 05:17 |
axw | .. no it's not, the summary is just confusing | 05:18 |
=== tasdomas_afk is now known as tasdomas | ||
arosales | bigjools, I added https://bugs.launchpad.net/juju-core/+bug/1214181/comments/4 | 05:33 |
_mup_ | Bug #1214181: Azure Provider always uploading 1.12 tools <juju-core:New> <https://launchpad.net/bugs/1214181> | 05:33 |
arosales | not sure why that is occuring. . . | 05:33 |
arosales | not sure if 1.12 tools are needed for some reason. | 05:34 |
arosales | but be interesting to see if you hit that by using public-storage-* | 05:34 |
* arosales is going to put up for the night | 05:34 | |
bigjools | arosales: ok | 05:35 |
bigjools | I'll need to punt to an expert | 05:35 |
arosales | bigjools, I had you pegged as the expert :-) | 05:36 |
bigjools | arosales: well I know about azure, but juju not so much :) | 05:36 |
arosales | ah | 05:36 |
arosales | bigjools, would you mind checking if you can reproduce what I am seeing? | 05:37 |
arosales | bigjools, I'll check the bug comments in the morning. Thanks for your help. | 05:40 |
arosales | bigjools, davecheney, wallyworld_ have a good rest of your day and thanks for the help. | 05:40 |
wallyworld_ | anytime, you too | 05:40 |
jam | thumper: are you still around? | 05:43 |
bigjools | arosales: sure | 05:46 |
axw | does anyone know if there's a reason why we don't use "write_files" in our cloud-init config? rather than a script that echos the contents... improperly interpreting escape sequences | 05:49 |
bigjools | I can suggest one but it's rude | 05:55 |
bigjools | jam: do all the providers take mem= in MB? | 05:55 |
davecheney | axw: probably no good reason | 06:02 |
davecheney | i think we should use cloud init whereever possible | 06:02 |
davecheney | scott moser has already solved these problem | 06:03 |
davecheney | we shouldn't reimplment his wheel | 06:03 |
bigjools | yeah it's quite amazing the number of formats cloud-init can handle | 06:03 |
bigjools | however you are tied to the oldest version in old releases | 06:04 |
* davecheney sobs | 06:04 | |
davecheney | 18 months ago everyone was like 'precise is the best release ever' | 06:04 |
davecheney | now they are like' urgh, precise, soooo oooold' | 06:04 |
davecheney | axw: https://code.launchpad.net/~axwalk/juju-core/juju-add-machine/+merge/179840 | 06:06 |
davecheney | you have a conflict in your merge proposal | 06:06 |
axw | davecheney: I'm not surprised. I was hoping to get some comments before I actually attempted to merge. Are you attempting to test it? | 06:07 |
davecheney | nah, got as far as reading the diff and saw it was dirty | 06:07 |
davecheney | just merge it to trunk | 06:07 |
davecheney | then lbox propose agian | 06:07 |
axw | yeah ok | 06:07 |
davecheney | s/to/from | 06:08 |
jam | axw: write_files (IIRC) was not available in cloud-init on the versions we wanted to use | 06:12 |
jam | I could be wrong | 06:12 |
jam | I think I remember digging into that befgor | 06:12 |
jam | before | 06:12 |
axw | jam: okey dokey. I'll confirm, and add a comment if that's the case | 06:13 |
axw | thanks | 06:13 |
jam | bigjools: I'm not very familiar with pyjuju, but I'm pretty sure that in go-juju you specify mem directly "juju deploy --constraints=mem=512M | 06:13 |
bigjools | oh that makes more sense | 06:13 |
davecheney | jam: correct | 06:27 |
davecheney | --constraints="arch=amd64 mem=2G" etc | 06:28 |
axw | jam: yeah, seems write_files was not in cloud-init 0.6.3 :( | 06:34 |
axw | oh wlel | 06:34 |
jam | davecheney, axw: I would think that newer cloud-init might end up in the minor updates (12.10.2, etc). But I don't have any proof of that, we'd have to ask smoser | 06:36 |
axw | jam: do we stop supporting .1 when .2 is available? | 06:37 |
davecheney | jam: i'll not hold my breath | 06:37 |
jam | axw: we look in simplestreams to find what "precise" is. I imagine it always points to the latest. | 06:37 |
jam | There is still userland and custom images, etc. | 06:37 |
axw | yeah.. I guess you'd want to give people some warning about doing something like that | 06:38 |
jam | axw: the other problem is that we can't really "just detect" what a given image has available, so it is probably most reasonable to stick with least-common-denominator | 06:39 |
axw | yep | 06:39 |
axw | I'll add a comment in the code for the next person :) | 06:39 |
axw | davecheney: merged and reproposed | 06:48 |
bigjools | hey, does a mongo binary need to exist with the public tools even on saucy? | 06:49 |
jam | bigjools: we use the ppa even on precise | 06:50 |
jam | bigjools: we don't use it from the bucket for a while now. | 06:50 |
bigjools | I ask because I am testing on azure and it gets stuck when trying to connect to mongo | 06:50 |
bigjools | conn refused | 06:51 |
jam | bigjools: I think that is because we aren't initializing properly on the machine, and we only detect that because mongo didn't get started. | 06:51 |
jam | bigjools: the jujud binary writes a custom upstart | 06:51 |
davecheney | bigjools: no, it does not need to exist for any series | 06:51 |
davecheney | it is redundant | 06:51 |
bigjools | k | 06:51 |
bigjools | do we expect it to take a while to get started? | 06:52 |
davecheney | bigjools: it comes up pretty much instantly | 06:52 |
jam | bigjools: not very long vs the machine being up and running. I think on HP it is < a minute | 06:52 |
bigjools | ok, something's buggered then | 06:52 |
davecheney | but we can't predict when that instant occurs | 06:52 |
jam | bigjools: can you ssh in to look at log files? | 06:52 |
bigjools | I *could* if I had not already destroyed my env :) | 06:52 |
davecheney | jam: yup < 90 seconds for HP | 06:52 |
davecheney | bigjools: tail -f /var/log/cloud-init-output.log // the goods | 06:53 |
bigjools | yup | 06:53 |
bigjools | ta | 06:53 |
bigjools | waiting for a bootstrap to finish is awkward from a UI PoV, are there any plans to improve this experience? | 06:54 |
bigjools | 9 minutes later, still waiting...! | 06:57 |
bigjools | ah there it is | 06:57 |
davecheney | bigjools: there is a discuission on the juju-dev ML i belive | 07:00 |
bigjools | I remember one from a while ago :) | 07:01 |
davecheney | bigjools: oh, it's still ongoing | 07:16 |
rogpeppe1 | mornin' all | 07:30 |
bigjools | wallyworld_: so see you at the Plum any time after 08:45 then? | 07:31 |
bigjools | hello rogpeppe1 | 07:32 |
=== rogpeppe1 is now known as rogpeppe | ||
rogpeppe | bigjools: hiya | 07:33 |
=== ChanServ changed the topic of #juju-dev to: https://juju.ubuntu.com | On-call reviewer: - | Bugs: 7 Critical, 92 High - https://bugs.launchpad.net/juju-core/ | ||
=== ChanServ changed the topic of #juju-dev to: https://juju.ubuntu.com | On-call reviewer: rogpeppe | Bugs: 7 Critical, 92 High - https://bugs.launchpad.net/juju-core/ | ||
axw | davecheney: 1121914 was released in 1.13.1 | 07:44 |
wallyworld_ | bigjools: ok, sounds good | 07:44 |
dimitern | morning | 07:46 |
rogpeppe | fwereade: i have just come to the conclusion that the collect logic in entityWatcher is entirely redundant - state/watcher can never deliver more than one event for the same document in the same cycle AFAICS. | 08:09 |
rogpeppe | fwereade: (the same is not true of lifeCycleWatcher, of course) | 08:11 |
davecheney | axw: did we call it out in the release notes ? | 08:13 |
axw | davecheney: yes | 08:13 |
axw | under "Resolved issues" | 08:13 |
davecheney | ok, removed | 08:13 |
davecheney | thanks for checking | 08:13 |
axw | nps | 08:14 |
davecheney | night y;all | 08:14 |
fwereade | rogpeppe, my worry is that the state code doesn't get to control the watcher cycles | 08:16 |
fwereade | rogpeppe, (and I'd rather keep the watcher implementations in line as far as possible... it will make life easier if we ever get as far as generating some of this code) | 08:16 |
rogpeppe | fwereade: the issue is that it's impossible for me to write a test that will fail | 08:17 |
rogpeppe | davecheney: g'night dave | 08:17 |
fwereade | gn davecheney | 08:17 |
fwereade | rogpeppe, a test that *would* fail, as determined by our best attempt at analysis, is all I'm really looking for here | 08:18 |
fwereade | rogpeppe, (hmm, if we *were* to force a collect on the initial event that would resolve the double-event ickiness that was causing intermittent failures in the first place... they definitely can fail ;p) | 08:20 |
rogpeppe | fwereade: as i do usually, i try to write a test that actually fails (at least once) when the code is wrong. | 08:20 |
fwereade | rogpeppe, (but it wouldn't hit the steady state path anyway, so, meh) | 08:20 |
TheMue | fwereade: ping | 08:21 |
fwereade | rogpeppe, that is indeed a good thing to do in general and I applaud the approach, but I think it's also occasionally legitimate to write assumption tests that don't fail at the time of writing | 08:22 |
fwereade | rogpeppe, and entityWatcher is an internal detail anyway -- it's not the only NotifyWatcher out there, and their various implementations do differ | 08:23 |
fwereade | TheMue, pong | 08:23 |
TheMue | fwereade: after syncing I'm now continuing with https://bugs.launchpad.net/juju-core/+bug/1194945 | 08:23 |
_mup_ | Bug #1194945: juju set is overloaded <juju-core:In Progress by themue> <https://launchpad.net/bugs/1194945> | 08:23 |
TheMue | fwereade: the first approach following the "set --default" way showed, that this is not optimal in the sense of usability | 08:24 |
fwereade | TheMue, cool, I wasn't that keen myself -- what's your preference now? | 08:25 |
rogpeppe | fwereade: the only two watchers that call collect are entityWatcher and lifecycleWatcher | 08:25 |
TheMue | fwereade: it leads to mixed situations like "set foo=bar --default baz" etc | 08:25 |
rogpeppe | TheMue: i don't think there's any need to allow mixing | 08:25 |
TheMue | fwereade: I would like an own command for it, like "juju unset ..." or "juju reset ..." | 08:25 |
fwereade | TheMue, sweet, so would I :) | 08:25 |
TheMue | rogpeppe: yeah, now allowance, but people may call it that way | 08:26 |
rogpeppe | TheMue: if they do that, they'd get an error | 08:26 |
TheMue | rogpeppe: dimiter and jam mentioned it too, because it is not really clear to the user | 08:26 |
rogpeppe | TheMue: fair enough. i think i suggested it too originally, but it didn't really seem to justify a whole new command | 08:27 |
TheMue | rogpeppe: that's what I've done so far, but it doesn't feel good. any reasons against unset or reset as own commands? | 08:27 |
fwereade | TheMue, I think I favour unset, because reset seems to be a bit more overloaded | 08:27 |
TheMue | fwereade: yep, I'm feeling better with unset too | 08:27 |
rogpeppe | TheMue, fwereade: i'd be ok with juju unset | 08:28 |
rogpeppe | TheMue: the help text for set should mention the existence of unset | 08:29 |
TheMue | fwereade, rogpeppe: ok, doing that, makes me feeling better too ;) | 08:29 |
TheMue | rogpeppe: oh, yes, very good idea | 08:29 |
fwereade | rogpeppe, my position is that the watchers that don't collect() probably should in general, but that Lax is appropriate for those cases in the meantime; but making every notify checker lax is not a good idea, because it means we can't write tests for alternative notifywatchers that do need to collect | 08:31 |
fwereade | rogpeppe, the code was written to support being built on in predictable ways | 08:31 |
fwereade | rogpeppe, ...but, look, from my perspective you made something worse and are fussing about undoing that change because it was less than perfect to begin with | 08:33 |
fwereade | rogpeppe, can we please just reinstate what we had before? | 08:33 |
rogpeppe | fwereade: i really don't think Lax helps much | 08:34 |
rogpeppe | fwereade: it's smoke-and-mirrors | 08:34 |
fwereade | rogpeppe, you turned *everything* into a Lax one | 08:35 |
rogpeppe | fwereade: oh, sorry, i forgot the terminology | 08:35 |
rogpeppe | fwereade: if we have some functionality that needs to be tested, we should have a test for that functionality | 08:35 |
rogpeppe | fwereade: rather than pretending that a few nanoseconds of scheduler decisions might give us a test failure more than once a century | 08:36 |
fwereade | rogpeppe, it doesn't help *much*, I know | 08:37 |
fwereade | rogpeppe, I added it because it helped a *bit* | 08:37 |
fwereade | rogpeppe, and you removed it with a clear statement of "I don't understand what it does, but meh" | 08:37 |
rogpeppe | fwereade: i didn't understand what it did, because it didn't do what it was intended to do | 08:37 |
fwereade | rogpeppe, what do you believe it was intended to do? | 08:37 |
rogpeppe | fwereade: i can easily add a test for aggregation | 08:37 |
rogpeppe | fwereade: i believe it was intended to make some tests fail if aggregation was not working | 08:38 |
rogpeppe | fwereade: but it's not clear which tests are intended to fail in that case | 08:39 |
fwereade | rogpeppe, and your problem is that those tests do not *always* fail? yes, this is less than ideal -- but you seem to be saying things are better with that behaviour untested? | 08:39 |
rogpeppe | fwereade: my problem is that in all likelihood those tests will never fail | 08:39 |
rogpeppe | fwereade: and i'm not sure which tests they are | 08:39 |
jam | axw: do you have any idea of why cloud-init stuff was working for a while but seems to have changed? | 08:39 |
rogpeppe | fwereade: because the "non-lax" code was sprayed around everywhere, as if everywhere was trying to test this issue | 08:40 |
axw | jam: no, but I never saw it in the working state | 08:40 |
jam | axw: k. Is there a reason why 'shquote' doesn't grow the escape '\' code? | 08:40 |
fwereade | rogpeppe, it was written to test against the NotifyWatcher interface without regard for the underlying implementation | 08:40 |
rogpeppe | fwereade: out of interest, which tests *should* (potentially) fail if the aggregation isn't working? | 08:41 |
fwereade | rogpeppe, CleanupWatcher at least IIRC -- and the point is that the tests should be somewhat useful canaries against non-obvious underlying implementation changes | 08:42 |
fwereade | rogpeppe, this is how a NotifyWatcher should act regardless | 08:42 |
axw | jam: not technically, but I think whomever wrote it intended it to be like http://www.daemon-systems.org/man/shquote.3.html | 08:42 |
axw | or something similar | 08:42 |
fwereade | rogpeppe, the fact that the implementation of one particular one is such that it can't fail is just a detail, and not a justification for using less strict testing infrastructure | 08:43 |
axw | jam: IOW, I didn't want to surprise anyone | 08:43 |
rogpeppe | fwereade: how many tests for impossible happenstances should we write? | 08:43 |
TheMue | rogpeppe: thx | 08:44 |
TheMue | rogpeppe: "happenstance" is a new word for me, like it | 08:45 |
fwereade | rogpeppe, quite a lot, really, because if you use inspection of the implementation as justification not to test we can drop a whole load of tests... but then they *don't fail when someone changes the implementation* | 08:45 |
rogpeppe | fwereade:i did think it should be possible to make a test fail by changing the code it's testing. if that's no longer the case, then i really see no bound on the amount of test code we need to write. | 08:45 |
fwereade | rogpeppe, then in that case use the Lax watcher explicitly in those cases, because I cannot be bothered to argue that | 08:46 |
rogpeppe | fwereade: the implementation can change in so many possible ways - there are zillions of ways that things could fail if the underlying implementation is free to change completely. i really do find this a difficult issue to deal with. | 08:47 |
fwereade | rogpeppe, but that is *still* using asusmptions about the implementation in tests for the interface | 08:47 |
rogpeppe | fwereade: yes, i believe it's ok to assume the implementation. otherwise we don't have any idea of how to test the code well. | 08:47 |
fwereade | rogpeppe, the existence of Lax is a sad acknowledgement that we cannot entriely dodge the issue, but Lax is meant to be the one that's eventually dropped, not the other way round | 08:48 |
rogpeppe | fwereade: Lax==Sync, right? | 08:48 |
fwereade | rogpeppe, yeah | 08:48 |
rogpeppe | fwereade: StartSync is a total hack | 08:48 |
rogpeppe | fwereade: it shouldn't exist at all really | 08:49 |
rogpeppe | fwereade: (and it didn't, originally) | 08:49 |
fwereade | rogpeppe, Sync is a total hack, StartSync is the only one that reasonably approximates real conditions | 08:49 |
axw | jam: now that I read the docstring for utils.ShQuote properly, tho, it seems fair to put it there. I'll update it. | 08:49 |
fwereade | rogpeppe, sync only helps when you've only got one level do deal with | 08:49 |
rogpeppe | fwereade: StartSync gives you no guarantees of anything happening at all | 08:49 |
fwereade | rogpeppe, exactly so | 08:50 |
fwereade | rogpeppe, sync sometimes does and sometimes doesn't | 08:50 |
rogpeppe | fwereade: it at least guarantees that the watcher has received the sync message... | 08:51 |
dimitern | rogpeppe: https://codereview.appspot.com/13113045 - two more uniter API calls needed I forgot about | 08:51 |
rogpeppe | fwereade: perhaps that's a better way to fix this | 08:51 |
fwereade | rogpeppe, it guarantees that the message has travelled *some* distance through the plumbing, but not how far it has actually travelled | 08:51 |
fwereade | rogpeppe, *frequently* it is good enough, but that just encourages faulty assumptions | 08:52 |
rogpeppe | fwereade: it doesn't guarantee, unfortunately, that the sync message has been acted on at all | 08:52 |
rogpeppe | fwereade: oh, Sync, yes | 08:52 |
rogpeppe | fwereade: how about this: | 08:52 |
fwereade | rogpeppe, StartSync is better because it is reliably unreliable, as opposed to unreliably reliable | 08:53 |
axw | jam: actually, sorry, last word on this ;) utils.ShQuote single quotes its input, so '\' characters shouldn't be interpreted | 08:53 |
rogpeppe | fwereade: i change the watcher code so that StartSync actually works properly, and use it everywhere we can. | 08:53 |
rogpeppe | fwereade: in fact, rename StartSync to Sync | 08:54 |
dimitern | mgz: hey | 08:54 |
fwereade | rogpeppe, define "works properly", because I'm not following | 08:54 |
dimitern | jam: ? | 08:54 |
rogpeppe | fwereade: by "works properly" i mean "when you've called (Start)Sync, you know that the underlying watcher implementation is synchronising, and won't act on random other timer events before that" | 08:55 |
fwereade | rogpeppe, (also, StartSync cannot be blocked by a faulty watcher implementation, and Sync can) | 08:56 |
rogpeppe | fwereade: that is true | 08:56 |
dimitern | fwereade, rogpeppe: sorry to interrupt, but I'd like to bug one of you for a review | 08:57 |
rogpeppe | dimitern: looking | 08:57 |
fwereade | rogpeppe, seeking common ground: if we were to call it SyncSoon instead of StartSync, would you agree that was more accurate? | 08:57 |
dimitern | rogpeppe: ta | 08:57 |
rogpeppe | fwereade: i'd just call it "Sync" | 08:57 |
rogpeppe | fwereade: and make it work | 08:57 |
rogpeppe | fwereade: yeah, SyncSoon is a better description of the current behaviour | 08:57 |
rogpeppe | fwereade: but it isn't very useful behaviour | 08:58 |
rogpeppe | fwereade: because it is inherently difficult to predict its results, which makes it hard to write good tests using it | 08:58 |
fwereade | rogpeppe, it's hard, and inherently timing-dependent, and that sucks -- but to write useful tests by those lights, we can't depend on anything internal to state/watcher *anyway*, because we're affected by the layers of plumbing between that package and the actual test | 08:59 |
fwereade | rogpeppe, Sync is useful iff there is a single layer | 09:00 |
rogpeppe | fwereade: yeah, i'm suggesting deleting the current Sync implementation (which simplifies state/watcher a bit too) | 09:00 |
rogpeppe | fwereade: and renaming StartSync to Sync, but making it more deterministic | 09:00 |
rogpeppe | fwereade: my objections to Sync when it was originally written were similar to yours | 09:01 |
fwereade | rogpeppe, that is to me the problem -- being a bit more deterministic just encourages poor assumptions | 09:01 |
rogpeppe | fwereade: i think it's reasonable to assume that the underlying implementation is using state/watcher | 09:02 |
rogpeppe | fwereade: (that's what (Start)Sync is talking to, after all | 09:02 |
rogpeppe | ) | 09:02 |
jam | dimitern: I'm around, but I'm not sure what you are asking for | 09:02 |
fwereade | rogpeppe, I think it's impossible to make state/watcher *clients* more deterministic by tweaking state/watcher -- we're always vulnerable to the client implementations | 09:02 |
dimitern | jam: sorry :) was just a ping | 09:03 |
dimitern | jam: you wanted to discuss the api? | 09:03 |
fwereade | dimitern, what's Resolved() for? | 09:03 |
dimitern | fwereade: what do you mean? | 09:03 |
fwereade | dimitern, what calls it? | 09:03 |
dimitern | fwereade: let me check, just a sec | 09:03 |
rogpeppe | fwereade: if we assume that the clients function as a deterministic result of events received from state/watcher, i think that by tweaking state/watcher, we *can* make the clients more deterministic too. | 09:04 |
dimitern | fwereade: filter.go:432:if resolved := f.unit.Resolved(); resolved != f.resolved { | 09:04 |
rogpeppe | dimitern: why does Unit.Resolved need to make an API call? can't we get the resolved mode with the rest of the unit params? | 09:05 |
rogpeppe | s/params/fields/ | 09:05 |
dimitern | rogpeppe: how? | 09:05 |
fwereade | dimitern, forgive my brainfart | 09:05 |
rogpeppe | dimitern: Resolved is in unitDoc, right? | 09:06 |
dimitern | rogpeppe: since LifeGetter is now common, there's no way to inject stuff that get's refreshed when you call Refresh() | 09:06 |
rogpeppe | dimitern: then surely your problem is that you're using LifeGetter for getting all the fields in a unit? | 09:06 |
dimitern | rogpeppe: what? | 09:06 |
jam | axw: did you dig into cloud-init at all to see what it might be unescaping? | 09:07 |
dimitern | rogpeppe: LifeGetter reports back the life only | 09:07 |
fwereade | rogpeppe, life and resolution are essentially orthogonal -- it's an artifact of the current implementation that we get them at the same time | 09:07 |
jam | axw: for example: http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/cloud-config-run-cmds.txt | 09:07 |
fwereade | rogpeppe, this gives us the opportunity to move towards less monolithic event filtering at some point in the future | 09:07 |
rogpeppe | fwereade: ah, i thought it's actually quite nice that we get more than one attribute of an object when we ask for the object | 09:07 |
rogpeppe | fwereade: because the overhead is much smaller than making n different API calls | 09:08 |
rogpeppe | fwereade: but if that's no longer considered a good approach, fair enough | 09:08 |
fwereade | rogpeppe, filter is a beast *because* all these different pieces of information are glommed together | 09:08 |
jam | there are no '\' characters there, but it seems to imply that cloud-init won't do anything with '\' but whether you pass a list or a string makes a difference. | 09:08 |
dimitern | rogpeppe: we changed everything else, so that's a minor thing :) | 09:08 |
axw | jam: I started to, but didn't get to the bottom of it. I noted that the YAML produced shouldn't be escaped. I didn't want to spend a lot of time on it, but if you prefer I can dig further. | 09:08 |
rogpeppe | dimitern: yeah, i'm just wondering about how many extra round-trips we'll be having | 09:09 |
rogpeppe | dimitern: but since we aren't measuring anything, who knows? | 09:09 |
fwereade | rogpeppe, I'd like it most of all if we only even bothered to check/watch resolved status when the uniter knew it had to | 09:09 |
fwereade | rogpeppe, we can't get there in just one step though | 09:09 |
dimitern | rogpeppe: once we do it, we can measure easily | 09:10 |
jam | axw: I mostly want us to understand what is going on rather than just saying "oh, add another \" because that may not be appropriate always, as it might get interpreted as literal "\" + "n" | 09:10 |
jam | which would then fail for a different reason, etc. | 09:10 |
dimitern | rogpeppe: and optimize as needed | 09:10 |
axw | jam: yep fair enough. I'll keep digging | 09:10 |
jam | mgz: poke about maas constraints and py-juju | 09:10 |
rogpeppe | dimitern: optimizing will be difficult if we can't change the API (which is the whole rationale for the bulk call thing AFAIR) | 09:10 |
jam | axw: for example we also write agent.conf via this mechanism, and some other files, it may be that we should always escape, or never, or write it differently, etc. | 09:11 |
rogpeppe | dimitern: but i agree anyway | 09:11 |
jam | axw: what I'm really concerned with is if in precise we need to do it one way, and in saucy it will be different. | 09:11 |
dimitern | rogpeppe: we're all smart guys, I'm sure we'll find a way when comes to that :) | 09:11 |
jam | axw: I think runcmds goes through "shellify" which will escape things if passed in as a list, but *not* escape them if passed in as a string | 09:11 |
jam | I don't know for sure what cloud-init path we are doing atm | 09:12 |
jam | axw: though if I'm reading it correctly, AddFile uses AddScripts which uses RunCmd | 09:13 |
rogpeppe | axw: i think i was probably responsible for shquote | 09:13 |
rogpeppe | axw: what's the issue? | 09:13 |
axw | jam: understood. it's a string and not a list, so it will go through the shell | 09:13 |
jam | axw: and it looks like we are doing a single string for the whole script to run | 09:13 |
axw | rogpeppe: nothing specific to shquote. the rsyslog conf written out has its \n interpreted | 09:13 |
rogpeppe | axw: ah, so you can't have '\n' | 09:14 |
dimitern | axw, jam, rogpeppe: AddFile and AddScripts were recently changed by sidnei IIRC | 09:14 |
jam | axw: and we *could* pass it in as "args" rather than "literal" which might be a whole lot more obvious through all the transformation steps | 09:14 |
axw | jam: sorry I don't follow that last statement | 09:15 |
jam | axw: going back to this example: http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/cloud-config-run-cmds.txt | 09:15 |
jam | cloud-config takes a yaml description | 09:15 |
jam | in that | 09:15 |
jam | you can have a list of things to run | 09:15 |
jam | each item in that list | 09:15 |
jam | can either be a literal string | 09:15 |
jam | "ls -l /root" | 09:15 |
jam | or a list | 09:15 |
jam | "[ ls, -l, root ]" | 09:15 |
jam | if you pass in a literal string | 09:16 |
jam | then cloud-init just passes it directly to sh to interpret | 09:16 |
jam | if you pass in a list of strings | 09:16 |
jam | cloud-init will escape them for you before passing it to sh | 09:16 |
jam | axw: it *looks* like our internal code has a "command" object in cloudinit.go | 09:16 |
jam | which can take either a "literal string" or a "args []string" | 09:16 |
jam | but all of our AddFile code uses the "literal string" approach. | 09:16 |
jam | And I'm wondering if instead of playing games with escaping on our side | 09:17 |
jam | we might just go with | 09:17 |
jam | the args []string form | 09:17 |
axw | jam: indeed, I missed that. I'll look into using that | 09:17 |
axw | thanks | 09:18 |
jam | axw, dimitern, sidnei: it looks like we switched from doing "echo content > filename; chmod MODE filename" to "install -m MODE /dev/null filename; echo CONTENT > filename" any idea why? | 09:20 |
jam | (I don't think it changes the failure mode here, but I'm trying to understand the logic behind the change) | 09:20 |
fwereade | rogpeppe, anyway: *WatcherC targets the ideal *Watcher behaviour; some of them suck, and need Lax*WatcherCs, but those should be dropped one day; thank you for tracking down the case where non-lax was not good enough, but please reinstate the stricter versions and use them where they don't cause failures | 09:21 |
axw | no idea | 09:21 |
jam | the commit comment just says "move addFile from environments/cloudinit.go to cloudinit/cloudinit.go" | 09:21 |
rogpeppe | fwereade: how are you with my plan to do away with Sync entirely? (and fix StartSync so it works reliably for us - i've nearly done it, it's not a hard change) | 09:22 |
jam | I guess the overall commit says "create the file with the correct mode first, so that we slightly increase security". Which is fine, as long as that doesn't actually break this :) | 09:22 |
dimitern | jam: https://codereview.appspot.com/12352043/ - that's the change | 09:23 |
axw | jam: using a list isn't really viable here, since it wants to redirect output | 09:23 |
fwereade | rogpeppe, I still consider it philosophically suspect -- I don't see how guaranteeing that a sync has actually started helps anyone, because what we really care about is that *all* consequences have completed, and we can't affect that at the state/watcher level | 09:24 |
rogpeppe | fwereade: the issue it solves is this: | 09:24 |
rogpeppe | fwereade: a test makes some changes, then wants to see what happens | 09:24 |
rogpeppe | fwereade: it calls StartSync, but the regular timer event happens first, at the wrong time | 09:25 |
rogpeppe | fwereade: if we make StartSync actually guarantee that the watcher is doing a sync *right now* | 09:26 |
dimitern | rogpeppe: how's the review looking? :) | 09:26 |
rogpeppe | fwereade: then we avoid that possibility | 09:26 |
rogpeppe | dimitern: apologies, getting back on it | 09:27 |
fwereade | rogpeppe, keep explaining, I'm not seeing how that situation causes problems | 09:27 |
fwereade | dimitern, can't we determine service name unambiguously from knowing the unit name? | 09:27 |
dimitern | fwereade: hmm | 09:27 |
dimitern | fwereade: yes, actually you're right, but we can't be sure we can get it from state perhaps? | 09:28 |
fwereade | dimitern, the Unit surely knows its own name, though | 09:28 |
dimitern | fwereade: yes it does | 09:29 |
dimitern | fwereade: but unit.Service() -> *Service, error | 09:29 |
dimitern | fwereade: should we always return nil there in the api? | 09:29 |
fwereade | dimitern, I'm confused, the method I'm looking at is called ServiceName | 09:30 |
rogpeppe | fwereade: there's a good example of the problem in https://codereview.appspot.com/12352044/ | 09:30 |
dimitern | fwereade: i mean, for the error, otherwise we construct and return a proxy uniter.Service object ofc | 09:30 |
dimitern | fwereade: ah, that one - yeah, you're right there - I should just extract the service name from the unit tag and return it | 09:30 |
dimitern | fwereade: it's a good candidate for such a call in names | 09:32 |
fwereade | dimitern, +1 | 09:32 |
rogpeppe | fwereade: another possibliity, i suppose, would be to raise the watcher period to forever | 09:32 |
rogpeppe | fwereade: in tests | 09:32 |
dimitern | fwereade: but we still need GetService at the server-side, right? | 09:32 |
rogpeppe | fwereade: so events we get are exactly and always as a result of StartSync calls | 09:33 |
fwereade | dimitern, yeah, think so | 09:33 |
dimitern | fwereade: for the other call: func (u *Unit) Service() (*Service, error) | 09:33 |
dimitern | fwereade: ok | 09:33 |
jam | axw: so looking at cloud-init-output.log I see the echo line, but I don't see *any* single quotes | 09:33 |
fwereade | rogpeppe, that is an interesting thought | 09:33 |
jam | are they getting interpreted in the yaml maybe? | 09:33 |
fwereade | rogpeppe, because just guaranteeing that a sync is in progress doesn't say anything about whether or not the last event landed before the sync started | 09:34 |
rogpeppe | fwereade: (if we have any tests that are actually relying on the regular polling, they're broken anyway) | 09:34 |
axw | jam: just recreating my env, I destroyed it prematurely. sounds feasible though | 09:34 |
fwereade | rogpeppe, agreed | 09:34 |
jam | axw: I'm trying to figure out if cloud-init writes out the script it is going to be running somewhere to more easily inspect iti | 09:34 |
jam | or I can try querying the metadata server | 09:35 |
axw | jam: I think it's in /var/lib/cloud/seed/instances or something like that | 09:35 |
fwereade | rogpeppe, but I'm pretty comfortable as it is with the idea that an initial event may reflect the past, not so much because it's nice behaviour but because it's an insidious sort of assumption that it's hard to spot | 09:36 |
fwereade | rogpeppe, and I'm concerned about the impact of changing it | 09:36 |
fwereade | rogpeppe, because I think *that* will also be subtle | 09:37 |
rogpeppe | fwereade: i don't *think* i was suggesting that, was i? | 09:37 |
rogpeppe | fwereade: (it's a pretty fundamental part of the watcher implementation) | 09:37 |
jam | axw: /var/lib/cloud/instance/user-data.txt.i | 09:37 |
axw | jam: there's a runcmd file too | 09:38 |
axw | jam: I just munted my cloudinit output tho, so need to run it again... | 09:39 |
rogpeppe | fwereade: the random interference of timer events is actually perhaps the underlying problem here, not the StartSync behaviour. still thinking it over. | 09:39 |
fwereade | rogpeppe, yeah, I'm a bit uncertain myself | 09:40 |
fwereade | rogpeppe, might go eat something and think it over a bit | 09:40 |
rogpeppe | fwereade: okeydokey | 09:40 |
jam | axw: so if I look at instance/scripts/runcmd it uses #!/bin/sh and calls "echo '....'" and that has a %\n" in it. | 09:41 |
jam | however my /etc/rsyslog.d/25-juju.conf doesn't have the \nd | 09:42 |
jam | I'm noticing we *aren't* using "echo -e" soecho shouldn't be interpreting it. | 09:42 |
jam | but it might be | 09:42 |
jam | or #!/bin/sh might be | 09:42 |
jam | axw: ugh | 09:45 |
jam | seems that dash and bash interpret 'echo' differently | 09:45 |
axw | jam: doh | 09:46 |
dimitern | rogpeppe: cheers for the review | 09:46 |
jam | axw: do 'man dash' and then /echo | 09:46 |
jam | it always interprets '\' | 09:46 |
jam | while *bash* echo | 09:46 |
jam | only interprets '\' characters if you specify "echo -e" | 09:46 |
rogpeppe | jam: there are many different versions of echo | 09:46 |
dimitern | rogpeppe: but the comment should've been about ServiceName(), not Service(), right? | 09:47 |
jam | (and you can force echo -E to disable it) | 09:47 |
rogpeppe | jam: even bash has several built in | 09:47 |
jam | dash's echo -E just prints "-E" | 09:47 |
mgz | jam: hey | 09:47 |
rogpeppe | jam: that's the original echo (it just interprets -n) | 09:47 |
jam | axw: so... if we run on a machine where "/bin/sh" is dash, then we need to escape, if we run on a machine with "bash" then we *shouldn't* escape | 09:47 |
jam | axw: fun times :) | 09:47 |
axw | jam: how about I just pipe it through base64 ;) | 09:47 |
jam | axw: hence my "lets understand what is going on" | 09:47 |
axw | jam: good call. | 09:48 |
rogpeppe | jam: one possibility is to call /bin/echo | 09:48 |
rogpeppe | jam: but that can vary too, of course, sysv vs bsd etc | 09:48 |
jam | axw: /bin/echo seems to be sane here | 09:49 |
axw | are we ever going to support anything that uses non-GNU? | 09:49 |
* rogpeppe has no idea what portability range we're aiming for | 09:49 | |
jam | axw: I know we have plans to support centos, but I don't know of any immediate plans for BSD (also maybe windows, but that will be entirely different anyway) | 09:49 |
axw | CentOS will be fine. We can always change it later anyway | 09:50 |
axw | /bin/echo it is | 09:50 |
jam | axw: I can confirm that write_files is not available on the precise image I'm looking at after bootstrapping. | 09:52 |
axw | jam: thanks. I also checked in the cloud-init source from 12.04, and confirmed it didn't have the module | 09:53 |
* rogpeppe can't work out how to reliably print a string with /bin/echo either | 09:53 | |
axw | rogpeppe: ? | 09:53 |
axw | you mean different implementations? | 09:54 |
rogpeppe | axw: what if the string is "-E"? | 09:54 |
rogpeppe | axw: no, i mean with gnu echo | 09:54 |
jam | rogpeppe: -- ? | 09:54 |
rogpeppe | jam: nope, doesn't work | 09:54 |
axw | heheh | 09:54 |
rogpeppe | frickin' magnificent | 09:54 |
jam | rogpeppe: so it doesn't matter in this case, but yes, trying to echo things starting with "-" is not very well supported | 09:55 |
rogpeppe | it's ok if we don't mind an extra space at the start | 09:55 |
rogpeppe | /bin/echo '' $x | 09:55 |
rogpeppe | /bin/echo '' $x | sed 's/ //' | 09:56 |
rogpeppe | :-) | 09:56 |
jam | rogpeppe: in our particular case we actually start the string with a blank newline, so it really doesn't matter :)( | 09:56 |
axw | | cut -c2- | 09:56 |
axw | but I'm not going to go there | 09:56 |
rogpeppe | oh G N U we love U | 09:56 |
jam | axw: my current vote is for /bin/echo for AddFile | 09:57 |
axw | jam: yep that's what I'll do | 09:57 |
axw | with some comments... | 09:57 |
rogpeppe | axw: printf "%s\n" $var ? | 09:58 |
rogpeppe | axw: avoids the whole echo minefield | 09:59 |
axw | oh, I suppose so :) | 10:00 |
axw | printf "%s\n" '-E' | 10:02 |
axw | yay | 10:02 |
jam | rogpeppe: "printf is a shell builtin" are we sure dash and bash won't interpret it differently? | 10:09 |
jam | axw: http://pubs.opengroup.org/onlinepubs/009696799/utilities/echo.html | 10:10 |
jam | seems to state "echo is not portable across POSIX so use printf" | 10:10 |
jam | so lets use printf :) | 10:10 |
axw | just updating tests now | 10:11 |
rogpeppe | dimitern: my comment *was* actually about GetService | 10:13 |
rogpeppe | dimitern: it just returns the service name currently | 10:13 |
dimitern | rogpeppe: it returns the service tag, and that'll be used in Service() | 10:14 |
rogpeppe | dimitern: but we know the service tag given the unit name | 10:14 |
dimitern | rogpeppe: but we need to get it from state, right? | 10:14 |
rogpeppe | dimitern: why? | 10:14 |
dimitern | rogpeppe: it might be missing or something | 10:15 |
dimitern | rogpeppe: why is there an error return on state.Unit.Service() otherwise? | 10:15 |
rogpeppe | dimitern: can a service be deleted when it's still got units? | 10:15 |
rogpeppe | dimitern: because state.Unit.Service actually gets other info too | 10:15 |
rogpeppe | dimitern: if we're planning to get that other info as part of the GetService call, then fine | 10:16 |
dimitern | rogpeppe: i stil think there should be a server-side GetService call | 10:16 |
rogpeppe | dimitern: but it doesn't look like it | 10:16 |
rogpeppe | dimitern: what value does it add? | 10:16 |
dimitern | rogpeppe: I could change it to get the life as well | 10:17 |
dimitern | rogpeppe: but we already have Life that works on services | 10:17 |
rogpeppe | dimitern: so is the plan that we don't hold any state locally at all for an entity? | 10:18 |
rogpeppe | dimitern: so we won't have a Refresh call | 10:18 |
axw | jam: I'll finish this later, going to get my daughter ready for bed | 10:18 |
dimitern | rogpeppe: I'll propose a follow-up that adds the mentioned ServiceFromUnitTag to names, and can remove GetService then | 10:18 |
dimitern | rogpeppe: no, we hold the life | 10:19 |
rogpeppe | dimitern: ah, in which case GetService needs to get the life too, right? | 10:20 |
dimitern | rogpeppe: no, Life already works on service tags | 10:20 |
rogpeppe | dimitern: oh, of course. | 10:20 |
dimitern | rogpeppe: so perhaps uniter.Unit.Service() should really do a Life call underneath, like uniter.Unit does | 10:21 |
rogpeppe | dimitern: yup, that seems about right. | 10:21 |
rogpeppe | dimitern: it should probably just call Service.Refresh to avoid making assumptions about the fields in a service | 10:22 |
dimitern | rogpeppe: who should? | 10:22 |
dimitern | rogpeppe: Life already gets the service afresh | 10:23 |
rogpeppe | dimitern: the client side uniter.Unit.Service should create a local instance of Service, then call Refresh on it, rather than making the Life call itself. | 10:23 |
rogpeppe | dimitern: the Service.Refresh call will make the Life call itself | 10:24 |
dimitern | rogpeppe: that works as well, yes | 10:24 |
rogpeppe | dimitern: that way if we add more fields to Service, we just need to change that one place (Refresh) | 10:24 |
dimitern | rogpeppe: yep | 10:29 |
dimitern | rogpeppe: there it is https://codereview.appspot.com/13112045/ | 10:55 |
* TheMue => lunchtime | 10:56 | |
dimitern | rogpeppe: included that what talked about above | 11:02 |
rogpeppe | dimitern: i'm halfway through :-) | 11:02 |
dimitern | rogpeppe: cool | 11:02 |
fwereade | dimitern, couple of comments | 11:03 |
dimitern | fwereade: ta | 11:03 |
dimitern | fwereade: not sure what you mean by the second comment - are you suggesting to drop .ServiceName() ? | 11:05 |
fwereade | dimitern, if it's not used elsewhere, having a names method for converting unit tag -> service tag seems most helpful here | 11:05 |
dimitern | fwereade: if what's not used elsewhere? | 11:06 |
rogpeppe | dimitern: reviewed | 11:07 |
rogpeppe | fwereade: i've just suggested a slightly different approach | 11:07 |
dimitern | rogpeppe: thanks! | 11:07 |
rogpeppe | fwereade: keep the conversion on names only. | 11:07 |
fwereade | rogpeppe, sgtm | 11:07 |
rogpeppe | fwereade: that way it's only the name-related functions that panic on unexpected things | 11:07 |
dimitern | rogpeppe: sgtm as well | 11:08 |
fwereade | rogpeppe, yeah, definitely better, thanks | 11:08 |
rogpeppe | fwereade: cool, ta | 11:08 |
jamespage | mgz or hazmat: any chance either of you can take a look at these test failures | 11:22 |
jamespage | http://paste.ubuntu.com/6006051/ | 11:22 |
jamespage | juju-0.7 on saucy - going to re-introduce so as to not kill folks with existing py-juju deployments | 11:23 |
dimitern | rogpeppe: quick glance before I submit it? https://codereview.appspot.com/13112045/ | 11:24 |
rogpeppe | dimitern: glancing | 11:24 |
mgz | jamespage: I think I filed some bugs for test failures that I got only when run as part of the package build process, not outside it | 11:24 |
mgz | hm, not those failures though | 11:25 |
hazmat | jamespage, sure | 11:25 |
jamespage | hazmat, thanks | 11:25 |
natefinch | man, testing the azure environ is... less than fun | 11:26 |
rogpeppe | dimitern: one thought: we should implement Unit.String | 11:27 |
dimitern | rogpeppe: it's easy enough to do if we need it | 11:27 |
rogpeppe | dimitern: (lots of things call printf %q with units and services | 11:27 |
dimitern | rogpeppe: it also applies to the other proxy objects, like service, etc. | 11:28 |
dimitern | rogpeppe: only for units and services? | 11:28 |
rogpeppe | dimitern: any types which have String defined on them in state, i guess | 11:29 |
dimitern | rogpeppe: and they should return names, not tags | 11:29 |
rogpeppe | dimitern: i think so | 11:29 |
rogpeppe | dimitern: reviewed | 11:30 |
dimitern | rogpeppe: will add them next then, along with other stuff | 11:30 |
dimitern | rogpeppe: ta | 11:30 |
jam | dimitern, rogpeppe: https://plus.google.com/hangouts/_/f497381ca4d154890227b3b35a85a985b894b471 standup? | 11:33 |
jamespage | hazmat, thanks for the licensing update for jujuclient btw - I just uploaded that and juju-deployer + websocket-client to saucy | 11:36 |
hazmat | jamespage, awesome, thanks | 11:37 |
dimitern | anybody seen this debug hooks test failure? http://paste.ubuntu.com/6006151/ | 11:57 |
jam | dimitern: I haven't seen it before, though it does look like one of those "it should take 100ms but real-world variability is higher than that". At the least, we need a better message because that is *really* hard to read. | 12:01 |
dimitern | jam: +1 | 12:02 |
hazmat | looks like its got a skew of 1s | 12:02 |
jam | wallyworld_: so the bot seems to say "parse-tools-simplestreams" has already been merged | 12:08 |
jam | which is why it isn't merging it again, I'll poke a bit more. | 12:08 |
wallyworld_ | jam: i got a singlr LGTM, so i laned it today | 12:09 |
jam | wallyworld_: k, looks like LP didn't notice, and I'm not sure why that is. | 12:10 |
dimitern | rogpeppe: the String()s are here https://codereview.appspot.com/13079044 | 12:26 |
wallyworld_ | jam: sorry, just got off the call, is lp sorted out with the merge? | 12:37 |
smoser | jam, axw there is no plan to put write_files into 12.04. features don't really qualify for SRU, but we could make that happen if it was terribly useful. | 12:47 |
axw | smoser: IMHO it's not worth the trouble - it's not a big deal to continue doing what we're doing. | 12:48 |
axw | (not worth the trouble to update 12.04's cloud-init) | 12:49 |
smoser | what is it that you'ore doing ? | 12:49 |
axw | just writing out rsyslog config files | 12:49 |
axw | there was a bug in our script that was writing the files; they were using echo, which happened to be the shell's builtin | 12:50 |
axw | and it was interpreting \n | 12:50 |
axw | that shell was dash, evidently. whereas bash's builtin, and /bin/echo don't interpret by default | 12:50 |
dimitern | rogpeppe: ping | 12:55 |
jam | wallyworld_: I think I sorted LP out. | 13:04 |
wallyworld_ | great | 13:04 |
geme | I'm moving over to juju-core - are there any docs / blogs that explain the key changes ? | 13:05 |
TheMue | geme: the repository contains a doc dir with some very helpful files | 13:06 |
andrew_w_deane | rogpeppe: hi. I'm testing against the api using a local provider and I'm getting "unknown provider type local" errors. I was under the impression that the local provider was supported now. | 13:08 |
geme | TheMue: Thanks | 13:08 |
natefinch | allenap: got a minute for a juju - azure environ question? | 13:09 |
rogpeppe | andrew_w_deane, dimitern: sorry, was at lunch | 13:17 |
allenap | natefinch: Sure, go for it. | 13:17 |
andrew_w_deane | rogpeppe: no worries. | 13:17 |
rogpeppe | andrew_w_deane: what are you trying to do, exactly? | 13:17 |
rogpeppe | dimitern: pong | 13:17 |
natefinch | allenap: I'm trying to test a new method I added to the azure environ to return the addresses (hostname and ips) of instances | 13:18 |
natefinch | allenap: testing the azure stuff seems to use gwacl.PatchManagementAPIResponses to mock out the responses from the server, but I'm having difficulty getting it to do exactly what I want | 13:19 |
allenap | natefinch: Yeah, it's rather involved. | 13:20 |
natefinch | allenap: let me whip up a pastebin so you can see what I'm doing | 13:20 |
allenap | natefinch: Cool. | 13:21 |
dimitern | rogpeppe: did you have a chance to look at it? | 13:21 |
rogpeppe | dimitern: only briefly, will do soon | 13:21 |
dimitern | rogpeppe: ok, thanks | 13:21 |
* dimitern bbiab | 13:22 | |
natefinch | allenap: http://pastebin.ubuntu.com/6006401/ | 13:23 |
natefinch | allenap: the problem is that the test isn't getting the IP address returned from the call to Addresses.... even though I'm creating the deployment with the RoleInstanceList with a RoleInstance that has the IP Address set | 13:25 |
natefinch | allenap: sorry, that Addresses function was half modified... here's the one that actually compiles ;) http://pastebin.ubuntu.com/6006409/ | 13:28 |
smoser | axw, i dont think cloud-init was getting in your way, was it ? | 13:29 |
smoser | the message https://code.launchpad.net/~axwalk/juju-core/lp1212148-cloudinit-escapes/+merge/180988 implies cloud-init | 13:30 |
allenap | natefinch: I'm going to patch this in and fire it up. | 13:30 |
rogpeppe | smoser: will cloudinit interpret backslashes inside single quotes ? | 13:30 |
natefinch | allenap: I haven't actually tested the code against a real azure environment... that was going to be my next question :) | 13:30 |
natefinch | allenap: and thanks :) | 13:31 |
smoser | well, cloud-init reads yaml (through python-yaml). | 13:31 |
rogpeppe | smoser: hmm, sorry, yes, was thinking of upstart | 13:31 |
smoser | afaik, cloud-init correctly escapes commands in 'runcmd' or bootcmd when it writes the run script. | 13:31 |
smoser | rogpeppe, whenever i have to deal with fighting multiple levels of escaping (which i dont think cloud-init is actually giving you pain itself here), i often just base64 encode stuff. | 13:32 |
rogpeppe | smoser: yeah, that's always an option | 13:33 |
smoser | echo BASE64_ENCODED_STUFF | base64 --decode > output | 13:33 |
rogpeppe | smoser: assuming the base64 command is provided by default | 13:33 |
axw | smoser: yeah I mistook it to be the culprit, it's not a cloud-init problem at all | 13:33 |
smoser | $ dpkg -S `which base64` | 13:34 |
smoser | coreutils: /usr/bin/base64 | 13:34 |
axw | sorry, didn't mean to blemish your good name :) | 13:34 |
smoser | $ apt-cache show coreutils | grep Ess | 13:34 |
smoser | Essential: yes | 13:34 |
smoser | what that means is your'e extremely unlikely to find a debian or ubuntu system without coreutils. | 13:34 |
rogpeppe | smoser: ok, that's good to know, thanks | 13:34 |
smoser | and iirc busybox even provides 'base64' | 13:34 |
axw | I did consider base64'ing it | 13:35 |
axw | no good reason not to I suppose, just didn't want to obfuscate the data and make debugging *slightly* more onerous | 13:35 |
rogpeppe | smoser: i think the problem was actually in the echo command | 13:35 |
rogpeppe | smoser: which is, as we know of old, problematic | 13:36 |
rogpeppe | smoser: so we're going to use printf(1) | 13:36 |
smoser | yeah, i was going to suggest that too. | 13:36 |
smoser | printf "%s" "whatever-wont-get-interpreted-here" | 13:37 |
rogpeppe | smoser: sad really, but yes, that's the preferred solution | 13:37 |
rogpeppe | smoser: let's blame SysV | 13:38 |
smoser | it not sad. | 13:38 |
natefinch | allenap: I actually have to head out for probably an hour to an hour and a half. If you need to do something more pressing, please feel free, but any help would be much appreciated. I'm sure I'm just doing something wrong in setting up the test (whether or not the actual function is correct is another matter). | 13:38 |
rogpeppe | smoser: it's a bit sad that echo is not fit for purpose. "you only had one job" and all that. | 13:38 |
allenap | natefinch: I'll look at in the meantime. It's good actually; you're not blocked while you're out :) | 13:39 |
natefinch | allenap: thanks, I appreciate it :) | 13:39 |
=== natefinch is now known as natefinch-afk | ||
smoser | rogpeppe, fair enough :) | 13:39 |
=== robbiew1 is now known as robbiew | ||
smoser | but printf just has one job too. | 13:39 |
smoser | and it does what you want. | 13:40 |
axw | long live the mp, the mp is dead | 13:41 |
allenap | natefinch-afk: http://paste.ubuntu.com/6006470/ is my solution. Addresses() calls GetDeployment(), which only expects a single deployment to be returned. | 13:48 |
allenap | natefinch-afk: Fwiw, where you do `if len(d.RoleInstanceList) > 0 {` I suggest you instead loop. There *should* only be one instance, but my spidey senses think it'll be easier to debug if someone does start another instance in the deployment (by hand, for example). I'm not sure that Azure promises ordering of instance lists. | 13:51 |
mgz | yeah, I agree with that | 13:53 |
jamespage | mgz, fwereade: hey - I just uploaded golang 1.1.2 to saucy - I'm guessing that you guys want that in the Juju golang PPA right? | 14:04 |
mgz | jamespage: that would be ace | 14:05 |
fwereade | jamespage, yes please :) | 14:05 |
jamespage | mgz, also fixes up some problems with os/user | 14:05 |
jamespage | fwereade, mgz: OK _ as soon as it lands in the release pocket I'll do the backports | 14:06 |
mramm | mgz: jamespage: what do you guys think about a short network addressability sprint in your hometown? | 14:06 |
fwereade | dimitern, hey, mea culpa for lazy reviewing, but an error on .Count() does not mean "ehh pretend not in scope" it means "something went wrong, report it" | 14:06 |
fwereade | dimitern, (in InScope) | 14:06 |
jamespage | mramm, depends when | 14:06 |
mramm | jamespage: I know you have a "life event" coming | 14:07 |
mramm | jamespage: but I don't remember when (sorry) | 14:07 |
mgz | these events have a habit of not turning up quite when expected as well :) | 14:08 |
mgz | sounds like a neat idea if james can fit it in though | 14:09 |
mramm | mgz: jamespage: yea, and I think it would be worth doing even if james can't come | 14:12 |
jamespage | mramm, probably this week :-) | 14:13 |
mramm | jamespage: cool. How much family leave time are you thinking you will take? | 14:13 |
jamespage | mramm, 2 weeks | 14:14 |
mramm | cool | 14:14 |
mramm | so I was thinking about mid september for a network addressability sprint | 14:14 |
mramm | well, actually jam suggested it | 14:14 |
dimitern | fwereade: hmm, then how come all tests pass? :) | 14:28 |
fwereade | dimitern, because you implemented it to ignore errors | 14:29 |
dimitern | fwereade: :) | 14:29 |
fwereade | dimitern, we aren't encountering errors under test conditions | 14:30 |
dimitern | fwereade: ok, I see your point, will change it to return an error and a bool | 14:30 |
fwereade | dimitern, thanks :) | 14:31 |
=== tasdomas is now known as tasdomas_afk | ||
mramm | natefinch-afk: ping me when you get back RE: windows client | 14:39 |
* axw snores | 14:43 | |
axw | night folks | 14:43 |
=== BradCrittenden is now known as bac | ||
=== natefinch-afk is now known as natefinch | ||
natefinch | allenap, mramm: I'm back | 14:56 |
allenap | natefinch: I replied soon after you afk'ed. Ping again if you didn't get it. | 14:57 |
natefinch | allenap: saw it. | 14:58 |
allenap | Cool. | 14:58 |
natefinch | allenap: not sure how we'd handle that... should we return all addresses of all instances? | 14:58 |
natefinch | allenap: if not, how do we detect which one is "ours"? | 14:59 |
mgz | natefinch: in practice, there should only be one instance | 15:00 |
mgz | but we at least want some handling of len()!=1 in case something is weird | 15:01 |
natefinch | mgz: right now I handle zero and > 0 :) for > 0 I just pick the first one. If there's a better way to handle 2+, I'm all for it | 15:01 |
allenap | natefinch: What mgz said. I think it would be better to return all the addresses instead of the first of an unordered list. Maybe better yet would be to return an error. | 15:02 |
natefinch | allenap: an error sounds good to me. Indicates someone mucked with our environment | 15:03 |
fwereade | rogpeppe, jam, I'd appreciate your thoughts on https://codereview.appspot.com/12841044 -- particularly the question in the description | 15:03 |
allenap | natefinch: Yeah, good point, I agree. | 15:03 |
fwereade | rogpeppe, jam: it's a step towards https://bugs.launchpad.net/juju-core/+bug/1192433 | 15:03 |
_mup_ | Bug #1192433: relation-list reporting dying units <jujud> <relations> <juju-core:Triaged by fwereade> <https://launchpad.net/bugs/1192433> | 15:03 |
natefinch | allenap, mgz: sorry, brb, gotta help with emergency diaper duty | 15:04 |
allenap | natefinch: Heh, I know what that's like. Go! :) | 15:04 |
fwereade | rogpeppe, jam: I'm not quite sure whether this is a good point at which to introduce a provider/requirer asymetry -- can you think of potential issues there? | 15:05 |
rogpeppe | fwereade: that was the first thought that crossed my mind too | 15:05 |
fwereade | rogpeppe, my heart is saying you should PrepareLeaveScope if you're a peer or a provider, but not if you're a requirer | 15:07 |
rogpeppe | fwereade: i'm not sure | 15:07 |
rogpeppe | fwereade: but it's a difficult call | 15:07 |
natefinch | mgz, allenap: back, crisis averted ;) | 15:10 |
fwereade | rogpeppe, my problem is that I'm not seeing a great deal of difficulty in the call, but I feel like I might be missing something ;) | 15:10 |
rogpeppe | fwereade: i can't think of any argument that applies to providers that doesn't apply to requirers too | 15:10 |
rogpeppe | fwereade: a requirer could very easily set up creds for a provider, for example | 15:11 |
fwereade | rogpeppe, it *could* but that would be very annoying ;p | 15:11 |
fwereade | rogpeppe, I guess that's the problem with having left it wide open thus far | 15:11 |
rogpeppe | fwereade: how do you mean? | 15:11 |
rogpeppe | fwereade: annoying for us as developers? | 15:11 |
fwereade | rogpeppe, annoying for anyone who takes the meanings of provide/require at face value really | 15:12 |
rogpeppe | fwereade: i do find the provider-requirer thing a bit odd (you can have a requirer with a relation to several providers, right?) | 15:12 |
rogpeppe | fwereade: but i find it particularly difficult trying to second guess how people might be using our primitives | 15:13 |
rogpeppe | fwereade: maybe we should do this for peer relations only | 15:15 |
rogpeppe | fwereade: the other question is: why does querying a dying unit fail? | 15:16 |
rogpeppe | fwereade: if we made that work, would your CL be necessary? | 15:16 |
fwereade | rogpeppe, I read that to mean "the dying unit is busy shutting down replication, and an app-level attempt to connect fails" | 15:18 |
rogpeppe | fwereade: ah, i see, yes | 15:18 |
fwereade | rogpeppe, so I don't think that's something we can affect | 15:18 |
rogpeppe | fwereade: another possiblity would be to add a flag to relation-list to allow it to ask for only alive units | 15:19 |
rogpeppe | fwereade: that way a charm could exclude dying units at its own discretion | 15:20 |
rogpeppe | fwereade: and we wouldn't need to break symmetry | 15:20 |
fwereade | rogpeppe, I think that'd be somewhat challenging | 15:20 |
fwereade | rogpeppe, from the charm perspective, it introduces a whole new concept, and I'd need to think pretty hard before I was sure that didn't introduce its own sources of confusion | 15:21 |
rogpeppe | fwereade: i think i'd be inclined to make this happen for peer relations only, addressing the specific use case the bug talks about | 15:27 |
rogpeppe | fwereade: you're assuming that requirer-provider implies client-server, but that's by no means the only possibility | 15:28 |
fwereade | rogpeppe, I *think* that all I'm assuming is that it means requirer-provider, but I'm probably being dense; expand? | 15:29 |
rogpeppe | fwereade: well, AFAICS, the situation you're concerned about it this: | 15:31 |
mgz | allenap: any ideas on bug 1214451? | 15:32 |
_mup_ | Bug #1214451: Unable to bootstrap maas environment <juju-core:New> <https://launchpad.net/bugs/1214451> | 15:32 |
rogpeppe | fwereade: provider sees requirer go away, so shuts off access, but requirer is still shutting down and tries to access the provider to flush any final information, but it can't | 15:32 |
rogpeppe | fwereade: because access is shut off | 15:32 |
rogpeppe | fwereade: is that an accurate representation? | 15:32 |
fwereade | rogpeppe, yeah | 15:32 |
rogpeppe | fwereade: so, i don't really see how that logic doesn't work the other way around too (with "requirer" swapped with "provider") | 15:33 |
fwereade | rogpeppe, well, it does indeed all hinge on the naming, that a "provider" is expected to "provide" something that a "requirer" "requires" ;) | 15:33 |
dimitern | fwereade: quick review? https://codereview.appspot.com/12782045 | 15:34 |
fwereade | rogpeppe, and that it's not a problem if something not required is not present, but the converse does not hold | 15:34 |
allenap | mgz: My guess is that it's trying to create an empty provider-state, but for some reason MAAS forbids an empty file. Sigh. It's probably our fault, but you never know because Django gets flustered at the difference between "" and None. I'll investigate... | 15:35 |
rogpeppe | fwereade: i think that's perhaps a step too far - it's that a resource that we knew about is going away, and we want to be able to shut down in an orderly manner | 15:35 |
rogpeppe | fwereade: and that seems to apply for both requirers and providers | 15:36 |
mgz | allenap: a django version difference also sounds like a good bet | 15:36 |
mgz | natefinch: you have a moment for a quick catchup in a sec? we can do kanbany things while we're at it | 15:38 |
fwereade | rogpeppe, it still STM that providing something not required is fine; but requiring something not provided is a problem | 15:38 |
fwereade | rogpeppe, this discussion is I guess orthogonal to the practical question of "how many relations are implemented backwards" | 15:38 |
fwereade | dimitern, LGTM btw | 15:39 |
rogpeppe | fwereade: ... or "how many charms shut off all access on relation-departed?" | 15:39 |
dimitern | fwereade: ta | 15:39 |
fwereade | rogpeppe, well, those that do will I think be helped by this change, so long as they're defined the natural way round; those that don't won't care, AFAICS | 15:40 |
natefinch | mgz: sure | 15:40 |
rogpeppe | fwereade: i was thinking of applying this change across the board | 15:41 |
mgz | natefinch: same hangout as this morning? | 15:41 |
rogpeppe | fwereade: and wondering how many things would break | 15:42 |
natefinch | sure | 15:42 |
fwereade | rogpeppe, to consciously and deliberately remove a requirer's, er, requirements, seems a little perverse though | 15:43 |
fwereade | rogpeppe, even if nothing broke it'd cause the relationship to make less sense | 15:43 |
rogpeppe | fwereade: well, the requirements are going away in a moment anyway | 15:43 |
allenap | mgz: I want Django to die in a lake of burning acid, but that doesn't help here. Raphaël landed a fix in r1540 to allow empty files. jamespage, can you use ppa:maas-maintainers/dailybuilds instead? | 15:43 |
jamespage | allenap, OK - let me try | 15:44 |
fwereade | rogpeppe, yeah, the other perspective is "this is the same as an independent breakage of some unit, and we should WONTFIX it, because charms have to handle that anyway" | 15:44 |
rogpeppe | fwereade: the question is whether it's important that we get told that they've gone away *after* they've entirely shut down, or before they start to shut down | 15:44 |
fwereade | rogpeppe, but I think it's unhelpful to enforce a model that obscures that (IMO) real distinction | 15:45 |
rogpeppe | fwereade: the difficulty is that there's no right answer | 15:46 |
rogpeppe | fwereade: both answers to the question "what are the active units in this relation" are equally valid | 15:47 |
mgz | hm, nate still isn't in the list of users that I canassign cards to on the kanban board? | 15:47 |
mgz | fwereade: I don't suppose you have the right kanban access to fix that? | 15:48 |
fwereade | mgz, I don't *think* so but I'll try to poke around | 15:48 |
fwereade | mgz, if I can I can't figure out how | 15:51 |
fwereade | mgz, *but* he seems to be on the list -- just pushed off the bottom of the quick-access submenu | 15:51 |
mgz | that worked, thanks! | 15:51 |
fwereade | rogpeppe, well, we do already define the reality we present to the charm, and what we show doesn't necessarily bear much relation to what's really going on | 15:52 |
fwereade | rogpeppe, units can be available for a long time before a related unit knows about them, for example | 15:52 |
rogpeppe | fwereade: yeah. | 15:55 |
rogpeppe | fwereade: i think it's worth a post to the mailing list | 15:57 |
rogpeppe | fwereade: interestingly my changes to the watcher logic exposed a bug in cleanupWatcher | 16:07 |
rogpeppe | fwereade: it didn't coalesce events | 16:07 |
fwereade | rogpeppe, ha :) nicely done then | 16:08 |
fwereade | rogpeppe, ah, hmm, looking at that code I have something knocking at the back of my mind | 16:09 |
rogpeppe | fwereade: the watcher code? | 16:09 |
fwereade | rogpeppe, the cleanup watcher | 16:09 |
rogpeppe | fwereade: oh yes? | 16:10 |
fwereade | rogpeppe, all I can remember is that it was implemented as simply as possible for some specific reason | 16:11 |
rogpeppe | fwereade: hmm | 16:11 |
rogpeppe | fwereade: perhaps we don't really care if we receive two cleanup events | 16:11 |
fwereade | rogpeppe, that's basically it -- a Cleanup() with nothing to clean up is cheap enough that we don't really care | 16:11 |
fwereade | rogpeppe, but, that said, there's no reason *not* to coalesce | 16:12 |
rogpeppe | fwereade: hmm, i could just fix the test | 16:12 |
fwereade | rogpeppe, I'm pretty sure it predated collect anyway, and the introduction of collect was not done across the board | 16:12 |
rogpeppe | fwereade: (although it was no hassle to make it call collect) | 16:12 |
fwereade | rogpeppe, I think a collect is a good idea tbh | 16:12 |
fwereade | rogpeppe, ah wait | 16:13 |
rogpeppe | fwereade: (the only awkward bit was that collect assumed string keys, but that wasn't a problem to change) | 16:13 |
fwereade | rogpeppe, let's go with it | 16:13 |
=== teknico1 is now known as teknico | ||
=== TheRealMue is now known as TheMue | ||
TheMue | Ah, found my silly mistake. *phew* | 16:30 |
natefinch | rogpeppe: easy one, if you have time - https://codereview.appspot.com/13126043 | 16:41 |
natefinch | mgz: back | 16:41 |
rogpeppe | natefinch: looking | 16:42 |
mgz | natefinch, rogpeppe: also an easy one https://codereview.appspot.com/12741048 | 16:44 |
natefinch | rogpeppe: checker was needed for my next couple changesets | 16:44 |
rogpeppe | natefinch: isn't it O(n³) in fact ? | 16:44 |
rogpeppe | natefinch: (not that it matters much, probably) | 16:45 |
natefinch | rogpeppe: yeah with the reslicing, yeah, you're right | 16:46 |
natefinch | rogpeppe: moral of the story, keep n under 10 and you won't notice | 16:46 |
rogpeppe | natefinch: i think you can keep the amount of code about the same and still be O(n*log(n)) | 16:47 |
natefinch | rogpeppe: you going to make me sort the slices? | 16:48 |
rogpeppe | natefinch: nope (you can't do that easily) | 16:48 |
natefinch | rogpeppe: right, that's why I didn't :) Sure, lay it on me | 16:48 |
rogpeppe | natefinch: just sketching it | 16:48 |
mgz | natefinch: I think I win my bet :) | 16:49 |
natefinch | mgz: haha yep | 16:49 |
natefinch | rogpeppe: just saying... you're optimizing something that is only used in tests and likely only ever used on n < ~5 | 16:49 |
mgz | but it's fun! | 16:50 |
rogpeppe | natefinch: it should make the code more obviously correct too | 16:51 |
natefinch | rogpeppe: I'm all for more obviously correct. I know it's not the prettiest right now, but the algorithm is pretty simple | 16:51 |
rogpeppe | natefinch: something like this? http://paste.ubuntu.com/6007096/ | 16:54 |
rogpeppe | natefinch: i *think* that should be sufficient, but i might be missing something | 16:55 |
rogpeppe | natefinch: i have to go in exactly 3 minutes | 16:57 |
natefinch | rogpeppe: ok no big deal | 16:57 |
natefinch | rogpeppe: I'll test that out | 16:57 |
rogpeppe | natefinch: does that paste make sense? | 16:57 |
natefinch | rogpeppe: yep. | 16:57 |
rogpeppe | natefinch: essentially we just need to check that each slice has the same number of each item | 16:57 |
natefinch | rogpeppe: yep | 16:58 |
rogpeppe | mgz: i think the simpler code is worth it, even despite the performance difference, which i don't really care about. | 16:58 |
mgz | rogpeppe: I do agree really, also fun is worth it :) | 17:00 |
rogpeppe | mgz: :-) | 17:00 |
mgz | rogpeppe: go now :) | 17:00 |
natefinch | rogpeppe: thanks | 17:00 |
rogpeppe | mgz: yes, my wife has a bottle of cold champagne up my back - it's our anniversary and i really must | 17:01 |
rogpeppe | g'night all | 17:01 |
natefinch | rogpeppe: enjoy! | 17:01 |
hazmat | jamespage, try again re builldd on 0.7 rel branch, i was able to get through a ppa build of the same branch. there is some vagary based on buildd performance and running the test suite reliably. unfortunately its impossible to trigger outside of the buildd envs. | 17:02 |
mgz | hazmat: that's pretty much what I found previously ;_; | 17:02 |
mgz | gah! | 17:13 |
natefinch | mgz: btw, I got azure working with some help from allenap... he had posted a fix that I missed earlier | 17:25 |
mgz | ace | 17:29 |
thumper | morning | 21:00 |
thumper | mramm: ping? | 21:09 |
sidnei | thumper: around? | 22:05 |
sidnei | ah, nm. found https://code.launchpad.net/~themue/juju-core/037-empty-strings-in-charm-config/+merge/178318 | 22:07 |
thumper | hi sidnei | 22:30 |
thumper | was putting on slow cook asian pork for dinner in the slow cooker | 22:31 |
sidnei | got bitten by the bug above | 22:35 |
sidnei | with juju-deployer and setting '' | 22:35 |
sidnei | changed to ' ', which did the trick, but /o\ | 22:35 |
fwereade | sidnei, it's been languishing a bit, TheMue was on holiday for a couple of weeks, but he's back and actively on it AIUI | 22:40 |
sidnei | fwereade: thanks! | 22:40 |
thumper | fwereade: you wouldn't believe how long it takes to unpick the dependencies on structs across packages | 22:47 |
mramm | thumper: sorry, lost track of time | 23:00 |
fwereade | thumper, oh, I would, that's why I tend to give up before I start :( | 23:02 |
mramm | fwereade: hahaha | 23:03 |
Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!