/srv/irclogs.ubuntu.com/2012/08/20/#juju-dev.txt

fwereade_davecheney, if you are bored and listless at any time, you might enjoy taking a look at https://codereview.appspot.com/646011002:29
fwereade_davecheney, which has a real live uniter inside :)02:29
davecheneyfwereade_: will do02:31
mrammfwereade_: impressive02:36
Arammorning.06:40
davecheneyhowdy06:44
Aramso10:48
Aramwhen is the release meeting?10:48
Aramin 70 minutes?10:49
davechen1yAram: tomorrow at 9pm AEST I thought10:49
davechen1ymramm: is that correct ?10:50
TheMueAram, davechen1y: tomorrow after the regular weekly10:53
AramI see.10:53
TheMueAram: Just accept the mail invitation and your calendar will show it.10:54
Aramtoo much trouble to regenerate a new password or two factor auth or whatever we use now.10:54
* Aram hates this crap10:54
TheMueAram: It's a simple google account. Once setup and ok. I like it all networked, so I always see all our appointments and my private one in my desktop appl as well as on my phone.10:56
AramI've setup it once, but for some reason it doesn't remember my password so I have to enter it all the time.10:57
Aramand because it's a random password I don't remember it.10:57
TheMueAram: That's why I don't have random passwords.10:59
Aramyeah, but for some reason I can only use the canonical provided password, couldn't change it.11:00
TheMueAram: The calendar is a google accout and it can be changed, once you switched to this account.11:00
TheMueAram: And random pwds are always hard to remember and don't interest brute force attacs. So I choose long ones with stupid sentences like TheQuickBrownFoxJumpsOverTheLazyDog.11:02
TheMueAram: But only more stupid. ;)11:02
TheMuethats strange: when NOT closing a watcher channel, the according test for the closed watcher fails, so far ok. but when I add the closing a test for unexpected changes fails, that's executed BEFORE the watcher is stopped (and the channel closed). *dunno*11:57
fwereade_TheMue, sounds like a bug to me :)11:58
TheMuefwereade_: yeah, but what kind of bug? it's in the SRW. your added tests like assertNoChange(), which mostly work fine.12:00
TheMuefwereade_: funnily the fail happens after the w.Stop(), but the test is befor.12:00
fwereade_TheMue, ServiceRelationsWatcher?12:00
TheMueoh, have to break for a moment, the technician for our heating is there.12:00
TheMuefwereade_: yes12:00
fwereade_TheMue, I can take a look if yu give me a pointer to the branch12:01
fwereade_TheMue, but I guess what it *sounds* like is some actual error is killing the watcher at an unhelpful time... is that possible12:02
TheMuefwereade_: I changed almost nothing in your test, only regarding Kill() and Die(). but the watcher now works differently. i'll paste it.12:15
TheMuefwereade_: http://pastebin.ubuntu.com/1157107/ line 56 fails12:16
TheMuefwereade_: without closing the change channel line 69 fails12:16
fwereade_TheMue, ok, so it's line 56 that gets an unexpectedly closed channel; does that not surely indicate that something has suffered some sort of error caused by the relation removal?12:18
fwereade_TheMue, try heavy logging in the watcher to figure out why it dies?12:19
TheMuefwereade_: line 56 get's no closed channel, it receives an unexpected change of "nothing"12:20
fwereade_TheMue, if the watcher isn't dying I think there's definitely something weird going on12:20
fwereade_TheMue, then that just sounds like the watchers is sending something it shouldn't12:20
TheMuefwereade_: i already logged around the sending (there's only one point), but it isn't explicity called12:21
fwereade_TheMue, ok, for us to receive, either we are sending or we are closing, right?12:21
fwereade_TheMue, if you have verified we are not sending, surely we are closing, which implies that something is killing the watcher12:22
TheMuefwereade_: sorry, don't understand12:22
TheMuefwereade_: ah, now it gets more clear12:22
fwereade_TheMue, ok, the problem is that the test receievs an unwanted event on the changes chan, yeah?12:22
TheMuefwereade_: then i already have an idea, one moment12:22
fwereade_TheMue, defer a log of w.tomb.Err just before you start the loop maybe?12:23
fwereade_TheMue, fwiw I suspect something is manipulating a relation after it's removed12:25
TheMuefwereade_: one moment please, test is running12:26
TheMuefwereade_: hehe, it passes12:28
TheMuefwereade_: it has indeed been a wrong handling of a dying relation life watcher. i signaled the SRWs tomb to kill itself12:30
TheMuefwereade_: instead only doing so in case of an error12:30
fwereade_TheMue, ha, bad luck12:30
TheMuefwereade_: so i can propose the new SRW now12:31
TheMuefwereade_: it behaves a bit different than you wanted it to do12:31
* fwereade_ raises an eyebrow12:32
fwereade_TheMue, would you hit the high points please?12:32
TheMuefwereade_: as i get the events of alive/dying/dead by individual life watchers you don't get them bundled12:32
fwereade_TheMue, as long as it's the same event, but it just happens to have a single change at a time, that is just fine, so long as we still get a bundle for the first event12:33
TheMuefwereade_: the SRW can't know when the last event will be received, so it just sent what it gets.12:33
fwereade_TheMue, I don't mind individual item events in any except the first event12:33
fwereade_TheMue, is the first event getting the proper state?12:34
TheMuefwereade_: the life watcher sends a first proper event, but individual12:34
TheMuefwereade_: so if the watcher starts and 5 relations are active you'll get 5 'alive' events12:35
fwereade_TheMue, so when I do <-s.WatchRelations().Changes(), I get something different to when I call s.Relations()?12:35
fwereade_TheMue, that can't work, sorry12:35
TheMuefwereade_: see line 74ff12:35
fwereade_TheMue, I will think about it a bit, but offhand I'm not sure how I can make that work12:36
fwereade_TheMue, I would strongly favour something that worked like presence.ChildrenWatcher12:36
TheMuefwereade_: the problem would have been the same in the SRW. i would have to store the startup state, ignore the alive events for all those of the startup state and then contine sending those which are not part of the startup12:38
fwereade_TheMue, that sounds sensible to me, what's the issue with it?12:39
TheMuefwereade_: the SRW is so beautiful clean now, it would make it more complex. :D12:40
fwereade_TheMue, it doesn't matter how simple it is if it doesn't do what we need ;p12:41
TheMuefwereade_: just define your requirement new *lol*12:41
fwereade_TheMue, I will think on how I can work with those events but I'm pretty strongly -1 on implementing just this watcher completely differently from all the others12:41
TheMuefwereade_: sorry, it ISN'T completely different, absolutely not12:42
fwereade_TheMue, initial event?12:42
fwereade_TheMue, that seems like a pretty vast semantic change to me12:42
TheMuefwereade_: a change yes, but the word completely is too strong12:43
fwereade_TheMue, well, all other watchers send an initial event that represents the state, and then send diffs12:43
fwereade_TheMue, this sends a sequence of initial events representing the state, and at someunknowable point starts sending diffs12:44
TheMuefwereade_: This one also sends an initial even, only sadly per relation12:44
fwereade_TheMue, and how is a client meant to know when they've consumed that initial state?12:44
TheMuefwereade_: but i understand your reason and will change it12:45
* fwereade_ is relieved :)12:45
fwereade_TheMue, if you look at RelationUnitsWatcher you should see a similar model in place12:45
fwereade_TheMue, rather than what you described earlier, I would suggest: ignore initial state except to start a watcher for each; consume the initial events on each of those watchers, and collate those into the initial event; send the watches over to their own goroutines for further processing12:47
fwereade_TheMue, sorry, s/send the watches over to their own goroutines/start a goroutine for each watch/12:48
fwereade_TheMue, sane?12:48
TheMuefwereade_: that's already running, but the first part sound's good12:48
TheMuefwereade_: consuming the initial events.12:48
fwereade_TheMue, have a look at RUW -- it's undeniably more complex but I think it still works out pretty clean12:49
mrammwell, I went back to my room for a nap at 5pm after the pycon sprints before dinner12:51
mrammand just woke up with a fever, sore throat, sinus problems, etc12:52
mrammI thought I was just tired from the jetlag12:52
* Aram is too hungry for the time of the day.12:52
niemeyerMorning!13:14
fwereade_niemeyer, heyhey13:14
fwereade_mramm, ouch :(13:14
mrammniemeyer: morning13:15
mrammfwereade_: yea I hate being sick while traveling13:15
fwereade_mramm, it sucks :(13:15
niemeyerI personally hate being sick. Period. :-)13:17
TheMueniemeyer: morning13:22
TheMuefwereade_: another question: think of service s1 having relations r1 and r2, both are alive13:23
TheMuefwereade_: i get the SRW of s1, and now wait for the first events of r1 and r2. i get r1 as alive and now wait for r2. but during this time i get a r1 as dying13:24
TheMuefwereade_: so after reciving alive from r2 i send r1 as dying and r2 as alive, ok?13:24
fwereade_TheMue, if you get a second event on one of the it should be happening on its own goroutine13:25
TheMuefwereade_: yes, it will, and the srw collects it13:26
fwereade_TheMue, surely it shouldn't collect it until it has finished handling the initial state?13:26
TheMuefwereade_: otherwise i would send you the dying as a single event before the inital event is out (while waiting for the last life watcher)13:26
TheMuefwereade_: please rephrase13:27
fwereade_TheMue, surely you should use an intrnal channel to marshal the subgoroutine events onto the main goroutine13:27
TheMuefwereade_: i do so, yes13:27
fwereade_TheMue, surely therefore you would not even pick them up for sending until you'd finished the initial event creation on the main goroutine13:28
TheMuefwereade_: and here i talk about getting 2 or more events of r1 before r2 (which is also part of the initial state) sent its first life13:28
fwereade_TheMue, why is it relevant that you got more than one event? maybe you did, and the sub-goroutine is trying to send it to the main one, but the main one won't pick it up until it hits its main select again13:29
TheMuefwereade_: i am in the main select loop13:29
fwereade_TheMue, have you looked at what RUW does?13:29
fwereade_TheMue, most of what I say is attempts to helpfully translate that into english :)13:30
fwereade_TheMue, but, ok, you've just got an initial event that indicates that N relations exist13:31
TheMuefwereade_: may i describe how it works now (before i turn everything around)?13:31
fwereade_TheMue, surely you go through each of those relations, consuming event and starting goroutine, and send the collected initial state, all before you leave the current case?13:32
fwereade_TheMue, please do :)13:32
fwereade_TheMue, your knowledge will be better than my guesses :)13:32
TheMuefwereade_: when the srw starts it watches the topology, as before, and retrieves the relations of the service. for each relation a lifewatcher in an own goroutine is started.13:33
fwereade_TheMue, ah, OK, to get what we need I think you need to start all the watchers on the main goroutine to consume the initial events13:33
TheMuefwereade_: the all write their events back to the srw in one channel, where the srw collects then and sends the changes to the receiver of Changes()13:33
fwereade_TheMue, only once you have consumed the first event do you start a new goroutine to handle the subsequent ones13:34
TheMuefwereade_: yes, that my question, please wait with writing13:34
fwereade_TheMue, sorry13:34
TheMuefwereade_: now, as you wrote above, i want to consume the first events of those life watchers before sending it combined as the initial state to you13:35
TheMuefwereade_: the question is now, that it may happen, that the state of r1 changes before r2 is received.13:36
fwereade_TheMue, yes, that can happen if you don't start the life watches on the main goroutine13:36
TheMuefwereade_: but because i'm in the same loop i receive it.13:36
fwereade_TheMue, right, so... don't do it that way :)13:37
TheMuefwereade_: ah, ok, ic, while setting the life watchers i directly wait blocking on their first event13:38
fwereade_TheMue, yeah, sorry unclear13:38
TheMuefwereade_: eh, sorry, i wanted to say that, when setting up the life watcher for a relation I immediatelly wait for its first event. so after setting up the first set i've got all first life states.13:40
TheMuefwereade_: that will be sent then and afterwards the single events of the life watchers13:41
niemeyerfwereade_, TheMue: I was following but didn't want to interrupt, but seems like we've reached agreement now13:46
niemeyerfwereade_, TheMue: I'm curious about what's the case there, given we'll be doing things slightly differently soon13:46
fwereade_niemeyer, sorry, I'm not sure what you're asking13:47
TheMueniemeyer: we talked about the service relation watcher, which will handles the lifecycles of realations13:48
niemeyerfwereade_: I'm wondering what the underlying issue being debated above is about13:48
TheMueniemeyer: and william and i discussed about how to get a propper initial state and then only diffs13:48
niemeyerfwereade_: Trying to load mind state since we have to do that stuff in mstate13:49
fwereade_niemeyer, just "should a watcher always send initial state as a single event" -- I feel that is part of the definition of a watcher13:49
TheMueniemeyer: now it's more clear to me, thx to williams feedback13:49
niemeyerfwereade_: Okay13:49
niemeyerfwereade_: That's easy, thanks :)13:49
fwereade_niemeyer, cool13:49
TheMueniemeyer, fwereade_ +113:49
TheMue;)13:49
fwereade_TheMue, cheers :)13:50
fwereade_niemeyer, btw, I don't know if you saw, there's a Uniter in review13:50
niemeyerfwereade_: Yeah, brilliant13:51
niemeyerfwereade_: How're things going there, btw?  Are you happy with it?13:51
niemeyerfwereade_: Or with progress, in general13:51
fwereade_niemeyer, it's basically the whole unit agent state machine, excluding relations, because basically everything interacts with everything else and looks very different if you try to implement bits without other bits13:51
fwereade_niemeyer, honestly I think it's awesome, it does an awful lot in very few lines of code13:52
niemeyerfwereade_: Woot!13:52
fwereade_niemeyer, and the tests are pretty cool too13:52
fwereade_niemeyer, I fully expect to have missed something, but I was feeling pretty damn happy when I proposed it :)13:52
fwereade_niemeyer, uniter and modes are each under 250 lines13:52
niemeyerfwereade_: Sweeeet13:53
fwereade_niemeyer, I'm sad that I didn't et it proposed on friday, but happy that I think relation support will be easy to add13:53
niemeyerfwereade_: I get all excited just thinking that we're about to run our first charm13:54
fwereade_niemeyer, yeah :D13:54
fwereade_niemeyer, and, heh, the name Uniter feels like a surprisingly good joke, it really does pull almost everything together in one place13:54
niemeyerfwereade_: Hah.. hadn't thought of it from that perspective13:55
TheMuefwereade_: Yes, Sir, Mr Reade, Sir. Initial state is up and running. Thx again. ;)14:04
fwereade_TheMue, awesome, tyvm14:04
niemeyerAram: ping14:18
Arampong14:18
niemeyerAram: Yo14:18
Aramhi14:18
niemeyerAram: I've just sent you a review on confignode14:18
niemeyerAram: It's definitely awesome14:18
Aramlooking14:18
niemeyerAram: There are a couple of high-levels we should understand, just in terms of how we'll be porting these concepts14:19
niemeyerAram: The logic itself is very cool14:19
Aram1 min to answer IN the CL.14:21
niemeyerAram: Okay, although I'd like to follow up here if that's fine with you14:23
Aramdone14:24
niemeyerAram: Okay, given those comments, LGTM on the branch going in as-is14:25
niemeyerAram: We can tweak it further in follow ups14:25
Aramthanks :).14:25
niemeyerAram: Re. the path, I'm wondering if we should be using context-specific collections14:26
Aramthat might be a good kidea.14:26
Aramidea14:26
niemeyerAram: On the version, once I finish the txn package (which is almost there, btw), this should become automatic, so it's cool to live as-is for now14:27
niemeyers/live/leave14:27
Aramcool.14:27
niemeyerAram: Spent a good while polishing it further over the weekend.. I haven't seen a single error with the current logic so far.. last night I've finally started on the handling of inserts/removes, and I *think* the approach is sane and easy to get right..14:29
Aramyeah, I've seen your G+ post. so basically, after insert and delete it should be good to go?14:29
niemeyerAram: It's not yet functional, but I suspect I can do that in a couple of hours tonight14:29
niemeyerAram: Yep14:29
niemeyerHmm.. I have to do some errands today, like banking and expense-reporting14:37
* Aram needs to buy new backpack, laptop, and some small laptop carying thingy.14:39
niemeyerAram: What's the plan for the new laptop? Anything interesting these days?14:51
niemeyerfwereade_: Nice one on the downloader refactoring14:51
fwereade_niemeyer, cheers, was rather pleasing14:51
Arammeh, I wanted to buy the new ThinkPad X1 carbon, it's a great machine, 14'' screen in 13'' chassis and weight, 1600x900 matte screen etc.14:52
niemeyerfwereade_: Isn't it awesome playing with lego when you have the right blocks?  :-)14:52
Arambut at home I want to use two external monitors and this new thinkpad only has a stupid windows onlu usb (?!?) dock.14:52
Aramno drivers for linux at all.14:52
fwereade_niemeyer, yeah, it really is -- this last week or so has been a salutary lesson in the benefits of building bottom-up14:52
fwereade_niemeyer, not sure we could have done it like that starting from scratch, but that's maybe just me :)14:53
AramIf I didn't need to use two external monitors, I'd buy the new ThinkPad X1 carbon.14:53
Arammainly because of screen.14:53
niemeyerAram: Ouch14:54
niemeyerfwereade_: Yeah, we should definitely sit down for a couple of hours over the next sprint evaluating what we did14:54
fwereade_niemeyer, postmortems++14:54
niemeyerfwereade_: I tend to agree that to do what we're doing right now, we need crystal-clear vision of where we're going14:55
fwereade_niemeyer, ...but when we *do*, it's awesome :)14:56
niemeyerfwereade_: +1000 x 0.00115:24
niemeyer:-)15:24
niemeyerfwereade_:  You have a LGTM! That branch is great15:24
fwereade_niemeyer, haha :)15:24
fwereade_niemeyer, sweet15:24
fwereade_niemeyer, thank you :D15:24
niemeyerfwereade_: Another review on uniter-support-tweaks15:57
niemeyerfwereade_: I'm afraid this one isn't so positive.. please let me know when you want to talk about it15:57
fwereade_niemeyer, you're probably right on most of it given a quick scan, and it's definitely worth a chat -- but are you about to have lunch?15:58
fwereade_niemeyer, because I am rather hungry myself, but will be back shortly15:59
niemeyerfwereade_: Indeed I am.. if there's anything quick you wanna talk before that, I'd be happy to unblock you15:59
niemeyerfwereade_: Otherwise I'll be back soon after lunch + bank15:59
fwereade_niemeyer, nah, I'm good, just need to work up the mental resolve to stop coding and go get some fod ;)15:59
niemeyerfwereade_: Superb, sounds like a plan :)15:59
=== marrusl_ is now known as marrusl
niemeyerrobbiew: Sorry, I know you just mentioned it in the meeting, but I'm not sure: do we have the consistency call today?16:55
robbiewlol16:57
robbiewniemeyer: are you trolling me16:57
robbiewno call16:57
niemeyerrobbiew: Well, that's getting pretty consistent I guess :)16:58
robbiewindeed16:58
fwereade_niemeyer, ping, I have a bit of pushback on HookContext.CmdGetter in the review17:13
fwereade_niemeyer, although honestly I could live without any or all of the things I propose -- they just make a few bits of the Uniter arguably neater17:17
niemeyerfwereade_: Agreed, I can also live without any code, although it wouldn't be so fun I believe :-)17:27
niemeyerfwereade_: That's not justification to get things in blindly, though.. CmdGetter feels like a pretty awkward piece at first sight17:28
niemeyerfwereade_: I'm happy to talk, though.. have been wrong a non-trivial number of times17:28
fwereade_niemeyer, I think there's an underlying point we haven't discussed:17:29
fwereade_niemeyer, IMO it's simplest right now to start a jujuc server for each hook and stop it when the hook's done17:29
fwereade_niemeyer, I know that this approach will probably not live forever, but I don't think it's better *now* to implement a persistent server which chooses contexts, without having any contexts to choose, than it is to defer implementing that until we know exactly what we want17:30
fwereade_niemeyer, assuming you're ok with this, then we can debate CmdGetter, although ...actually, I'm happy to concede it's unnecessary17:31
fwereade_niemeyer, if you're not ok with the above, we should probably talk more :)17:32
niemeyerfwereade_: I don't have a strong feeling either way, but I'd appreciate understanding what it means in practice17:32
niemeyerfwereade_: My view is that it has a context to choose, and we just haven't implemented the bit that makes it choose different contexts17:33
niemeyerfwereade_: If we already have that neatly in place, I'm curious about why we'd go backwards17:34
niemeyerfwereade_: Although, maybe we have the model entirely wrong17:38
fwereade_niemeyer, ok, but the actual mechanics of context choice become more complicated if there's ever more than one possibility: that is, if I have a server running all the time, I need to keep track of the current hook context in the Uniter, and to worry about what happens if someone happens to call into it when I'm not expecting it17:38
niemeyerfwereade_: Well, that's the very reason why we have a context id, right?17:39
fwereade_niemeyer, I'm not saying they're intractable, just that they're not something we need yet when we can just run single-context servers17:39
niemeyerfwereade_: Yeah, this is interesting.. let's explore that for a bit17:39
fwereade_niemeyer, sure, the concept of a context id has been flowed through from the start because we're confident we'll want to do something interesting with it one day17:39
niemeyerfwereade_: We had that conversation in the sprint where we agreed to do something entirely different from what we originally envisioned17:39
niemeyerfwereade_: Which can actually affect this in a good way17:40
fwereade_niemeyer, cool17:40
niemeyerfwereade_: We had that thing with.. how was it.. "juju-context foo.sh" or something?17:40
fwereade_niemeyer, that was the suggestion, I think, yes17:41
niemeyerfwereade_: Okay.. and IIRC we agreed that it was going to be serialized too17:41
niemeyerfwereade_: Or am I on crack?17:41
fwereade_niemeyer, although I'm thinking juju-run might actually be nicer17:41
niemeyerfwereade_: Yeah, that sounds better17:41
fwereade_niemeyer, no, I am entirely comfortable with this idea17:42
niemeyerfwereade_: Okay, so.. hmm17:42
niemeyerfwereade_: If it's all serialized, you're on the right track.. why do we have multiple contexts17:42
niemeyerfwereade_: There's still a role for the context id as originally incepted, though, I think17:43
fwereade_niemeyer, validation, primarily, I think -- commands will act slightly differently in a relation context, for example17:43
niemeyerfwereade_: Bingo!17:43
niemeyerfwereade_: What if we replaced it by a nonce?17:43
fwereade_niemeyer, expand please, not sure how that's superior17:44
niemeyerfwereade_: What we want is to prevent stuff from randomly accessing the juju server17:44
niemeyerfwereade_: When they've reportedly left the context in which they were running17:44
niemeyerfwereade_: If I juju-run my-stuff.sh, nothing from my-stuff.sh should be touching the server after juju-run returns17:45
fwereade_niemeyer, yes, exactly17:45
niemeyerfwereade_: A nonce is a good way to implement the mechanics for that, without separating into multiple contexts on the server side17:45
niemeyerfwereade_: When we start to run something, we provide a nonce to the environment, when we stop running it, we reset the nonce17:46
niemeyerfwereade_: Any requests that arrive with the wrong nonce are denied17:46
fwereade_niemeyer, ok, so, just as we have been doing, but I like this perspective, it doesn't have to be tied to the context17:47
niemeyerfwereade_: yeah, pretty much as we've been doing, except we lose the concept of the context id, because the client can't "select the context"17:47
niemeyerfwereade_: It's just able or unable to talk to "the one context"17:48
fwereade_niemeyer, we can keep the same context forever, and just take a little bit of care with concurrency17:48
niemeyerfwereade_: Right17:48
fwereade_niemeyer, ok, that sounds awesome17:49
fwereade_niemeyer, I have a plan, then: I drop evenything except the ExpandTo change, and rework the tests as you suggest17:49
fwereade_niemeyer, then you can take a look at the real-live-uniter branch and decide whether the command running is horrifying enough to demand that fix as a prereq, or whether you can live with it a a followup17:51
fwereade_niemeyer, sane?17:51
niemeyerfwereade_: +117:52
niemeyerfwereade_: Is CmdGetter there?17:52
niemeyerfwereade_: Or, will it remain there?17:52
fwereade_niemeyer, nah, I'll write the same tiny little closure inline, unless you're willing to put up with it as a temporary measure17:53
niemeyerfwereade_: I think it could go away entirely17:53
niemeyerfwereade_: but certainly willing to review for more context17:53
niemeyerfwereade_: This closure is doing if a != b { error }17:54
fwereade_niemeyer, yeah17:54
fwereade_niemeyer, oh, yes, we never did talk properly about charm.Status18:04
fwereade_niemeyer, from the questions you ask, I think I maybe got the name wrong18:05
fwereade_niemeyer, in a sense there are only 3 statuses -- missing, changing, installed -- but there are multiple reasons to be changing the charm, and I think the Uniter wants to keep track of them somehow18:06
fwereade_niemeyer, it seemed sensible to store them all in one type, for the convenience of the package's only client, which does care about those distinctions18:06
niemeyerfwereade_: I'm just wondering why18:07
fwereade_niemeyer, why the distinction between the two upgrade types?18:07
fwereade_niemeyer, because forced ones don't want to run hooks while already in a potential error state18:07
niemeyerfwereade_: Why the forced status is necessary18:08
niemeyerfwereade_: In the charm upgrading directory18:08
niemeyerfwereade_: If we have a charm directory upgrade in progress, it is in progress and we must complete it.. it doesn't matter how we got there18:08
niemeyerfwereade_: retry is unrelated to that.. force means "upgrade even if in error"18:08
fwereade_niemeyer, hum, I was not involved in the original implementation there, but AIUI it was precisely so that users *could* upgrade hte charm while in the middle of a hook error without otherwise perturbing the unit's state18:08
fwereade_niemeyer, ok, and given that the process could die N times in the course of the upgrade, when we come up in the middle of an operation, I think it is useful to know exactly what sort of operation it is18:09
niemeyerfwereade_: It's an upgrade operation., ?18:09
fwereade_niemeyer, right, but it wants to finish it idfferently depending on whether or not it's forced18:10
fwereade_niemeyer, python elevated the forcedness as the most important thing -- ie a forced upgrade would never run hooks18:10
niemeyerfwereade_: Exactly.. so why do we need both an "upgradeing" and an "upgrading forced" status in a charm directory?18:10
fwereade_niemeyer, because how the upgrade operation is completed differers, depending on that status18:11
niemeyerfwereade_: Why?18:11
fwereade_niemeyer, I was not privy to the original reasoning, but I would not be surprised if the word "twisted" didn't feature in the answer somewhere18:12
niemeyerfwereade_: Okay, so can we drop that status?18:12
fwereade_niemeyer, as long as you're happy to make a forced upgrade in started state act exactly like a normal upgrade18:13
fwereade_niemeyer, I would be very happy with that18:13
niemeyerfwereade_: I don't understand how it's any different, to be honest.. a "forced" upgrade indicates whether or not we're willing to start the upgrade even if in an error status18:14
fwereade_niemeyer, and then any upgrade operation will, when it completes, run hooks or not based purely on existing hook error18:14
niemeyerfwereade_: After that decision, we're running the upgrade.. it's already in progress and we can't stop it, no matter how we got to start running it18:14
fwereade_niemeyer, ok, sure, but when we finish I think we still do not want to run the upgrade-charm hook if another hook has an unresolved error18:14
niemeyerfwereade_: Once the upgrade completes, there's a decision to be made regarding running hooks or not, and that's not related to whether we said "force" or not, or is it?18:15
fwereade_niemeyer, the only reason it is related is because it is implemented like that in python18:16
fwereade_niemeyer, and I doubt anyone is depending heavily on the ability to upgrade charms without hooks in started status18:16
niemeyerfwereade_: Okay, I can't see the reasoning, but maybe we'll find out while trying to drop it.. if we don't, even better18:16
fwereade_niemeyer, so if you're ok with the behaviour change then I am ++happy to drop it18:16
niemeyerfwereade_: Okay, just to be clear, what's the behavior change again?18:17
fwereade_niemeyer, whether or not to run an upgrade-charm hook at the end of a forced charm upgrade in started status18:17
fwereade_niemeyer, I think the change is a good one18:17
fwereade_niemeyer, ie that forcedness should be entirely ignored in started mode18:17
niemeyerfwereade_: Huh.. that's what I expected it meant, so I guess the change from whatever was being done is a reasonable one18:18
fwereade_niemeyer, this also lets me -wip that branch before you take a look, the install/upgrade will get *much* nicer as a result18:18
niemeyerfwereade_: It's like "rm -f foo".. if foo would be removed without -f.. well.. that's fine :)18:19
fwereade_niemeyer, yeah, the meaning of force should not have been overloaded in the first place :)18:20
fwereade_niemeyer, ok, I think I'm going to rework my branches18:22
fwereade_niemeyer, the one we've been discussing will lose UpgradingForced, will get the ExpandTo test fixes, and will also get a reworking of the state unit/service charm API that I ended up needing in the followup18:23
niemeyerfwereade_: Cool18:24
fwereade_niemeyer, when that's ready I'll repropose and gtw on real-live-uniter with nicer charm changes18:24
niemeyerfwereade_: Superb, cheers18:24
fwereade_niemeyer, ok, now I'm looking at the state charm stuff on its own, I'm thinking some more18:40
* niemeyer listens18:41
fwereade_niemeyer, do we have any reason to have CharmURL or SetCharmURL at all? I don't think we really do18:41
niemeyerfwereade_: Go on?18:42
fwereade_well, they're barely used, and they allow for inconsistency that setting and getting actual *state.Charms do not18:42
niemeyerfwereade_: I'm not yet following18:42
niemeyerfwereade_: I don't want to state the obvious, but they're the way we download charms18:43
niemeyerfwereade_: What am I missing?18:43
fwereade_niemeyer, ok, SetCharmURL(something-made-up) is possible; SetCharm(some-actual-charm) is not18:43
fwereade_niemeyer, ok, that made no sense18:44
fwereade_niemeyer, I'll try again: it should not be possible to set a unit's, or a service's, charm URL to a charm that is not in state18:45
fwereade_niemeyer, the two ways of accomplishing this are (1) check against state whenever we set a charm url or (2) allow setting of charm urls purely by setting actual *state.Charm values, which should be guaranteed to represent real charms18:46
fwereade_niemeyer, I favour (2), it feels cleaner18:46
niemeyerfwereade_: I don't understand how that's possible18:46
niemeyerfwereade_: Charm URLs are signed so that we can access a private bucket18:47
fwereade_niemeyer, no, charm urls -- *charm.URL -- not bundle urls18:47
fwereade_niemeyer, units and services identify their charm by charm URL18:47
niemeyerfwereade_: Oh, oka18:47
niemeyery18:47
fwereade_niemeyer, when we come to download it, we get the bundle url from the state charm itself -- that's fine, I think it's immutable18:48
niemeyerfwereade_: So what's the thing on the left-hand side of SetCharmURL again? :-)18:48
* niemeyer looks at the code18:48
fwereade_niemeyer, unit/service18:48
niemeyerfwereade_: Okay, sorry, I think I get it now18:50
niemeyerfwereade_: Are you suggesting we replace SetCharmURL and CharmURL by SetCharm and Charm?18:51
fwereade_niemeyer, yes18:51
niemeyerfwereade_: +118:51
fwereade_niemeyer, sweet -- and, while I'm there, I kinda want to change state.Unit.serviceName to state.unit.service -- I think we've always got a service available when we create a unit, and it then means that we can actually get to all the relevant state given just a *Unit18:52
fwereade_niemeyer, rather than having to store units and services together in a bunch of places18:52
fwereade_niemeyer, well, 2 places, anyway18:52
fwereade_niemeyer, (the point is that we can then have (*Unit)Service() *Service18:53
fwereade_)18:53
niemeyerfwereade_: If it's cleaner, certainly +118:53
niemeyerfwereade_: Well, hmm18:53
niemeyerfwereade_: I guess that sounds sane.. I'm just wondering about how that will impact performance and the caching stuff18:54
fwereade_niemeyer, only positively, I *hope*18:54
niemeyerfwereade_: Yeah, probably18:55
niemeyerfwereade_: These changes should take place on mstate at the same time18:55
niemeyerfwereade_: I think we're already covering that part of the API there18:55
niemeyerAram?18:55
fwereade_niemeyer, I think the Unit methods are missing, but that's just less code to delete :)18:56
niemeyerfwereade_: Yeah, and it'll probably be easier to add to mstate than state even, and it'll also give you a nice idea of how it maps18:56
fwereade_niemeyer, yeah, I have yet toget myhands dirty in there18:57
fwereade_niemeyer, sorry, more things to get agreement on ahead of time, actually18:58
fwereade_niemeyer, (1) units should start out without charms set18:58
fwereade_niemeyer, (2) the charm state file will actually want a charm URL *and* a status, because I won't be able to trust the charm URL I set in state (what if I'm restarted on a different machine?)18:59
fwereade_niemeyer, I think that's it19:00
niemeyerfwereade_: Hmm19:07
niemeyerfwereade_: (1) seems rather curious19:07
fwereade_niemeyer, well, given (2), we could ignore (1), but I guess the question is what exactly a unit's charm URL *means*19:09
niemeyerfwereade_: Is there any doubts about that?19:09
niemeyerfwereade_: It's the charm the unit is supposed to run?19:09
fwereade_niemeyer, if it's the charm the unit *should* have, it puts us in a position of potentially writing 10k nodes in order to upgrade the charm for a big service19:09
fwereade_niemeyer, if it's the charm the unit *does* have, IMO it should absolutely start out empty and only be set once the charm is installed19:10
niemeyerfwereade_: Yes, assuming we want to upgrade all at once19:10
fwereade_niemeyer, well, I guess, we do write those 10k *anyway* in order to actually tell them to upgrade19:10
niemeyerfwereade_: Yeah19:10
fwereade_niemeyer, if we're telling them what to upgrade to that's only twice as much work :)19:10
niemeyerfwereade_: It's also the easy part of the job, assuming we're upgrading 10k units :)19:10
fwereade_niemeyer, haha19:10
niemeyerfwereade_: Although.. I can easily see us doing better in that area19:11
niemeyerfwereade_: The thinking around all of that is to enable partial upgrades19:11
niemeyerfwereade_: Which I'm assuming *will* happen.. nobody will be upgrading 10k nodes at once to a new version if they have a real production system19:12
niemeyerfwereade_: Well, I should fix that.. nobody *should* do that.. they probably will :)19:12
fwereade_niemeyer, ha19:13
fwereade_niemeyer, well, ok, this is again a behaviour change, about which I'm a little less certain, because I don't know whether I will be implementing upgrade-charm, and this all needs to tie in nicely there19:14
fwereade_niemeyer, ATM python depends on (1) the unit's upgrade flag and (2) the service's charm19:14
fwereade_niemeyer, and it uses the unit's charm in state to determine that it doesn't need an upgrade19:14
niemeyerfwereade_: I quite like what we did in the agent stuff19:15
niemeyerfwereade_: We could mimic it19:15
fwereade_niemeyer, that last part is crack anyway, really, it should be using local state to know what's already installed19:15
fwereade_niemeyer, that has crossed my mind19:15
niemeyerfwereade_: We have proposed and current19:15
niemeyerfwereade_: Which means we support both ends19:16
niemeyerfwereade_: That doesn't change what you just said, though19:16
niemeyerfwereade_: Current is set via local state19:16
niemeyerfwereade_: This also means no behavioral change is necessary19:16
fwereade_niemeyer, ok, yep, it's not an external behaviour change, wrong term -- what I mean is that it's a change that has ramifications beyond my current narrow focus19:17
fwereade_niemeyer, ie in the implementation of juju upgrade-charm itself19:17
fwereade_niemeyer, which I will capture in the bug, so np there :)19:18
fwereade_niemeyer, so: service just has Charm/SetCharm, and the service's charm controls the proposed-charm that new units are created with19:18
fwereade_niemeyer, unit has proposed-charm and current-charm, which starts out empty19:19
fwereade_niemeyer, whenever the UA finishes unpacking a charm to disk, it sets current-charm19:19
niemeyerfwereade_: +119:20
niemeyerfwereade_: Well, I assume proposed-charm should start out filled19:20
fwereade_niemeyer, so unit gets Charm/SetCharm, and ProposedCharm, and maybe something else19:20
fwereade_niemeyer, SetProposedCharm and SetNeedsUpgrade sound like they could profitably be combined19:21
niemeyerfwereade_: As it doesn't make sense to fire a unit if we don't know what it is19:21
niemeyerfwereade_: Agreed19:21
fwereade_niemeyer, ok, I'm starting to feel that the ripple effects may be pretty significant, because a diff between current and proposed should be enough information to determine that an upgrade should happen19:23
niemeyerfwereade_: Exactly19:23
niemeyerfwereade_: Alternatively, we may dump that half-baked idea19:24
niemeyerfwereade_: Since we're paying cost for nothing so far19:24
fwereade_niemeyer, I therefore feel like we should stick with the existing upgrade flag approach, because that does contain one valuable bit (force) along with the less valuable bit (upgrade)19:24
niemeyerfwereade_: And say that proposed-charm lives in the service, while current-charm lives in the unit19:25
fwereade_niemeyer, hey, nice19:25
fwereade_niemeyer, and that then does mean that the unit starts out empty19:25
niemeyerfwereade_: Right19:26
fwereade_niemeyer, then we keep the upgrade flag exactly as is19:26
fwereade_niemeyer, and then in fact we just keep the existing API, but use Charm instead of CharmURL19:26
fwereade_niemeyer, because really unit.CurrentCharm/service.ProposedCharm don't make a huge amount of sense, while .Charm/.Charm can be sensibly documented19:27
niemeyerfwereade_: I think NeedsUpgrade can go19:27
niemeyerfwereade_: Agreed19:27
fwereade_niemeyer, just the API method? yeah, nobody needs to read that without watching, I don;t think19:28
niemeyerfwereade_: The whole idea of the flag in the unit, I mean19:29
niemeyerfwereade_: needing upgrade == service.Charm != unit.Charm19:29
fwereade_niemeyer, hmm... just a moment ago you convinced me that it would be a good idea to keep the possibility of upgrading parts of a service19:30
fwereade_niemeyer, and we still need somewhere for the force flag to live -- I guess it could be the service, but see above, partial upgrades19:30
niemeyerfwereade_: Agreed, but I've been changing my mind since then.. we're putting brand new logic in place that doesn't scale, for a benefit we don't yet have19:32
niemeyerfwereade_: DOuble loss19:32
fwereade_niemeyer, well, ok, cool, but also ouch, more infrastructure rework :)19:32
niemeyerfwereade_: Well, you mean the method in Unit? That sounds trivial.. I'd be worry if we had logic in the uniter already19:33
niemeyerworried19:33
fwereade_niemeyer, I'm talking about the watcher really19:34
fwereade_niemeyer, I expect it will be trivial, it's just that for some reason it flips my perception of my blockers from "meh, I'll probably finish it tonight" to "omg this will take forever"19:35
fwereade_niemeyer, which is self-evidently insane, I do not need to be told ;)19:35
niemeyerfwereade_: Ah, yeah, you mean we need a watcher for the service which I suppose we don't yet have19:36
fwereade_niemeyer, yeah, that's all really19:36
niemeyerfwereade_: A lot of blocks indeed19:37
fwereade_niemeyer, but still, I'll see what I can do :)19:37
niemeyerfwereade_: I wonder about the force upgrade flag SetCharm(charm, force)?19:39
niemeyerfwereade_: service.Charm() (charm, force)?19:39
niemeyerWell19:39
niemeyerfwereade_: service.Charm() (charm, force, error)?19:39
fwereade_niemeyer, yeah, I *think* so, but I'm still following it through19:40
fwereade_niemeyer, hmmm, how do we know when the force flag can be cleared without scanning all units?19:42
niemeyerfwereade_: I don't think we have to clear it19:42
niemeyerfwereade_: (!)19:42
fwereade_niemeyer, ah, yeah, next upgrade we just set a new charm and force it or not19:43
niemeyerfwereade_: Yep19:43
niemeyerfwereade_: It's awesome that the right path generally shows itself obviously good by the number of things we *don't* have to do19:43
fwereade_niemeyer, hmm, is it meaningful to unforce the upgrade to a particular charm?19:44
fwereade_niemeyer, IIRC we have some logic that says you can't unforce an upgrade, but I forget why19:44
niemeyerfwereade_: I actually commented in the review that this was weird, but accepted not to argue until later19:44
fwereade_niemeyer, ha :)19:45
niemeyerfwereade_: The upgrade operation as "I want to use this charm, with forcing enabled/disabled" feels as good as it gets19:45
fwereade_niemeyer, sgtm, can we explore the idea a bit more in the context of compatibility?19:46
fwereade_niemeyer, Service.SetCharm gives us a great point at which to enforce interface compatibility... maybe that's all we need19:47
fwereade_niemeyer, trying to figure out how much damage a zombie unit can do19:48
fwereade_niemeyer, I guess the answer is "none" as long as it's operating well enough that it kept its relations alive19:48
niemeyerfwereade_: Hm19:49
fwereade_niemeyer, because those relations, had they had that unit as a member, would not have dies, and would therefore themselves have blocked the upgrade in the first place19:49
niemeyerfwereade_: I'm afraid I'm a bit out of context19:51
niemeyerfwereade_: I agree re. SetCharm being a nice point19:51
fwereade_niemeyer, sorry, it feels like it's connected to, er, 1 sec19:51
niemeyerfwereade_: It's actually brilliant, in the sense that we can have a single point efficiently checking for all units19:51
niemeyerfwereade_: I don't know what a zombie unit is, though :)19:51
fwereade_niemeyer, I mean a unit that comes back up after a long break, which is using a hugely outdated charm, and may even be dying19:52
niemeyerfwereade_: Ok, so what's the issue with it again?19:53
fwereade_niemeyer, I'm just feeling like we should consider https://bugs.launchpad.net/juju-core/+bug/1032557 in this context before we go too far19:53
fwereade_niemeyer, but on a reread I don;t think it's relevant19:54
fwereade_niemeyer, it's just another chunk of ugliness for the uniter, wwhich I'll hopefully be able to keep under control :)19:54
niemeyerfwereade_: The bug sounds a bit awkward in its wording19:56
niemeyerfwereade_: Oh, wait19:56
niemeyerfwereade_: upgrade-charm as in "juju upgrade-charm"?19:56
niemeyerfwereade_: I had the hook name in my mind for whatever reason19:56
fwereade_niemeyer, ah, sorry :)19:57
niemeyerfwereade_: No, it's my bad19:57
fwereade_niemeyer, but anyway, I don't think it actually does hurt us here19:57
niemeyerfwereade_: I think we should start by just being conservative.. no changes in established relations19:57
niemeyerfwereade_: We can improve from there, always staying on the safe side19:58
fwereade_niemeyer, ok, sure, there's still a chunk of ugliness to deal with in the uniter19:58
niemeyerfwereade_: How so?19:58
fwereade_niemeyer, toactually stay on the safe side we need to make sure we don't join relations that don't exist in the current version of the charm19:58
fwereade_niemeyer, otherwise we'll get a bunch of hooks "executed" despite their not actually existing19:59
niemeyerfwereade_: Wow.. my mind just spinned for a second.. how's that again? :-)19:59
fwereade_niemeyer, unit has cs:series/dummy-0, service has cs:series/dummy-1, upgrade is unforced, uniter is in error state20:00
fwereade_niemeyer, relation is added using an interface that exists in -1, but not in -020:00
niemeyerfwereade_: Great, I'm with you now20:00
niemeyerfwereade_: Aha, thanks, gotcha20:01
fwereade_niemeyer, when the uniter goes into the started state, it... well, really, it just needs to check the upgrade flag before it starts messing with relations20:01
fwereade_niemeyer, ok, it's easier than I thought :)20:01
fwereade_niemeyer, yay!20:01
niemeyerfwereade_: Just when I was starting to get worried!? LOL20:01
fwereade_niemeyer, haha, sorry :)20:02
niemeyerfwereade_: The fact we disallow "correct multi-versioning" actually seems like a great simplification there20:03
fwereade_niemeyer, yes indeed20:03
niemeyerfwereade_: The unit should either follow along, or be broken20:04
niemeyerfwereade_: Which is not only easy to implement, but also easy to understand20:04
fwereade_niemeyer, yep, and as soon as it's unbroken it catches up20:04
fwereade_niemeyer, hum, I have a new scenario20:05
niemeyerfwereade_: Uh oh20:05
niemeyer:-)20:05
fwereade_niemeyer, unit with v-0 is running a hook which takes a long time; someone upgrades the service and adds a new v-1 relation, such that both watches are ready when the unit comes out20:06
fwereade_niemeyer, again it's easy, do a quick check of the upgrade flag before going back into the main select20:07
niemeyerfwereade_: Welllll20:07
fwereade_niemeyer, but the fiddliness factor is growing20:07
niemeyerfwereade_: I think we can be more deterministic than that20:08
niemeyerfwereade_: We know what charm the unit is running.. we know which relations it takes20:08
fwereade_niemeyer, hey, wait, it's even easier20:09
fwereade_niemeyer, just *totally ignore* all relations that don;t make sense yet20:09
fwereade_niemeyer, we'll start new relation watches when pick ourselves up from the upgrade20:09
fwereade_niemeyer, and it will all shake out then20:09
fwereade_niemeyer, niiice20:09
niemeyerfwereade_: It doesn't feel so straightforward20:10
fwereade_niemeyer, oh :(20:10
niemeyerfwereade_: I mean, it is, but you're trying to order two events that happen independently and chaotically20:10
niemeyerfwereade_: Doing: 1) do I have upgrades; 2) do I have new relations20:11
niemeyerfwereade_: Isn't safe20:11
niemeyerfwereade_: Because between 1 and 2, I can very quickly upgrade the charm and add a new relation20:11
fwereade_niemeyer, agreed, which is why the simpler solution is also *better* -- the only question I need to ask is "does this relation look sane?" and if it doesn't I can just ignore it20:12
fwereade_niemeyer, trusting that the rest of the system has enough integrity that sooner or later I'll pick up the upgrade that will make that relation make sense20:12
niemeyerfwereade_: Right, and by sane I suppose you mean verifying against the charm that the unit is running ATM20:12
fwereade_niemeyer, yeah, exactly20:12
niemeyerfwereade_: Cool20:12
niemeyerfwereade_: The only detail then is that we have to "re-watch" after upgrading20:13
niemeyerfwereade_: Since we may have lost events that were responsible for the creation of such relations20:13
fwereade_niemeyer, yeah, the idea is that upgrading is a spearate mode from starting, which is what actually watches for relations20:13
fwereade_niemeyer, s/starting/started/20:14
niemeyerfwereade_: Cool, I haven't yet run through the uniter in detail, so I'll just trust you on that.. it definitely sounds great :-)20:14
fwereade_niemeyer, once we're in started, we start a whole bunch of watches that only last for the duration of that mode, and relations is one of them20:14
niemeyerfwereade_: Neat20:14
fwereade_niemeyer, that said, I should -wip it, and I haven't yet20:15
fwereade_niemeyer, these underlying changes are only going to have good effects at the uniter level :)20:16
niemeyerfwereade_: Yeah, I have a great feeling about those conversations20:16
niemeyerfwereade_: It sounds like we're actually understanding the problems we've been dealing with, and are making good progress towards a fully working system20:17
fwereade_niemeyer, I am approaching a state of mystical oneness with the Uniter :)20:17
fwereade_niemeyer, I guess I should go write a spot more code, though, not sure how much the branches will need to be split up20:18
niemeyerfwereade_: That sounds so great.. LOL20:19
niemeyerfwereade_: Yeah, I felt tempted to suggest splitting things up in a few occasions too20:19
fwereade_niemeyer, I *think* it'll come out surprisingly clean20:19
niemeyerfwereade_: +120:20
fwereade_niemeyer, fixing up the bundle stuff is trivial, though, I'll getthat one out of the way in the first branch before anything else20:21
niemeyerfwereade_: Sounds good.. happy to review in-promptu as well20:21
fwereade_niemeyer, cool, I ballsed up my sleep patterns over the weekend so I'll be around for a bit, I'll shout if I'm unsure of anything20:22
niemeyerfwereade_: I know how that goes.. :-)   I'll have to step out for a moment soon, but I'm also going to be working on the evening, so we can stay in sync20:23
fwereade_niemeyer, great20:23
niemeyerOkay, biab20:54
fwereade_niemeyer, ping22:18
fwereade_niemeyer, I was wondering about the motivation behind the (1) continue-on-error and (2) write-revision-last behaviours of the current charm.ExpandTo22:19
niemeyerfwereade_: Hmm, let me check22:20
niemeyerfwereade_: Can't tell why the heck it continues on error22:23
niemeyerfwereade_: revision-last is an artifact of the revision bumping22:24
fwereade_niemeyer, ahhh, ofc -- and we actually use that on bundles?22:24
fwereade_niemeyer, it doesn't look like we do22:26
niemeyerfwereade_: Probably not.. it was part of the Charm interface at some point, which is how it ended up there22:26
fwereade_niemeyer, and it feels like there's somehow something odd about being allowed to, actually22:26
fwereade_niemeyer, can I drop it please?22:26
niemeyerfwereade_: Sure22:27
fwereade_niemeyer, sweet, thanks22:27
fwereade_niemeyer, also, just to check, IMO files and symlinks should fail to replace directories; sane?22:29
niemeyerfwereade_: Why?22:30
niemeyerfwereade_: It really depends on the intended semantics22:30
fwereade_niemeyer, hmm, just because it feel a bit drastic to my personal gut22:30
fwereade_niemeyer, it's equally perfectly fine by me to say Bundle.ExpandTo will overwrite with prejudice22:31
niemeyerfwereade_: I think we have to pick something sane from the upgrading perspective22:31
niemeyerfwereade_: If that's what we're doing22:31
niemeyerfwereade_: You know what we could do..22:32
fwereade_niemeyer, well, as long as people don't store data in dirs that then get turned into files/symlinks by future versions of the charm, we're fine22:32
niemeyerfwereade_: We could use bzr22:32
fwereade_niemeyer, how so?22:33
niemeyerfwereade_: Well, "as long as people don't do something that feels ok doing" is somewhat of a dead end :)22:33
niemeyerfwereade_: bzr has all the logic for merging state against working trees22:34
niemeyerfwereade_: We'll spend weeks trying to get close to it, and won't22:34
fwereade_niemeyer, I'm not sure it feels like an entirely ok thing to do to me, honestly22:35
niemeyerfwereade_: You're thinking too rationally about it, IMO22:35
fwereade_niemeyer, haha22:35
niemeyerfwereade_: People will delete the directory.. hack some more.. write the file.. deploy22:35
niemeyerfwereade_: This isn't particularly bad looking22:36
fwereade_niemeyer, is it really rational of them to think that they can have two entirely different things coexisting with the same name, though?22:37
niemeyerfwereade_: Again, they won't sit in a terminal thinking "I'm replacing a directory by a file!"22:37
niemeyerfwereade_: It will simply happen, and it will blow up after the fact22:37
fwereade_niemeyer, and how will bzr deal with that situation? just that it'll tell us there's a problem?22:38
fwereade_niemeyer, in that case I favour just falling over directly when we try to delete a dir22:39
fwereade_niemeyer, do the charm tests have an upgrade-from-previous-version bit?22:39
niemeyerfwereade_: http://pastebin.ubuntu.com/1157995/22:40
fwereade_niemeyer, http://pastebin.ubuntu.com/1158000/22:44
fwereade_niemeyer, I think that is the situation we have to worry about22:44
fwereade_niemeyer, with the added bonus that there is nothing that stops people from creating their state directories only after the charm has been deployed22:45
fwereade_davecheney, heyhey22:46
niemeyerfwereade_: Right, and bzr seems to have done the right thing in both cases22:50
fwereade_niemeyer, hmm, ok, it would also have some other nice advantages like being able to delete files as well22:54
niemeyerfwereade_: Right, and only if they changed22:55
niemeyererm22:55
niemeyerfwereade_: Right, and only if they changed NOT22:55
niemeyer:-)22:55
niemeyerfwereade_: bzr import -h, btw22:55
niemeyerfwereade_: We'd manage the importing into a side repo, and then pull onto the production side22:57
niemeyerfwereade_: Will all the nice benefits of that (don't screw up unless it all works, etc)22:57
niemeyerfwereade_: Rollbacks (!)22:57
niemeyerfwereade_: For the moment, though, bzr import + bzr pull sounds like an awesome low-hanging fruit22:59
fwereade_niemeyer, well, goodness me: so we just create a little standalone tree with the first expanded content and branch that into the charm dir; and subsequently import direct from the bundle into that side repo, then pull from that into the charm dir?22:59
niemeyerfwereade_: Exactly22:59
niemeyerfwereade_: We can share the repo between them, for added goodness23:00
fwereade_niemeyer, sorry, between who?23:00
niemeyerfwereade_: The two working trees23:00
niemeyerfwereade_: Although I'm not sure if bzr import could make our day23:01
* niemeyer tries23:01
fwereade_fwereade suspects this is the point at which he should actually figure out bzr rather than just using it in a spirit of optimism ;)23:02
niemeyerLOL23:04
niemeyerBOOOM23:06
niemeyer[niemeyer@gopher ~/foo]% bzr import ../foo3.zip23:06
niemeyerbzr: ERROR: bzrlib.errors.MalformedTransform: Tree transform is malformed [('overwrite', 'new-3', u'dir')]23:06
niemeyerfwereade_: Yeah, we need the side-repo :-)23:06
fwereade_niemeyer, aww23:06
niemeyerfwereade_: Well, side branch23:06
niemeyerfwereade_: So a side branch where we import stuff23:06
niemeyerfwereade_: bzr branch import-branch final-charm-location23:07
fwereade_niemeyer, ok, yep, and the actual charm dir is just a branch of that23:07
niemeyerfwereade_: run unit on final-charm-location23:07
fwereade_niemeyer, ok, great23:07
fwereade_niemeyer, we'll also want a final pass to fix up file modes, I think, which is a bit annoying23:08
niemeyerfwereade_: On upgrade, 1) bzr import charm.bundle import-branch (I think that works out of the box);   2) bzr commit final-charm-location -m "Preparing for upgrade.";  3) bzr merge import-branch final-charm-location; 4) bzr commit final-charm-location23:08
niemeyerfwereade_: Hmm, why?23:09
fwereade_niemeyer, there are tests for modes like 750 that apparently can't be expressed by bzr23:10
niemeyerfwereade_: I'd wait until that is a real problem23:10
niemeyerfwereade_: Getting sane upgrades would already be outstanding23:11
fwereade_niemeyer, ok, then I'll just drop the unwanted features of ExpandTo and implement this upgrade logic separately23:12
niemeyerfwereade_: May I suggest ignoring ExpandTo for the moment?23:12
fwereade_niemeyer, yeah, why not :)23:13
niemeyerfwereade_: Well, unless you're already half-way through it23:13
niemeyerfwereade_: Otherwise, it feels like it won't help or get in the way23:13
fwereade_niemeyer, yeah, it's totally orthogonal really, I'll leave the branch around and finish it off in my Copious Free Time23:14
* fwereade_ has a *new* plan forming23:14
niemeyerfwereade_: Awesome23:14
fwereade_niemeyer, now embarrassingly trivial: https://codereview.appspot.com/645416923:24
niemeyerfwereade_: Looking23:24
niemeyerfwereade_: Love embarrassingly trivial branches.. LGTM23:25
fwereade_niemeyer, cheers23:25
niemeyerfwereade_: Please just tweak the message before submitting23:25
fwereade_niemeyer, thanks for the reminder :)23:25
niemeyerfwereade_: np :)23:25
fwereade_niemeyer, ok, more ramifications trickle into my mind: this now means we have another potential "error" state which is not hook-related but which is susceptible to human intervention23:39
fwereade_niemeyer, so this is good, it even fits sanely with --retry (thank goodness we didn't call it retry-hooks ;))23:41
fwereade_niemeyer, it would be possible for us to revert and continue, but I don't think it's actually helpful to do so23:42
niemeyerfwereade_: Hmm.. I'm on the fence on it23:46
niemeyerfwereade_: Either way, it feels like a plus we don't have to worry about for now23:46
fwereade_niemeyer, ok, I'll go with a pause then; retry can revert and try again with (hopefully, presumably) the new version of the charm they've set on the service, which doesn't have this problem -- while no-retry implies that they have completed the change themselves23:48
fwereade_niemeyer, if we auto-revert they don't get much of an opportunity to fix it themselves unless we also add a pause-unit feature or something23:49
niemeyerfwereade_: Good point23:50
niemeyerfwereade_: Hmm.. what does "completing themselves" mean?23:50
fwereade_niemeyer, fixed the conflicts23:50
niemeyerfwereade_: It's not clear --retry makes sense for upgrading, besides for the hook itself23:50
fwereade_niemeyer, I think it offers a nice path back to a working unit by settings a new charm that's ok -- or even the old one again23:52
niemeyerfwereade_: After "juju resolved", it seems like we could run "bzr resolved --all', and in case that succeeds, commit the merge23:53
fwereade_niemeyer, yeah, that would be what do do on non-retry23:54
niemeyerfwereade_: How's that different from yes-retry?23:54
fwereade_niemeyer, yes-retry, I think, means that the user has set a different charm on the service and wants us to try an upgrade from scratch23:55
niemeyerfwereade_: We don't have to ask the user whether he wants that or not23:56
niemeyerfwereade_: We just need metadata to tell us what is in the directory23:56
niemeyerfwereade_: Same trick we use with the agent23:57
niemeyerfwereade_: if proposed != current { upgrade }23:57
fwereade_niemeyer, hmm... ok, so we also store what charm we were trying to upgrade to; and if that is different from the current one on the service, we revert and try again with the new charm?23:58
fwereade_niemeyer, or if the service's new charm is the same as the unit's old one, I guess we just revert :)23:59

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