/srv/irclogs.ubuntu.com/2012/06/15/#juju-dev.txt

niemeyerdavecheney: ping00:50
davecheneyack00:52
davecheneyniemeyer: ack00:52
niemeyerdavecheney: Yo00:52
niemeyerdavecheney: Sorry, I actually decided to just note down in the review.. we can talk after that00:52
davecheneyno worries00:53
niemeyerdavecheney: Please see what you think of https://codereview.appspot.com/629506701:04
niemeyerdavecheney: I'm looking at https://codereview.appspot.com/6307071/diff/3007/environs/jujutest/livetests.go01:07
niemeyerdavecheney: How come t.Env.AllInstances returns 1 instance, and t.Env.Instances right above returns two?01:07
davecheneyniemeyer: because the code above asks for id0 twice01:09
davecheneyAllInstances returns a Set of known instances01:09
niemeyerdavecheney: ROTFL01:09
davecheneymaybe I should add a comment there, took me a while to figure that one out, I'm not even sure if it's correct01:09
davecheneyreguarding the rety branch01:11
davecheneyi'm just going to remove that comment01:11
davecheneyyou are of course correct that calling p.Stop() will return nil01:11
davecheneyso that is a trap for someone who might add that fuctinoality (via a signal handler or something)01:11
niemeyerdavecheney: I've added a note on https://codereview.appspot.com/6307071/01:14
niemeyerdavecheney: There's one assertion there that would be nice, but otherwise please feel free to go ahead an merge it now01:14
davecheneyniemeyer: thank you01:14
niemeyerdavecheney: I'll likely move the branch over the day tomorrow to lp.net/juju-core (no /juju), so the least branches we have flying around the best01:15
niemeyerEven though this time it should really not be much trouble01:15
niemeyerSince reviews will remain valid and all01:15
davecheneycoiol01:15
davecheneycool01:15
niemeyerOkay, almost clean queue01:30
niemeyerdavecheney: I see a LGTM from rog on https://codereview.appspot.com/6294066/01:31
niemeyerdavecheney: I'll have a look at it tomorrow so we can get this in01:31
davecheneysure01:31
niemeyerOkay, bed time here02:50
niemeyerdavecheney: Have a good time there02:50
davecheneyniemeyer: will do, thanks again02:50
twobottuxaujuju: What is the correct way to set config options to a juju service unit with a file? <http://askubuntu.com/questions/151075/what-is-the-correct-way-to-set-config-options-to-a-juju-service-unit-with-a-file>03:30
twobottuxaujuju: Can't get juju to deploy, problem with ec2 keypair? <http://askubuntu.com/questions/151088/cant-get-juju-to-deploy-problem-with-ec2-keypair>04:53
rogpeppedavecheney: mornin'05:57
* rogpeppe is a bit hung over.05:57
davecheneyrogpeppe: hey, just responding to your follow up now06:03
davecheneywill be but a moment06:03
davecheneyhttps://www.youtube.com/watch?v=AJHCsVZGnNY << audio quality is utterly atrocious06:04
rogpeppedavecheney: oh yeah, i still have to finish watching that.07:12
rogpeppedavecheney: i learned one new thing: hex.Dumper.07:12
fwereaderogpeppe, btw, while I remember, what's state.Unit.isPrincipal for?07:43
fwereaderogpeppe, doesn't seem to be used; and Unit already has IsPrincipal()...07:44
rogpeppefwereade: i didn't think there is state.Unit.isPrincipal...07:44
rogpeppefwereade: let me check07:44
rogpeppefwereade: nope, i don't see that method07:44
fwereaderogpeppe, field07:45
fwereaderogpeppe, you added it recently07:45
rogpeppefwereade: ah!07:45
rogpeppefwereade: yes, it's so that when we're watching units for a machine, we can tell which units are principals without having to read the topology again for each one07:45
rogpeppefwereade: i made a mistake actually07:46
rogpeppefwereade: Unit.IsPrincipal should just return u.isPrincipal07:46
rogpeppefwereade: will fix asap07:47
fwereaderogpeppe, yeah, indeed07:47
fwereaderogpeppe, cool, thanks07:47
rogpeppefwereade: good catch, thanks07:47
fwereaderogpeppe, wasn't sure if there might have been something else going on07:47
fwereadecheers07:47
rogpeppefwereade: nope, just my forgetfulness07:47
rogpeppefwereade: BTW did you see my question on #juju?07:48
fwereadeah sorry no07:48
fwereaderogpeppe, I get to #juju rarely, when I run out of other work to do ;)07:48
rogpeppefwereade: i was playing around with writing some charms this morning and wondered what was the best way to wait until all of several relations had been joined07:49
rogpeppefwereade: like, for instance, if one relation has been joined, can i query the joined status of other relations?07:50
fwereaderogpeppe, honestly I'm a bit unclear about the current intent of the various hook commands07:51
fwereaderogpeppe, not really up on what jimbaker was doing just before last release07:51
fwereaderogpeppe, bu I need to find out in detail soon, so I can implement them ;)07:51
rogpeppefwereade: :-)07:53
=== TheRealMue is now known as TheMue
fwereaderogpeppe, can I run some ideas past you as a sort of crackfulness check please?08:08
rogpeppefwereade: please do08:09
fwereaderogpeppe, stop me when you detect the whiff ;)08:09
* rogpeppe sniffs carefully08:09
fwereaderogpeppe, RelatedService is a good name for ServiceRelation; and its role and scope should be taken from the expected endpoint (of the service it's describing)08:10
fwereaderogpeppe, RelatedService.RelationName(), however, should return the RelationName of the endpoint at *this* end of the relation, because that's how the related service is seen by the "local" service08:11
rogpeppefwereade: remind me what ServiceRelation represents again...08:11
fwereaderogpeppe, ie the one on which we called RelatedServices() to get that RelatedService08:11
fwereaderogpeppe, my best guess is that it represents what I just described08:11
fwereaderogpeppe, but there's definitely something hinky about the types in play in the python08:12
fwereaderogpeppe, I'm trying to come up with something that actually fits what we need to do08:12
rogpeppei haven't looked at those types. i think i had a mental block at "UnitRelation" which gustavo's renaming has helped with08:12
fwereaderogpeppe, I'm actually starting to think that UnitRelation was a real misstep, that we don't want at all08:13
fwereaderogpeppe, but that's a bit further down the crackfulness list08:13
rogpeppefwereade: we're talking about types that exist to hold the settings, right?08:13
fwereaderogpeppe, well, zookeeper holds the settings... and I don't think anybody except the unit agent has any right to be looking directly at those settings any more08:14
rogpeppefwereade: because there's one collection of settings for each service for each relation for each unit08:14
fwereaderogpeppe, yes08:14
fwereaderogpeppe, but nobody should be looking at them directly IMO08:14
rogpeppefwereade: are these types not there specifically to enable what the unit agent needs to do?08:15
fwereaderogpeppe, because they run the risk of destabilising the space-time continuum by violating causality08:15
fwereaderogpeppe, *kinda*08:15
rogpeppefwereade: how is the unit agent going to read and change those settings without an API in state?08:15
fwereade_gaaah08:18
rogpeppelol08:19
fwereade_rogpeppe, did you see any of that, about RelatedGroup?08:19
rogpeppefwereade_: nope08:19
fwereade_ rogpeppe, I'm going to return to my sorta-thread of ideas briefly, I think what I'm saying will make more sense with context08:19
fwereade_ rogpeppe, next: RelatedGroup is a useful concept that deserves its own (simple) type08:19
fwereade_ rogpeppe, a RelatedGroup really just wraps a path that's either /relations/rel-id or /relations/rel-id/container-id08:19
fwereade_ rogpeppe, but it's a lot more convenient to pass around one of those and specify things like group.settingsPath(RoleProvider, unitId)08:19
fwereade_ rogpeppe, ...thn it is to hand-hack those paths everywhere08:19
rogpeppefwereade_: last i saw from you was "*kinda*" BTW08:19
fwereade_rogpeppe, cool, I picked the right join point :)08:19
fwereade_rogpeppe, so, re RelatedGroup, this is IMO a useful concept that we didn't previously have a name for08:20
fwereade_rogpeppe, it's really the set of units that can (transitively) affect one another within a relation08:20
fwereade_rogpeppe, in a global relation it's just all units08:21
fwereade_rogpeppe, in a container-scoped one there's a RelatedGroup per container08:21
rogpeppefwereade_: so what kind of operations are you imagining on a RelatedGroup?08:21
fwereade_rogpeppe, .presencePath() and .settingsPath() mainly08:22
rogpeppefwereade_: is there anywhere in the current code that would be changed to use it?08:22
fwereade_rogpeppe, also perhaps .prepareJoin(role), which ensures that nodes have been created08:22
fwereade_rogpeppe, relationUnitWatcher would directly take presencePath and settingsPath which had been calculated from a RelatedGroup08:23
fwereade_rogpeppe, and finally, maybe, .Watch(...)08:23
fwereade_rogpeppe, but it is true that I have not yet figured out exactly what data the various bits of behaviour are best attached to08:24
rogpeppefwereade_: just so i have an idea, what would the type definition look like?08:24
fwereade_rogpeppe, it really just wraps a path08:24
fwereade_rogpeppe, that's it08:24
rogpeppefwereade_: type RelatedGroup string ?08:24
fwereade_rogpeppe, it'll need a zk.Conn, or State, or something too08:25
fwereade_rogpeppe, this is what I have atm:08:25
fwereade_/ RelatedGroup represents the set of units within a specific relation that08:25
fwereade_/ can (transitively) affect one another. For a globally-scoped relation, this08:25
fwereade_/ includes all units of all services in the relation; for a container-scoped08:25
fwereade_/ relation, there will be one RelatedGroup per container, containing all08:25
fwereade_/ units of the related services that are running within that container.08:25
fwereade_type RelatedGroup struct {08:25
fwereade_    zk   *zookeeper.Conn08:26
fwereade_    path string08:26
fwereade_}08:26
fwereade_rogpeppe, it's not a lot of data, but it draws together a lot of special-casing that would otherwise be smeared across the codebase08:27
fwereade_rogpeppe, there are several places in python that act differently depending on relation scope08:27
rogpeppefwereade_: could you point to a few examples in the python code, so i have an idea?08:27
fwereade_rogpeppe, just a sec08:27
fwereade_rogpeppe, oddly enough, mainly in state/relation.py -- there are several `if self._relation_scope == "container"`s08:32
fwereade_rogpeppe, there's a _self.container_path which seems kinda redundant but is also related08:32
fwereade_rogpeppe, basically everything involving relation unit presence or settings, whether reading or writing, needs to care about this concept (implicitly or explicitly)08:33
rogpeppefwereade_: i think i need to be reminded of how relations are laid out in zk08:34
fwereade_rogpeppe, I have vocab that will  make things easier :)08:34
fwereade_rogpeppe, a "group" has (1) a settings subnode, which contains a unit-key-keyed node for every unit in the relation08:35
fwereade_rogpeppe, (2) a role subnode for each role in play in the relation, which contains a unit-key-keyed presence node for every unit actively playing that role in the relation08:36
fwereade_rogpeppe, sorry, in the *group*08:36
fwereade_rogpeppe, a globally coped relation contains just one group, which is the relation node in ZK08:36
fwereade_rogpeppe, a container-scoped relation has N container-key-keyed groups within the relation node08:37
fwereade_rogpeppe, the group is the unit of... er, influence?08:37
fwereade_rogpeppe, I am still slightly scrabbling around for vocabulary; let me know if you come up with improvements ;)08:38
rogpeppefwereade_: how about RelationScope ?08:38
fwereade_rogpeppe, yeah, except the name is taken and I don't know what to call the thing that already has that name08:39
fwereade_rogpeppe, and all the existing methods called RelationScope08:39
rogpeppefwereade_: well, we're actually talking about the same thing, right?08:39
fwereade_rogpeppe, not really, RelationScope is just "container" or "global"08:40
fwereade_rogpeppe, the thing we're talking about is about what units are actually within a given scope of a given relation08:40
rogpeppefwereade_: aren't those the two kinds of things you can have in a RelatedGroup?08:40
rogpeppefwereade_: it seems to me that the path in RelatedGroup is exactly expressing the scope of the relation08:41
fwereade_rogpeppe, I strongly agree that RelatedGroup is, intuitively, a "scope"08:41
rogpeppefwereade_: so, can we think of a way to join the two concepts?08:41
fwereade_rogpeppe, but I feel somewhat constrained naming-wise08:41
fwereade_rogpeppe, I hope so :)08:41
fwereade_rogpeppe, one possibility is to rename RelationScope to RelationScopeKind or something08:42
rogpeppefwereade_: vague thought: i wonder if a relation could return a RelationScope which looks like your RelatedGroup, but has a Kind method which returns what is currently RelationScope08:42
rogpeppeha!08:43
fwereade_rogpeppe, then I can08:43
rogpeppefwereade_: jinx, kinda08:43
fwereade_rogpeppe, the trouble is that I cannot necessarily  just go from a relation to a relation scope, without knowing the container I'm talking about (in the case of a container-scoped relation, anyway)08:43
fwereade_rogpeppe, also there's no such type as a Relation ATM08:44
fwereade_rogpeppe, I'll add one if it seems worthwhile ofc ;)08:44
rogpeppefwereade_: there is actually08:44
rogpeppefwereade_: see relation.go:/^type Relation08:44
fwereade_rogpeppe, the way I currently have to get to a group is RelatedService.group(u *Unit)08:45
fwereade_rogpeppe, I deleted it08:45
rogpeppefwereade_: ah.08:45
fwereade_rogpeppe, it's entirely useless08:45
fwereade_rogpeppe, anyway, can we agree that I'm not *obviously* high, yet, although there cretainly are naming issues to be sorted out here?08:46
rogpeppefwereade_: i definitely think there's something to what you're saying, but i don't think it's just naming that's at issue.08:47
fwereade_rogpeppe, because the next step is to point out that a RelatedUnitsWatcher could be, in terms of vocabulary we've been discussing, a GroupRoleWatcher08:47
fwereade_rogpeppe, ah, ok, let's back up then08:47
rogpeppefwereade_: or rather, naming has semantic implications too08:48
fwereade_rogpeppe, oh hell yes08:48
fwereade_rogpeppe, I'm kinda hoping that naming fixes will fall out of the discussion08:49
rogpeppefwereade_: not sure about GroupRoleWatcher - that sounds like it's watching for changes in group roles08:49
fwereade_rogpeppe, for example with the scope idea that becomes a ScopeRoleWatcher, which feels much closer to what it's really doing08:49
rogpeppefwereade_: but it is actually watching for related units, no?08:49
fwereade_rogpeppe, yeah, it could indeed just be called a RelatedUnitsWatcher08:50
fwereade_rogpeppe, but it feels slightly important to make it clear that it's scoped08:50
rogpeppefwereade_: just that RelatedUnitsWatcher watches for related units within a particular scope, no?08:50
fwereade_rogpeppe, yeah, it's also reasonable to just ignore that entirely -- pass in a group/scope and not mention it at all in the type name08:51
fwereade_rogpeppe, probably a better idea all things considered08:51
rogpeppefwereade_: if we create the RelatedUnitsWatcher from a RelationScope, that would be obvious, perhaps08:51
fwereade_rogpeppe, yeah08:52
fwereade_rogpeppe, ok stepping back again a mo08:53
rogpeppefwereade_: type ScopeKind string?08:53
fwereade_rogpeppe, yeah, +108:54
fwereade_rogpeppe, a unit agent has a unit08:54
fwereade_rogpeppe, it can find out its service, and fro that get some RelatedServices08:54
fwereade_rogpeppe, given a unit and a RelatedService we can figure out the Scope08:55
rogpeppefunc (r *ServiceRelation) Scope(unit *Unit) RelationScope08:55
fwereade_rogpeppe, a Scope is useful both for watching related units and for signalling the unit agent's presence within the relation08:55
fwereade_rogpeppe, yeah08:55
rogpeppefor globally scoped relations, unit could be nil08:56
fwereade_rogpeppe, doesn't matter I think08:56
rogpeppefwereade_: that's true.08:56
rogpeppei think08:56
fwereade_rogpeppe, I think the question we're asking is "what scope will this unit be in if it joins, or please give me an error of the unit can't join"08:57
fwereade_and finally...08:57
fwereade_rogpeppe, watching related units, and signalling ones presence in the relation, are profoundly intimately bound up08:57
fwereade_rogpeppe, such that we don't want a unit agent ever doing just one of those things08:57
fwereade_rogpeppe, by signalling presence, it's advertising that it's also watching and responding to the related units08:58
rogpeppesorry, parcel just arrived08:59
fwereade_rogpeppe, and I *think* the right high-level thing for this is `func (u*Unit) AgentJoin(s *RelatedService) (*SOMETHING, error)`08:59
rogpeppeback now though08:59
fwereade_rogpeppe, where that SOMETHING is... I dunno, I've been calling it a JoinedService, but that's obviously wrong09:00
fwereade_rogpeppe, JoinedScope might be better09:00
fwereade_rogpeppe, (it's purpose is (1) to provide access to a RelatedUnitsWatcher's Changes channel, and (2) to maintain a pinger on the approriate path so that SOMETHINGs on other unit agents detect it)09:01
fwereade_rogpeppe, and if either of those tasks fail both should fail09:01
rogpeppefunc (u*Unit) AgentJoin(s *RelatedService) (*presence.Pinger, *someWatcherType, error) ?09:01
fwereade_rogpeppe, -109:02
fwereade_rogpeppe, if one of those things dies the other should too09:02
fwereade_rogpeppe, if anything that type is a RelationUnit09:02
fwereade_rogpeppe, but it's something whose mere *existence* has broad impact on other processes09:03
fwereade_rogpeppe, so I'm very reluctant to use that name ;)09:03
fwereade_rogpeppe, ScopePresence? JoinedRelation? JoinedScope? JoinedService?09:04
fwereade_rogpeppe, Joined is IMO a good word09:04
rogpeppefwereade_: i don't mind if we let the unit agent do some work, rather than pushing everything into a state type09:04
fwereade_rogpeppe, the unit agent will be doing *plently* of work09:04
rogpeppefwereade_: it's very easy for the unit agent to do: defer pinger.Stop()09:05
fwereade_rogpeppe, and to react to its death as well?09:05
fwereade_rogpeppe, to clean up one if the other dies, and vice versa?09:05
fwereade_rogpeppe, sound to me like a job for a type honestly09:05
rogpeppefwereade_: yeah, we'll already have a loop with a select in09:05
fwereade_rogpeppe, and it will also be simple to express Depart() and Abandon()?09:07
rogpeppefwereade_: but i'm sure a type could work well too09:07
fwereade_rogpeppe, ok, I think I'll go with ScopeKind string and RelationScope struct {*zk.Conn, string}09:10
fwereade_rogpeppe, see what falls out of that09:10
rogpeppefwereade_: i think that sounds good.09:10
fwereade_rogpeppe, TheMue: since I'm making this change, I wonder how you feel about s/RelationRole/RoleKind/ throughout as well09:12
fwereade_rogpeppe, TheMue: for consistency's sake if nothing else09:12
rogpeppefwereade_: that sounds good to me too09:13
fwereade_rogpeppe, TheMue: (also, for methods/fields currently called RelationRole/RelationScope, name them Role and Scope unless that causes ambiguity?)09:13
rogpeppefwereade_: and i'm thinking that the methods on ServiceRelation don't really benefit from having "Relation" prefixes09:13
rogpeppejinx09:13
fwereade_rogpeppe, RelationName kinda does09:13
rogpeppefwereade_: i don't mind ServiceRelation.Name09:14
fwereade_rogpeppe, but i want to call that type RelatedService :)09:14
rogpeppeah09:14
fwereade_rogpeppe, which IMO has more appropriate connotations09:15
fwereade_rogpeppe, but then, hmm.09:15
rogpeppefwereade_: in which case, yeah, RelationName is better09:15
fwereade_rogpeppe, similarly, in that case, RelationScope09:15
fwereade_rogpeppe, but Role is something that really is on the service not the relation so that should change09:16
fwereade_rogpeppe, it's more things like09:16
rogpeppefwereade_: i don't mind Scope on RelatedService actually09:16
rogpeppefwereade_: because services don't have scopes09:16
fwereade_rogpeppe, true, and the scope is shared by both ends of the relation09:16
rogpeppefwereade_: so it's obvious that it's about the Related bit of the name09:16
fwereade_rogpeppe, cool09:17
rogpeppefwereade_: i vote for a small CL cleaning up these issues, then another one renaming RelationScope to ScopeKind09:17
fwereade_rogpeppe, yeah, that sounds sensible09:18
rogpeppefwereade_: as they're orthogonal and the latter is more controversial09:18
fwereade_rogpeppe, I'll think on it a touch more though09:18
rogpeppek09:18
fwereade_rogpeppe, most of this morning's conversation is *really* about me figuring what order I can make CLs in to maximise my chances of getting all this stuff in ;)09:19
rogpeppefwereade_: ah, but you've now changed *what* you're gonna put in!09:19
rogpeppefwereade_: and i, for one, think it's a really nice step forward09:20
fwereade_rogpeppe, the types haven't changed, I think, just the names :)09:20
TheMuefwereade_: You know the current Py code best. If there's no conflict with Role and Scope I'm fine with it.09:20
fwereade_rogpeppe, (from what I was originally intending, that is; it's definitely changed from the py in some ways ;))09:20
rogpeppefwereade_: having ScopeKind hanging off RelationScope is new, i think09:20
rogpeppefwereade_: yeah. but the names make so much difference. when it was "RelatedGroup" i was, like, "where are the things in the group?". but now it's a "RelationScope", i see it as a container and it makes sense to me.09:22
fwereade_rogpeppe, yeah, tyvm for helping out with that09:23
rogpeppefwereade_: even though the underlying representation might be identical09:23
fwereade_rogpeppe, that was what I was looking for, and what I got :)09:23
rogpeppefwereade_: np. i would never have got as far as you did!09:24
fwereade_rogpeppe, I'm lucky to have undergone the baptism by fire that was the restartable-unit-agent work in the python09:24
fwereade_rogpeppe, that was enough that figuring out the real details here was.. possible09:24
rogpeppefwereade_: just had a silly naming idea09:25
fwereade_rogpeppe, oo, go on09:25
rogpeppefwereade_: so we've got these "scopes" right? so when we've got a language implementation, what do we call the actual implementation of scopes? "frames".09:26
rogpeppefwereade_: sadly it doesn't really work09:26
fwereade_rogpeppe, I don't think it quite does :(09:26
fwereade_rogpeppe, I culd call them continuations I suppose, if I really want someone to stab me09:26
rogpeppefwereade_: actually, maybe just RelationSettings might be appropriate09:27
fwereade_rogpeppe, -109:27
rogpeppefwereade_: as it's the settings that are scoped09:28
fwereade_rogpeppe, (1) they're presence as well (2) the only thing that should actually be reading the settings is the RelatedUnitsWatcher anyway09:28
rogpeppefwereade_: yeah09:30
rogpeppefwereade_: i'm just slightly concerned that the word "scope" implies something abstract rather than concrete09:30
Arammoin10:10
TheMueAram: Moin. Hehe, you adopted the usual greeting here in Northern Germany.10:20
TheMueLunchtime10:29
rogpeppefwereade_: ping11:14
fwereade_rogpeppe, pong11:15
rogpeppefwereade_: i wonder if you can help me thinking about a good way to test this new package: http://paste.ubuntu.com/1042221/11:15
rogpeppefwereade_: i can mock up start commands like the upstart package does11:16
rogpeppefwereade_: but i don't think it provides any useful assurance of anything11:16
rogpeppefwereade_: i'm considering a "-root" flag to the test, for tests that need to run as root.11:17
rogpeppefwereade_: then we can test it for real.11:17
fwereade_rogpeppe, yeah, it's tricky; in the python we had exactly that11:17
rogpeppefwereade_: a "-root" flag?11:17
fwereade_rogpeppe, and it always felt a little icky but I never saw any other way to really verify it11:17
fwereade_rogpeppe, well, a USE_SUDO env var11:17
fwereade_rogpeppe, but basically yes11:18
rogpeppefwereade_: it's particularly an issue for the LXC-manipulating code11:18
fwereade_rogpeppe, yeah, that's the main place we had it for11:18
rogpeppefwereade_: ok, that's useful, thanks11:18
fwereade_rogpeppe, I think I had it for the upstart stuff in the local provider as well11:18
rogpeppefwereade_: i think i'll go for a "-root" flag and require that the user id be root if it's set11:19
fwereade_rogpeppe, if you're going to require that, can't you just check for root and explicitly skip the tests that require it if not?11:20
rogpeppefwereade_: i thought of that, but i'm not sure i want the tests manipulating my global state without me explictly asking them to do so11:20
fwereade_rogpeppe, IMO by running them as root you're explicitly asking them to do so11:20
rogpeppefwereade_: sometimes i'm running a root shell without being aware of it...11:21
rogpeppefwereade_: but maybe it's ok11:21
fwereade_rogpeppe, ah, fair enough11:21
rogpeppefwereade_: and it means that i could do sudo go test ./...11:21
fwereade_rogpeppe, I *think* I've broken myself of that habit even when I really want to11:21
* rogpeppe hates sudo11:22
rogpepperather, i hate the requirement that so many things run as root11:22
fwereade_rogpeppe, ha, yeah11:23
fwereade_rogpeppe, TheMue: I have a thought about topoRelationService11:24
* rogpeppe is all ears11:24
fwereade_rogpeppe, at the moment a topoRelation has Services, which holds topoRelationServices keyed on service key11:24
fwereade_rogpeppe, tRS has RelationName and Role fields11:25
fwereade_rogpeppe, each taken from the appropriate endpoint of the apropriate service11:25
fwereade_rogpeppe, I contend that even here, the relation name should be taken from the opposite endpoint11:25
fwereade_rogpeppe, because, in the context of a relation, the important thing about a service is what the *other* end thinking it's called11:26
rogpeppefwereade_: what is the relation name BTW? is it a key?11:26
fwereade_rogpeppe, *db*-relation-joined11:26
fwereade_rogpeppe, *blog*-relation-changed11:27
fwereade_rogpeppe, etc11:27
rogpeppefwereade_: ok, thought so, just checking11:27
fwereade_rogpeppe, it's the name used within a charm to refer to the other end of the relation11:27
fwereade_rogpeppe, so it seems stupid for a service to store (1) what it does and (2) what it thinks the other end's called11:28
fwereade_rogpeppe, when it could store (1) what it does and (2) what it's called (from the perspective of the rest of the relation)11:28
fwereade_rogpeppe, it's non-obvious but I'm becoming convinced that the obvious solution is crack11:29
* rogpeppe is looking at the code11:31
fwereade_TheMue, when you return, I would also appreciate your opinion of the foregoing11:32
rogpeppefwereade_: hmm. this stuff is barely used at the moment. how do you anticipate it being used?11:36
rogpeppefwereade_: (currently there's just a single call to topology.Relation11:37
rogpeppe)11:37
fwereade_rogpeppe, well, I have this idea the a RelatedService is {relationKey string, serviceKey string, relater RelationEndpoint}11:37
rogpeppefwereade_: what's an "endpoint" again?11:38
fwereade_rogpeppe, where "relater" is the endpoint of the service at the "local" end of the relation11:38
fwereade_rogpeppe, relation name, interface, role, scope11:38
rogpeppeok11:38
fwereade_rogpeppe,  oh and service name11:39
rogpeppefwereade_: am i wrong that the only thing in that endpoint tuple that can't be derived from relationKey is the role?11:41
fwereade_rogpeppe, also the name11:41
rogpeppefwereade_: that comes from the relationKey and role too, doesn't it11:42
fwereade_rogpeppe, which needs to come from the topoRelationService, and which I contend is the wrong way round at the moment11:42
fwereade_rogpeppe, but, yes; it's pretty trivial to construct the RelatedService above, given a topology and a relation key11:42
rogpeppefwereade_: i'm thinking that a RelatedService is more {relationKey string, role RelationRole}11:42
fwereade_rogpeppe, sure, it could be, but the fields I described are the ones that are (1) convenient to access when constructing and (2) used subsequently11:43
rogpeppefwereade_: i'm trying to think fundamentals, not optimisation.11:44
fwereade_rogpeppe, if we only stored what you suggest it would be doable but a bloody hassle11:44
rogpeppefwereade_: really?11:44
rogpeppefwereade_: well, of course it'd need to store the topology too11:45
fwereade_rogpeppe, rooting around in the topology, looping through relation Services dicts trying to find the data it's looking for11:45
fwereade_rogpeppe, I'd really much rather collect all the relevant info than the bare minimum necessary to infer that info11:45
fwereade_rogpeppe, (otherwise why have types at all? :p)11:45
fwereade_rogpeppe, this would be problematic if relations could change after being created, but the fact of a relation and its endpoints is not something that changes over the lifetime of that relation11:46
rogpeppefwereade_: i guess i was trying to get to the bottom of what is *necessary* for a RelatedService11:46
fwereade_rogpeppe, it could equally be relationKey, serviceKey11:47
fwereade_rogpeppe, we can infer role from service+relation just as we can infer service from relation+role11:48
rogpeppefwereade_: ah, that seems more logical, given the name11:48
rogpeppefwereade_: ah, except that relationKey isn't visible outside state11:48
fwereade_rogpeppe, we don't have to expose it11:49
fwereade_;)11:49
fwereade_rogpeppe, I don't think we really want to expose much on a RelatedService at all tbh11:50
rogpeppefwereade_: what do we get from RelatedService that we don't get from Scope?11:50
fwereade_rogpeppe, I certainly don't need anything public *yet*11:50
fwereade_rogpeppe, scope covers both ends11:51
fwereade_rogpeppe, relatedservice is about one end only11:51
rogpeppefwereade_: i'm wondering about: func (svc *Service) Relation(u *Unit) *Scope11:51
rogpeppeah11:51
fwereade_rogpeppe, why would I care about that?11:51
fwereade_rogpeppe, the only actual use case is for the unit agent to loop over the related services and respond to changes in each11:52
fwereade_rogpeppe, for that I just want a list of RelatedServices, each of which describes what I need to know to join a relation with it11:52
* rogpeppe is starting to see11:52
* fwereade_ is hugely relieved11:53
fwereade_rogpeppe, I've been a bit nervous about all this -- it is definitely different to the python, but I think it is a projection of the same problem into a simpler space11:53
rogpeppe:-)11:53
fwereade_rogpeppe, and it's far from immediately obvious that that's the case ;)11:54
rogpeppefwereade_: the zk representation is pretty much the same though, right?11:54
fwereade_rogpeppe, I need to make another pass over the topology code, but yes, I think so11:55
fwereade_rogpeppe, the zk representation of the actual live relations is identical11:55
fwereade_rogpeppe, but I think the code representation of that representation is much nicer like this11:55
rogpeppefwereade_: dumb question: why isn't a RelatedService just a Service?11:56
fwereade_rogpeppe, I think that it will lead to a much cleaner clearer data flow11:56
fwereade_rogpeppe, because a service doesn't in itself have a role/relname/scope11:56
fwereade_rogpeppe, it has a whole bunch of relations, only one of which we're interested in at a time11:56
rogpeppefwereade_: but you could have something like: func (svc *Service) Join(*Service) error, though, no?11:57
fwereade_rogpeppe, I *think* that it's units which have to join services11:57
rogpeppefwereade_: oh yeah11:58
fwereade_rogpeppe, but I may be missing context... what would that do?11:58
fwereade_rogpeppe, at first glance that really looks like a different version of AddRelation(endpoints)11:58
fwereade_rogpeppe, but not specific enough to do anything, because there may be more than one valid pair of endpoints between the services11:59
rogpeppefwereade_: yeah, i've realised that11:59
rogpeppefwereade_: i'm just wondering if there's some way of doing without RelatedService11:59
fwereade_rogpeppe, I thought there was at one stage but the code said it wanted it12:00
fwereade_rogpeppe, (I understood the code to be saying it wanted it ;))12:00
rogpeppefwereade_: so i'm just trying to think about what the unit agent is doing12:00
fwereade_rogpeppe, I'm expecting pseudocode:12:01
fwereade_rogpeppe, for rs in self.unit.service.related_services: self.unit.AgentJoin(rs)12:02
fwereade_rogpeppe, and therefrom marshal the changes coming out of the JoinedService, or whatever we call it, into actual hook executions12:02
rogpeppefwereade_: i was toying with the idea of: func (u *Unit) Join(svc1, svc2 *Service)12:02
fwereade_rogpeppe, which is a separate and not entirely trivial thing12:02
fwereade_rogpeppe, what are the two services for?12:03
fwereade_rogpeppe, surely we can infer one of those from the unit12:03
rogpeppeah, we need a relation name too12:03
fwereade_rogpeppe, IMO hence the value of RelatedServcei12:03
rogpeppefwereade_: func (u *Unit) Join(svc *Service, relationName string)12:03
fwereade_rogpeppe, that doesn't uniquely identify the relation12:04
fwereade_rogpeppe, I, mysql, might have a bunch of different "db" relations going at the same time12:04
rogpeppefwereade_: really?12:04
fwereade_rogpeppe, ah but hmm maybe with service it is unique12:04
rogpeppefwereade_: i thought each relation had a unique name12:04
rogpeppefwereade_: yeah12:04
fwereade_rogpeppe, nah, this was something I only recently appreciated12:05
fwereade_rogpeppe, as a unit I may be participating in multiple foo relations12:05
rogpeppefwereade_: if a service provides a relation, it can be joined by more than one other service?12:05
fwereade_rogpeppe, charm authors handle this by looking at RELATION_IDENT in the hook context when running foo-relation-*12:05
fwereade_rogpeppe, yeah12:06
fwereade_rogpeppe, but those are still multiple relations12:06
fwereade_rogpeppe, (relation means different things in different contexts, unhelpfully)12:06
rogpeppefwereade_: ah, makes sense, if we want to share db connections etc12:06
rogpeppeanother piece of the puzzle falls into place12:06
fwereade_rogpeppe, the prospect of writing a charm that handles all that right makes my head hurt12:06
fwereade_rogpeppe, but we do provide all the information required to do so, I think12:07
fwereade_ciggie, brb12:07
rogpeppefwereade_: k12:07
fwereade_rogpeppe, b12:14
rogpeppefwereade_: but you can't have more than one of the same relation going on with a single other service, right?12:16
fwereade_rogpeppe, apart from that being somewhat crazy, Idon't think there's anything stopping you from doing so12:17
rogpeppefwereade_: i'm not sure you *can* do that though12:17
rogpeppefwereade_: how would you?12:17
fwereade_rogpeppe, I could certainly write a charm that had 2 relations with the same interface and role12:18
rogpeppefwereade_: yeah, but they'd have different relation names12:18
fwereade_rogpeppe, but on the *other* end on the charm with just one relation, those two others would have the same name12:18
rogpeppefwereade_: which is why i'm thinking that this could work ok:  func (u *Unit) Join(svc *Service, relationName string)12:19
rogpeppefwereade_: where relationName specifies the name at the other end12:19
fwereade_rogpeppe, if I'm mysql, I don't care whether your relation name is "db" or "posts" or what12:19
rogpeppefwereade_: i'm not quite sure how that's relevant.12:20
fwereade_rogpeppe, I, as mysql, am calling you "db", regardless12:20
rogpeppefwereade_: ok12:20
rogpeppefwereade_: and?12:20
fwereade_rogpeppe, why does one end of the relation ever want to know internal name the other end is using for the  first end?12:21
fwereade_rogpeppe, except to do what you suggest12:21
fwereade_rogpeppe, but then how does it get that information without smooshing all the RelatedService construction stuff inline?12:22
rogpeppefwereade_: ok, i think i'm *starting* to get there.12:23
fwereade_rogpeppe, IMO far easier to have (*Unit)AgentJoin(*RelatedService), which can barf quickly and easily if the unit's service name doesn't match the relater endpoint's service name12:23
rogpeppefwereade_: so you call Service.RelatedServices. then for each one of those, you can do Unit.Join(service)12:23
fwereade_rogpeppe, yeah, that's the idea12:23
fwereade_rogpeppe, RelatedServices is also I think just the right info for status display12:24
fwereade_rogpeppe, again we want to know what the service we're looking at thinks the related services are called, not what the related services think the current service is called12:25
rogpeppefwereade_: or even RelatedService.Add(*Unit)12:25
fwereade_rogpeppe, I don;t think that fits, I think join is exactly the right word12:25
rogpeppeok, yeah it works12:25
rogpeppe'specially with the usual xxx-relation-joined stuff12:26
fwereade_rogpeppe, exactly so12:26
fwereade_rogpeppe, we end up with methods like JoinedRelation.Depart(), which will cause -departed hooks to fire at the other end12:26
fwereade_rogpeppe, just as the Join causes -joined hooks to fire at the other end12:26
fwereade_rogpeppe, I also have a plan to write an Abscond method (ie depart but try to keep it secret for as long as possible) ;)12:27
rogpeppelol12:27
rogpeppefwereade_: maybe "Relation" is a good spelling for "JoinedRelation"12:28
rogpeppefwereade_: given you deleted the Relation type12:28
fwereade_rogpeppe, oh yes, I like that12:29
rogpeppefwereade_: cool.12:29
rogpeppefwereade_: so we're looking at something like this: http://paste.ubuntu.com/1042310/ ?12:33
fwereade_rogpeppe, close12:34
fwereade_rogpeppe, just a sec12:34
fwereade_rogpeppe, more like http://paste.ubuntu.com/1042315/ I think12:36
fwereade_rogpeppe, sorry crappy type name on Changes12:36
fwereade_rogpeppe, RelatedUnitsChange probably better12:37
rogpeppefwereade_: you'll still need Service.WatchRelatedServices though, no?12:37
fwereade_rogpeppe, well, yeah, I'll need to pay attention to what relations I'm meant to be part of12:38
fwereade_rogpeppe, that feels pretty simple and not really related at this stage12:38
rogpeppefwereade_: yeah, so you can watch 'em.12:38
rogpeppefwereade_: but i think you'll need an Attach method or something because you need some way of making a Relation without creating the join node12:38
fwereade_rogpeppe, so, yeah, I'll need a RelatedServicesWatcher12:38
fwereade_rogpeppe, why?12:38
rogpeppefwereade_: or maybe not12:38
rogpeppefwereade_: yeah, if the node already exists, we do nothing, that works12:39
fwereade_rogpeppe, I will probably want some way to get a list of the units involved, for status display12:39
rogpeppefwereade_: so unless i've missed something, the only change above is to add Relation.Changes ?12:39
rogpeppeRelatedService.Units12:39
fwereade_rogpeppe, yeah, I think so12:40
rogpeppefwereade_: perhaps ScopeUnitChange would be better spelled RelationSettingsChange12:40
fwereade_rogpeppe, also includes departs12:41
rogpeppefwereade_: hmm12:41
fwereade_rogpeppe, I think RelatedUnitsChange to go with RelatedUnitsWatcher12:41
rogpeppefwereade_: yeah12:41
rogpeppefwereade_: actually, given that there will be two independent watchers for the relation setting and the unit departure, maybe it makes sense to have two channels12:42
rogpeppefwereade_: rather than trying to stuff 'em both into the same type12:42
fwereade_rogpeppe, under the hood, there may well be12:43
fwereade_rogpeppe, I'm expecting RelatedUnitsChange to be {Updates map[string]string, Deletes []string}12:43
fwereade_rogpeppe, which I *think* is exactly the format we wnt for a hook scheduler12:44
fwereade_rogpeppe, where updates is map[unitKey]settingsData12:44
fwereade_rogpeppe, there's an interesting debate to be had on the precise type to use for the settings data12:45
fwereade_rogpeppe, but for today it's a derail ;)12:45
rogpeppefwereade_: ConfigNode12:45
fwereade_rogpeppe, hell no12:45
rogpeppemebbe12:45
rogpeppeno? ok12:45
fwereade_rogpeppe, we definitely don;t want any other bastard writing to our settings ;)12:45
rogpeppefwereade_: we're in control here, remember?12:45
rogpeppefwereade_: convention is ok12:46
fwereade_rogpeppe, another reason: we don;t want to see zookeeper state12:46
fwereade_rogpeppe, we want to see the state as it was at the time the change was detected12:46
rogpeppefwereade_: why would we? ConfigNode has a cache12:46
rogpeppefwereade_: but yeah, why not pass along the map[string]interface{}12:46
fwereade_rogpeppe, so, plausibly, map[string]map[string]interface{}12:46
rogpeppefwereade_: yup12:47
rogpeppefwereade_: so where did you want to put the departed watch info?12:47
fwereade_rogpeppe, departs will be in Deletes12:47
fwereade_rogpeppe, which should maybe even be called Departs because they do map cleanly onto hook executions, in a way that updates don't12:48
rogpeppe{Updates map[*Unit] string; Deletes []*Unit} ?12:49
rogpeppeoops12:49
rogpeppei mean12:49
rogpeppemap[*Unit]map[string]interface{}12:49
rogpeppeexcept units don't live well in maps, i suppse12:49
fwereade_rogpeppe, I'm not really sure why we need the *unit, especially since it might plausibly not exist by the time we try to look at it12:49
fwereade_rogpeppe, unit names only I think12:50
rogpeppefwereade_: that's true of MachineUnitsWatcher too though12:50
fwereade_rogpeppe, but probably the client of MachineUnitsWatcher actually wants to do something with the *Units though12:50
rogpeppefwereade_: and the unit agent doesn't?12:51
fwereade_rogpeppe, I don't think so12:51
fwereade_rogpeppe, again it's trying to present (to the hooks it runs) an immutable facade representing the state at the time it was known to have changed12:52
rogpeppefwereade_: BTW a little diversionary sketch i did early this morning: http://paste.ubuntu.com/1042285/12:52
fwereade_rogpeppe, I can't think of any Unit methods I'd want or need to call12:52
rogpeppefwereade_: ok, that's cool12:52
rogpeppefwereade_: so the strings would be unit names?12:53
fwereade_rogpeppe, yeah, that's what the hooks expect to work with expect to see12:53
fwereade_rogpeppe, I'm sure I have something kinda similar to that lying around somewhere :)12:53
rogpeppefwereade_: i think it should be quite quick to write.12:54
fwereade_rogpeppe, yeah, I think I already wrote most of it a while ago, then gotstymied by the lack of relations :)12:54
rogpeppefwereade_: the idea is that in every hook you put '#!/bin/sh\ngohook $0'12:54
rogpeppefwereade_: how do you mean?12:55
fwereade_rogpeppe, ok, I suspect what you wrote doesn't do what I thought it did12:55
fwereade_rogpeppe, explain please?12:55
fwereade_rogpeppe, (I'm not so sure about that HookKind busines either)12:56
rogpeppefwereade_: so you've got one go server that runs; the hooks talk to it with rpc.12:56
fwereade_rogpeppe, yes12:56
rogpeppefwereade_: when a hook executes, Wait returns a context, which you can then use to do the usual hooky things, until you close it, which terminates the hook execution12:57
fwereade_rogpeppe, ah, yes, I misread the stuff at the bottom12:58
rogpeppefwereade_: it's a kind of inversion of the usual callback-driven control flow, but makes sense in the go world i think12:58
fwereade_rogpeppe, I am in general suspicious of the idea that we should let people run hooks whenever they want to12:58
rogpeppefwereade_: they can't12:58
rogpeppefwereade_: you can only get a context when a hook is run by juju12:58
fwereade_rogpeppe, ok, sorry, who's calling RunHook?12:59
rogpeppefwereade_: in every hook you want to register, you have a shell script that does, as above:12:59
rogpeppe#!/bin/shj12:59
rogpeppegohook $012:59
rogpeppes/shj/sh/12:59
rogpeppeotherwise there's no way of knowing what hooks you want to register with juju13:00
fwereade_rogpeppe, isn't that hugely complicated compared to "if the file exists, it's a hook"?13:00
rogpeppefwereade_: it uses that mechanism13:00
rogpeppefwereade_: but all the hooks get actually executed in the same go program context.13:01
fwereade_rogpeppe, still not seeing what we get out of that13:02
rogpeppefwereade_: i *think* you could write pretty charms with it.13:02
rogpeppefwereade_: 'cos i'm not a big fan of callbacks13:02
rogpeppefwereade_: but yeah it's just an idea13:02
fwereade_rogpeppe, oh, I think I see13:03
fwereade_rogpeppe, yeah, that is interesting :)13:03
fwereade_rogpeppe, maybe one of those ones to do in our copious free time though ;p13:03
rogpeppefwereade_: yeah, definitely. all that copious free time.13:04
rogpeppefwereade_: i suspect it'd only be a hundred or so lines of code though.13:04
fwereade_niemeyer, heyhey13:29
TheMueniemeyer: Moin13:29
niemeyerHellos!13:30
* niemeyer waves13:30
fwereade_TheMue, did youhave any thought on that stuff (some way) above (by now)?13:30
jimbakerfwereade_, certainly feel free to ping me with any questions on the relation id stuff13:31
fwereade_TheMue, starting at round about 13:2413:31
TheMuefwereade_: One moment, will read it quickly.13:32
fwereade_jimbaker, cool, thanks -- I'll be getting there before too long I think :)13:32
jimbakerfwereade_, also if you have any more thoughts on the merge proposal for format: 2 support that would be great13:32
fwereade_TheMue, sorry, it gets pretty wide-ranging13:32
fwereade_jimbaker, crap, sorry, I'll take another look sometime today13:32
fwereade_TheMue, the bit I'm really concerned about is that IMO we're storing the wrong relation names in the topology13:33
jimbakerfwereade_, no worries. thanks for taking a look at this, you had some great comments. i did refactor to use polymorphism so the parallel code paths are all now in one place. lot cleaner code. and a lot more tests. (almost at 2000 for the python version as a whole)13:33
fwereade_jimbaker, awesome13:34
* niemeyer sips some great chimarrão on that shadowing Friday morning13:36
rogpeppeniemeyer: hiya!13:41
rogpeppefwereade_: i still don't quite see it. is your concern that the topology isn't storing the right info, or that the info is just a bit harder to get to than it should be?13:44
fwereade_rogpeppe, well, all the necessary bits are there, but in a misleading configuration13:45
fwereade_rogpeppe, we're storing a service's role together with what it thinks the other service is called13:45
fwereade_rogpeppe, considering it from the POV of the relation13:45
fwereade_rogpeppe, we should be storing name and role together13:45
rogpeppefwereade_: "storing a service's role together with what it thinks the other service is called" currently? or as you'd like it to be?13:46
fwereade_rogpeppe, that's current13:46
rogpeppefwereade_: ah, that seems odd13:46
fwereade_rogpeppe, indeed so13:47
fwereade_rogpeppe, it's tempting to do what we currently do because we're storing information from a single endpoint together13:47
TheMuefwereade_: Just for info, I didn't forget you, but it's a lot to read. ;)13:47
fwereade_TheMue, ofc, np13:47
rogpeppefwereade_: actually, i can't see anywhere that topoRelationService.RelationName is set13:48
fwereade_TheMue, it's restated succinctly just above though13:48
fwereade_rogpeppe, it's in State.AddRelation13:48
fwereade_rogpeppe, TheMue: storing the name according to the other end is more work but (1) IMO more correct and (2) also fits better with the RelatedService ideas discussed earlier13:49
fwereade_TheMue, if there's anything I can clarify please ask away :)13:50
rogpeppefwereade_: there's a one-to-one mapping between endpoints and topoRelationServices. that seems good to me.13:54
rogpeppefwereade_: i suppose the problem is i can't envisage the code which the current structure would make awkward13:54
fwereade_rogpeppe, the point is much more that it's wrong than that it's awkward13:55
rogpeppefwereade_: whether it's wrong depends on how we're gonna use it, no?13:55
fwereade_rogpeppe, well, the name is wrong anyway... and calling it NameByWhichWeReferToTheOtherServiceInThisRelationIfItExists is somewhat awkward13:56
fwereade_rogpeppe, whereas Name, implying "what other people call us", seems rather saner to me13:57
fwereade_rogpeppe, and the fact that it's stored within relation data should make the context clear IMO13:57
TheMuefwereade_: I don't know if I got everything right, but as far as I can follow it sounds reasonable.13:57
rogpeppefwereade_: so the RelationName in RelationEndpoint is the name as referred to by whom?13:57
rogpeppei see the awkwardness, because every relation has two names13:58
rogpeppefwereade_: so RelationName is ambiguous, which i hadn't really appreciated before13:59
fwereade_rogpeppe, the very term "relation" is ambiguous13:59
fwereade_rogpeppe, do we mean "thing in the 'relations' part of charm metadata", or "connection between two services"?14:00
rogpeppefwereade_: because it represents the abstract relation as defined in the metadata, but also ...14:00
rogpeppefwereade_: yeah14:00
rogpeppefwereade_: maybe if we sort out some terminology for that, then everything will become clearer14:01
fwereade_rogpeppe, perhaps, but I fear both meanings are (1) user-facing and (2) entrenched already14:01
rogpeppefwereade_: is there anywhere in the current code that we use "relation" to mean "the abstract relation as defined in the metadata" ?14:02
fwereade_rogpeppe, I think that's the meaning of RelationEndpoint.RelationName14:02
TheMuerogpeppe: At least in the yet ported code not.14:02
fwereade_rogpeppe, an endpoint is a perfectly meaningful construct even when not participating in a relation14:03
rogpeppefwereade_: hmm. so it's more PotentialRelationEndpoint than RelationEndpoint.14:04
fwereade_rogpeppe, heh, if you like :)14:05
fwereade_rogpeppe, I'd say it still exists even if don't connect to it14:05
rogpeppefwereade_: i'm trying to contrast with the other kind of endpoint, which actually exists and has an id14:05
rogpeppemaybe. i'm still fuzzy!14:06
fwereade_rogpeppe, sorry, what other kind of endpoint? topoRelationService?14:06
fwereade_rogpeppe, I don't really see that as an endpoint14:06
fwereade_rogpeppe, although I can certainly see a perspective from which that conception of it makes sense14:06
fwereade_rogpeppe, no, can't be, TRSs don't have ids14:08
fwereade_rogpeppe, I'm confused14:08
rogpeppefwereade_: what id is given to the hook? the relation key?14:08
* TheMue would like a whiteboard for the discussion. 14:08
fwereade_rogpeppe, yeah, effectively14:09
* rogpeppe too14:09
fwereade_rogpeppe, IIRC we strip unnecessary 0s14:09
* rogpeppe would like to see a snapshot of a fully populated zk tree14:09
* fwereade_ sympathises but doesn't think he has anything like that handy14:10
TheMuefwereade_: Could you mail a kind of outline of how the entities, structure and topology should look like to juju-dev?14:17
TheMuefwereade_: So it's mo simple to think about it twice and make annotations.14:17
fwereade_TheMue, this is 100% internal to the topology14:17
fwereade_TheMue, wait, except that it affects ServiceRelation.relationName14:18
TheMuefwereade_: Which makes it a bit simpler. ;)14:18
fwereade_TheMue, but if yu look at the docs for ServiceRelation it's very clear that it's "from the viewpoint of a participant service"14:18
fwereade_TheMue, my point is in essence very simple: that the RelationName stored in a topoRelstionService does not actually refer to that service14:19
fwereade_TheMue, and that this is a Bad Thing14:19
rogpeppefwereade_, TheMue: i'm writing a quick snapshot of how i think the whole thing will look, with a single wordpress/mysql instance. feel free to edit with me: https://docs.google.com/a/canonical.com/document/d/1z2bIJ097qawOPGtZnHABIqNPVXaQ5ePCRIQVYGfcHsg/edit14:21
TheMuerogpeppe: Thx *click*14:21
TheMuerogpeppe: Need access, request is sent. ;)14:22
rogpeppeTheMue: you should be able to access it with your canonical account14:22
TheMuerogpeppe: OK, I mostly use my old private one, also for lp.14:23
hazmathuh.. haven't seen this before "Your Amazon EC2 Instance scheduled for retirement "14:23
hazmatemail notification14:23
hazmati think that's for the jujucharms site14:23
rogpeppehazmat: poor dear. i hope it gets a pension.14:23
TheMuerogpeppe: I'm in.14:24
hazmatrogpeppe, this ain't no socialist cloud! ;-)14:24
rogpeppehazmat: paid for by its earnings over its lifetime, of course :-)14:24
fwereade_rogpeppe, balls, I appear to have the wrong @canonical.com google password stored... and resetting it doesn't appear to have sent me anything14:25
fwereade_rogpeppe, grar ok they won't send it to me14:25
hazmatrogpeppe, it was unemployed for most of its life sadly, and abused by the state, and  burden to it as we ll apparently. i'm going to appeal to amnesty international for it as a political prisoner ;-)14:25
fwereade_rogpeppe, any chance we could use an etherpad for now?14:25
rogpeppefwereade_: just made it available to all14:26
rogpeppefwereade_: etherpad?14:26
fwereade_rogpeppe, http://pad.ubuntu.com/14:27
fwereade_rogpeppe, but anyway, I'm in14:27
fwereade_rogpeppe, and I want to edit where you're sitting :p14:28
fwereade_rogpeppe, that's what I'd like to see in the topology14:33
rogpeppefwereade_: can we see what there is *now*.14:33
fwereade_rogpeppe, done14:33
rogpeppefwereade_: as i'd like to understand where we are before moving from that...14:33
fwereade_rogpeppe, can I delete everything to do with units and machines?14:34
fwereade_rogpeppe, services and relations are the only bits relevant right now I think14:34
rogpeppefwereade_: i'd like to keep the whole picture, for the moment14:34
rogpeppefwereade_: Aram will find it useful apart from anything14:35
fwereade_rogpeppe, ok, but I think everything outside the topology is a red herring14:35
fwereade_rogpeppe, for the purposes of the is-fwereade-on-crack-re-relation-names discussion14:36
niemeyerfwereade_: I've been following the conversation, but to be honest I still miss the root14:36
TheMuefwereade_: Nice project name.14:36
niemeyerfwereade_: Where's the etherpad?14:36
rogpeppefwereade_: i'm sure so. but for the moment, i think this is a useful diversion.14:36
fwereade_niemeyer, it's at https://docs.google.com/document/d/1z2bIJ097qawOPGtZnHABIqNPVXaQ5ePCRIQVYGfcHsg/edit14:37
rogpeppefwereade_: i've wanted to see something like this for a while, just to sort it all out in my head14:37
fwereade_niemeyer, no etherpad, we'd already started on docs14:37
niemeyerCool, looking14:37
niemeyerIs there audio or something?14:37
niemeyerWhat are we doing?14:37
niemeyerBesides hacking a topology? :)14:37
niemeyerIn other words, is there a problem statement somewhere?14:38
fwereade_niemeyer, all I'm trying to do is convince people that we're storing relation names in the wrong bits of the topology14:38
fwereade_niemeyer, rogpeppe is I think usefully diverted14:38
fwereade_niemeyer, but not in the direction I want him to be ;p14:38
fwereade_niemeyer, I would state the problem as follows:14:39
niemeyerfwereade_: Why? Oh, nevermind, go on please..14:39
rogpeppefwereade_: it's ok, i'm looking back at the relations now :-)14:39
fwereade_niemeyer, the topoRelationService has "Role" and "RelationName" fields14:39
niemeyerfwereade_: Ok14:39
niemeyerfwereade_: and is keyed by the service key on the topology14:40
fwereade_niemeyer, a topoRelation has "Scope", "Interface" and "Services"; Services contains a serviceKey:topoRelationService map14:40
niemeyerfwereade_: Okay, seems to make sense to me14:40
fwereade_niemeyer, the RelationName fields in topoRelationService do not refer to the service by which they are keyed14:40
niemeyerfwereade_: What?14:41
fwereade_niemeyer, I consider this to be misleading at best14:41
niemeyerfwereade_: This is a bug for sure14:41
fwereade_niemeyer, they refer to the14:41
fwereade_niemeyer, it's a subtle one though14:41
niemeyerfwereade_: It seems rather blatant to me14:41
fwereade_niemeyer, mainly because "relation" means different things depending on whether we're talking about charms alone, or... actual, er, relations... connections-between-services14:42
niemeyerfwereade_: If you asked me I'd say that's not the case in the current implementation..14:42
fwereade_niemeyer, from the perspective of a user, we do have the same word meaning two things14:42
niemeyerfwereade_: I see them as the same in both contexts14:42
niemeyerfwereade_: But even then, I don't see how that's related to what we're discussing14:43
fwereade_niemeyer, they are profoundly related14:43
fwereade_niemeyer, it's the cause of the problem IMO14:43
niemeyerfwereade_: I'll actually see the code right now because I still can't believe the RelationName isn't for the service14:43
fwereade_niemeyer, consider a RelationEndpoint14:43
niemeyerfwereade_: Okay, with you14:43
fwereade_niemeyer, that has a RelationName which matches the relation defined in the charm14:43
niemeyerfwereade_: Yes14:44
fwereade_niemeyer, however from the perspective of a hook running in a relation, that is effectively the name of the other side of the relation14:44
niemeyerfwereade_: Erm, no?14:45
fwereade_niemeyer, I run db-relation-joined because I think that someone has joined my db relation14:45
niemeyerfwereade_: The local relation name is always the local relation name.. the charm doesn't care about what's the remote relation name14:45
fwereade_niemeyer, I am seieng14:45
niemeyerfwereade_: Yes, *your* db relation.. local relation name14:45
niemeyerfwereade_: Your db relation has a different high-level identification for the remote charm14:46
niemeyerfwereade_: and they both don't fight about that14:46
fwereade_niemeyer: ok, I am mysql, and I provide "db"; you are wordpress and you require "data" (interfaces, scopes match)14:48
niemeyerfwereade_: Cool14:48
niemeyerfwereade_: (by the way, I just checked the code, and seems to match my understanding)14:48
fwereade_niemeyer, we currently store {mysql-key: {role: provides, name:db}, wp-key: {role: requires, name:data}}14:49
fwereade_niemeyer, this representation fits nicely with the charms14:49
niemeyerfwereade_: Yes, that sounds correct14:50
niemeyerfwereade_: in all senses of that14:50
fwereade_niemeyer, but from my perspective as "mysql" I consider myself to be related to a thing called "db"14:50
niemeyerfwereade_: Aha!14:50
niemeyerfwereade_: That's where the misunderstanding lies14:51
fwereade_niemeyer, and I don;t consider that t be *my* name at all14:51
niemeyerfwereade_: But it is..14:51
niemeyerfwereade_: You're not related to a thing called "db", and you have that feeling because that relation name is a poor name14:51
niemeyerfwereade_: Imagine you are wordpress, and for whatever reason you support two relations with interface "mysql": "cache", and "data"14:52
fwereade_niemeyer, ok14:52
niemeyerfwereade_: This is the *wordpress* name for the relations..14:52
niemeyerfwereade_: Who is "my cache"?14:52
fwereade_yes, and in the context of a relation that's the important thing... isn;t it?14:52
niemeyerfwereade_: Well, everything is important14:53
* TheMue listens carefully14:53
fwereade_niemeyer, your "cache" is a conduit to a service somewhere running mysql14:53
fwereade_niemeyer, or not?14:54
niemeyerfwereade_: Yes, but it's the name you gave to it.. it's your way of calling it14:54
fwereade_niemeyer, in the context of a relation, what name is important other than the name used by the other people in a relation?14:54
niemeyerfwereade_: It's a local identifier for the *relation*14:54
niemeyerfwereade_: Sorry, I missed your intention with that sentence14:55
fwereade_niemeyer, if I'm in a relation and looking at the other side of it -- rel.Services[key-of-other-service] -- what name do I want to see?14:55
fwereade_niemeyer, the name it think I have, or the name I think it has?14:55
niemeyerfwereade_: This is bogus14:56
niemeyerfwereade_: The relation that you have at hand is *a relation*, it's not on either side14:56
fwereade_niemeyer, wait, if I'm participating in a relation, there's no "other side"?14:56
niemeyerfwereade_: If I say relation.Service[serviceKey].RelationName, I want to see the "relation name" of the charm of serviceKey that is participating in this relation14:57
niemeyerfwereade_: The *relation that you have at hand*.. that value that you mentioned as "rel"14:57
niemeyerfwereade_: This has no side.. it's the storage for the relation data that all the sides will see14:57
rogpeppeniemeyer: +1. that's a good way of putting it.14:59
fwereade_niemeyer, if I am a unit of service-X and and I am looking at a relation between service-X and service-Y, then surely service-Y is the other side..?14:59
fwereade_niemeyer, and vice versa?14:59
niemeyerfwereade_: Yes, but do you understand what I'm trying to point out?  When you have a "rel", that "rel" has no side, because every single side in that relation will get the same data15:00
niemeyerfwereade_: This is not "the relation for my side of the service"15:01
niemeyerfwereade_: This is "the relation"15:01
fwereade_niemeyer, I *think* I understand that just fine15:01
TheMuefwereade_: It's seems like you're looking for a convenient way to navigate. "Hey, relation, I'm X, so who is my Y."15:01
niemeyerfwereade_: relation[serviceKey].RelationName has the relation name from serviceKey that is participating15:01
niemeyerfwereade_: and that seems correct to me15:01
fwereade_niemeyer, I will concede that that is also a valid way of looking at it ;)15:02
niemeyerfwereade_: It's not just a valid way.. it's the only way to look at what we have in place15:03
niemeyerfwereade_: You might want to represent it in a different way, and that's certainly possible, but I don't see a reason to change it15:03
niemeyerfwereade_: Maybe you do?15:03
hazmatsmaddock, invite out15:03
fwereade_niemeyer, I *think* I do, let me just take a moment to reorder my thoughts15:04
niemeyerfwereade_: Sounds good15:04
niemeyerfwereade_: As a curiosity, note that we say "juju add-relation service1:rel1 service2:rel2".. that's consistent with how we store it as well.15:10
fwereade_niemeyer, ok, when I want to get the relations participated in by  a specific service -- the "local" service, for the purposes of discussion -- I get a list of topoRelations out of the topology and I want to turn them into a bunch of instances that encapsulate what the local service needs to know about the various remote services15:12
niemeyerfwereade_: The local service needs to know pretty much nothing about the remote relation names being used, I think15:13
fwereade_niemeyer, from that perspective, it seems strange that I should get the name of the relation from my own service key, and the role it plays from its service key... but wait, dammit, I can get the name from my own key and trivially derive the role played by inverting my own role15:14
fwereade_niemeyer, I'd been thinking about getting the role of the opposite service from the opposite service key15:14
fwereade_niemeyer, and having to get the name from my own key, and that seemed insane15:14
niemeyerfwereade_: Yeah, I think doing provider => requirer sounds fine :)15:15
fwereade_niemeyer, right, I think we can safely forget I said anything :)15:15
fwereade_niemeyer, sorry derail15:15
niemeyerfwereade_: No worries, I actually find that kind of conversation useful to solidify the concepts we have in place15:16
rogpeppeme too15:16
rogpeppeand we've got this doc now as a kind of reference point: https://docs.google.com/a/canonical.com/document/d/1z2bIJ097qawOPGtZnHABIqNPVXaQ5ePCRIQVYGfcHsg/edit15:16
fwereade_niemeyer, yeah, the time wasn't wasted, just wish I'd seen the other perspective some hours ago15:16
rogpeppewhich has been helpful for me anyway15:16
* TheMue appreciates it too, getting a better understanding.15:16
fwereade_rogpeppe, slight update to https://codereview.appspot.com/6310046, tRS.RelationName became tRS.Name15:25
rogpeppefwereade_: sounds good15:25
rogpeppefd15:25
fwereade_everyone, I'm going for a quick walk to see whether thinking this through dislodges any more misconceptions, bbiab15:25
rogpeppefwereade_: at some point we should add some comments to the fields in the structs15:25
fwereade_rogpeppe, yeah, I think I will be doing that for my next trick :)15:26
* rogpeppe has just realised the google docs is absolutely terrible for editing a document where indentation matters15:33
rogpeppes/the/that/15:33
TheMuerogpeppe: You need a shared online vim.15:34
rogpeppeTheMue: noooo!15:34
rogpeppeTheMue: just normal text will do fine. i don't really want to go back to vi key commands...15:35
rogpeppeTheMue: or monospaced fonts15:35
TheMuerogpeppe: Hehe, even if my favorite editor is a different one I still like the good old vim.15:37
TheMuerogpeppe: It's always fine for admin tasks.15:38
rogpeppeTheMue: ed FTW!15:38
TheMuerogpeppe: For Go (and other tasks) I like my Sublime Text. highlighting, code completion, templates, fmt on save, good build support and as an editor many nice features.15:39
TheMuerogpeppe: But editors are good for endless discussions. *lol*15:40
rogpeppeTheMue: i had a challenge from hazmat to try sublime text for a month... if he tries acme for a month!15:40
TheMuerogpeppe: hazmat is using st too? Didn't know that.15:42
rogpeppeTheMue: no, i think he's an emacs user15:42
rogpeppeTheMue: but there's no way i'm using emacs :-)15:42
TheMuerogpeppe: Uhh, tried it for some time, but never get warm with it.15:42
hazmatTheMue, actually i'm on emacs user15:44
hazmatTheMue, i'd like to use ST  more15:44
TheMuehazmat: Just give it a try. ;)15:45
hazmatTheMue, i have.. its nice.. the go integration looks sweet15:45
TheMuehazmat: Especially when installing GoSublime.15:45
hazmatTheMue, indeed.. my use of ST is hindered by my workflow which has evolved into a terminal session with many open editors split across different tmux windows, all on different branches15:46
hazmati guess that translates into multiple ST editor windows15:46
TheMuehazmat: Yip.15:47
niemeyerLunch time15:59
rogpeppefwereade_, niemeyer, TheMue, Aram: gotta go soon. have a great weekend all.17:05
fwereade_rogpeppe, and you, happy weekend17:05
rogpeppefwereade_: just started world war Z, BTW. will let you know how i get on.17:06
fwereade_rogpeppe, cool; I've got the others of yours with me this w/e so hopefully I'll manage another :)17:07
rogpeppefwereade_: can't remember what i left you with now...17:07
rogpeppefwereade_: oh yeah, valentine's castle.17:07
fwereade_rogpeppe, er, nor can I now (I already read that one, must get sequels...)17:07
fwereade_rogpeppe, axiomatic17:08
fwereade_rogpeppe, to hold infinity17:08
rogpeppefwereade_: oh yeah, awesome shorts17:08
rogpeppefwereade_: i think you'll enjoy both17:08
fwereade_rogpeppe, you haven't led me wrong yet :)17:08
TheMuerogpeppe: Bye, have a nice weekend.17:24
niemeyerrogpeppe: Have a good time there man17:25
* TheMue leaves now too.17:26
niemeyerTheMue: Have a good time too17:27
TheMueniemeyer: Thx, for you, and all here, a nice weekend too.17:27
fwereade_niemeyer, re: redundant-relation-prefixes -- my thinking is that Role and Scope invariably refer to aspects of a relation; but Name and Key may need disambiguation, and where they do have been left alone17:31
fwereade_niemeyer, and I'm slightly concerned that we're drifting down the python path of VeryLongRedundantNomenclatureNamesThatEndUpObscuringMeaning17:32
fwereade_niemeyer, invalid?17:33
niemeyerfwereade_: I'm not sure this is the case on that specific instance17:37
niemeyerfwereade_: I find more awkward to have relationName string; scope RelationScope17:37
niemeyerfwereade_: RelationRole is VeryFarFromSuchALongAndUNpleasantNameInMyOpinion :-)17:38
niemeyerfwereade_: I'd be happy to take *all* prefixes off, but we can't, because RelationName is ambiguous with ServiceName in certain contexts17:39
fwereade_niemeyer, fair enough, I'd really prefer prefixes only for disambiguation, but it's hardly worth arguing over :)17:40
niemeyerfwereade_: I find consistency a relevant factor too17:40
niemeyerfwereade_: this hurts my eyes somehow: { relationKey string; scope RelationScope }17:41
fwereade_niemeyer, "prefixes only for disambiguation" is imo perfectly consistent, but as I say it's no big deal :)17:41
fwereade_niemeyer, I do have another thought I should probably run by you before I propose it17:42
niemeyerfwereade_: This is not consistent.. this is a statement17:42
niemeyerfwereade_: The code is consistent or not, and in the example above it isn't17:42
niemeyerfwereade_: type is { relationKey string; relationName; scope RelationScope; role RelationRole}17:43
niemeyerfwereade_: now I have a rel17:43
fwereade_niemeyer, as I say, I'm happy to drop it :)17:44
niemeyerfwereade_: DO I type rel.role or rel.relationRole?17:44
niemeyerfwereade_: Do I type rel.key or rel.relationKey?17:44
niemeyerfwereade_: That's what I mean by inconsistency.17:44
fwereade_niemeyer, I have no idea, and your position doesn't make it any easier to tell17:44
niemeyerfwereade_: I understand, I'm trying to provide reasoning so it doesn't feel like arbitrating a personal opinion17:44
fwereade_niemeyer, or should I go and change Unit.key to Unit.unitKey throughout?17:45
niemeyerfwereade_: It does.. it's always rel.relation*17:45
niemeyerfwereade_: This type, specifically, is named ServiceRelation, not Relation17:45
niemeyerfwereade_: If you introduce UnitRelation, then we can have the same convention17:45
fwereade_niemeyer, heh, I want to call it RelatedService actually17:45
niemeyerfwereade_: Okay, I'll just shut up now. :)17:46
fwereade_niemeyer, I'm entirely happy following your own preferred conventions, you don't actually have to convince me they're right every time... you favouring them is a pretty solid heuristic, and if I still don't like them in a few months we can worry about it then ;)17:48
fwereade_niemeyer, but if you have a moment... aside from wanting to rename ServiceRelation, which IMO doesn't say enough about what it is or why it exists17:49
niemeyerfwereade_: Sounds good.. I will still try to explain why in my opinion it isn't simply arbitrary favoring, though17:49
fwereade_niemeyer, that's fine -- but I think we have quite different perspectives on some things, and I can't always be convinced ;)17:50
niemeyerfwereade_: in a single type having prefix or not forces people to look it over, and this is obviously bad in my favoritism mechanism17:50
niemeyerfwereade_: I won't try to convince you every time, promise :17:51
niemeyer:017:51
niemeyer:)17:51
niemeyerfwereade_: I'll still explain, though17:51
fwereade_niemeyer, don't worry, I don't think you're just being arbitrary :)17:51
fwereade_niemeyer, it's worth it often enough that I'm certainly not going to complain17:51
niemeyersingle type with { relationKey, relationName, relationScope, relationRole } == Good17:52
niemeyersingle type with { relationKey, relationName, scope, role } == Bad17:52
fwereade_niemeyer, the message I failed to convey above was "yeah, I can see that's a sane perspective, I'm happy to go with it"17:52
niemeyerfwereade_: Sounds good, we're in sync17:52
niemeyerfwereade_: Thanks for being flexible as well, by the way17:52
fwereade_niemeyer, anyway, I'd quite like to introduce a RelationScope type that actually represents a specific scope17:52
niemeyerfwereade_: That counts highly17:53
fwereade_niemeyer, a pleasure :)17:53
fwereade_niemeyer, but this introduces naming issues17:53
fwereade_niemeyer, renaming RelationScope will be annoying -- something like ScopeKind could work, but then for consistency's sake I'd want to have RoleKind as well17:53
niemeyerfwereade_: Hmm, can you explain further what you mean by "actually representing a specific scope" in that sense?17:54
fwereade_niemeyer, the group of units within a relation that can actually affect one another17:54
fwereade_niemeyer, either all of them, or the set of them that are all in the same container, depending on scope17:54
fwereade_niemeyer, this concept is sprinkled through the python code and I think deserves to be promoted17:55
fwereade_niemeyer, even if the type itself is just a ZK conn and a path17:55
fwereade_niemeyer, so, on the basis that I don;t really want to rename the Relation* types, how would you feel about UnitScope for that?17:57
niemeyerfwereade_: Ah, interesting17:57
niemeyerfwereade_: Can you talk me through the use case(s?) we have for that, just so I can picture it?17:57
fwereade_niemeyer, most things to do with unit relations touch it in some way17:58
fwereade_niemeyer, the settings paths and presence paths, which are both read and written by different unit agents, are consistent relative to the unitscope base path17:59
niemeyerfwereade_: Right17:59
niemeyerfwereade_: But how do we actually need to handle these details, code wise?17:59
fwereade_niemeyer, and being able to pass it around saves us quite a lot of basePath + "/" + string(r.RelationRole) + "/" + u.key18:00
fwereade_niemeyer, for example, with that we can pass it into a RelatedUnitsWatcher, and it becomes positively trivial for that to start a unitRelationWatcher by passing in the settings path and presence path directly18:01
fwereade_niemeyer, with scope.presencePath(role, unit) and scope.settingsPath(unit)18:01
fwereade_niemeyer, the lazy parent node creation can be tidied away in one place18:01
fwereade_niemeyer, the *same* UnitScope we pass into the watcher can also be used to determine the paths the unit agent wants to write to18:02
niemeyerfwereade_: Is this a RelationScope, rather than UnitScope?18:02
fwereade_niemeyer, it's probably only half a dozen cases in total, but it lets us implement almost everything else without worrying about the concept of scope18:03
fwereade_niemeyer, I don;t think so, because it only becomes meaningful in the context of a specific unit18:03
niemeyerfwereade_: Yeah, I can see how it maps well to the issues we might have18:03
fwereade_niemeyer, in a global relation, ok, every unit on either side has the same scope18:03
fwereade_niemeyer, in a container relation it's a specific path that depends on the unit18:03
fwereade_niemeyer, I'm afraid I am being called to supper :)18:04
niemeyerfwereade_: Right, but I'm wondering if we don't simplify code and future use cases by having a representation which is unit-agnostic, if you see what I mean18:04
fwereade_niemeyer, hmm, the way I see it we construct it with a unit and never think of it again18:04
fwereade_niemeyer, it's just the scope and it does what it should18:04
niemeyerfwereade_: That's because I suspect you have a bit of a biased view18:04
niemeyerfwereade_: Having to implement that specific use case right now18:05
niemeyerfwereade_: But think of a monitor, for example18:05
niemeyerfwereade_: Or a debugger18:05
niemeyerfwereade_: You're not sitting on a single unit anymore, and still, the concept of a Scope still exists18:05
fwereade_niemeyer, it's still a <thing> which binds together N units which (transitively) can affect one another18:05
niemeyerfwereade_: Exactly, and that <thing> is a relation scope18:06
niemeyerfwereade_: With N units18:06
fwereade_niemeyer, that was the name I originally wanted to give it18:06
niemeyerfwereade_: As I understand it, your thinking was to have a relation scope which represents N-1 units18:06
fwereade_niemeyer, no: all units that can transitively affect one another18:06
fwereade_niemeyer, a unit is absolutely part of its own scope18:07
rogpeppeniemeyer, fwereade_: new container package for review: https://codereview.appspot.com/630408518:07
niemeyerfwereade_: Oh, ok18:07
rogpeppeunfortunately i can't seem to get it off WIP18:07
niemeyerfwereade_: Well, sounds like we're aligned then, and just need to bikeshed on names :)18:07
niemeyerfwereade_: Supper is calling you :)18:07
rogpeppeniemeyer: i have this issue: http://paste.ubuntu.com/1042741/18:07
fwereade_niemeyer, cool , cheers -- happy weekend if I decide to be all social tongiht :)18:08
niemeyerfwereade_: Thanks, you too :)18:09
niemeyerrogpeppe: Hmm18:09
niemeyerrogpeppe: Is bzr info and all working successfully on /home/rog/src/go/src/launchpad.net/juju-core/juju/.bzr/cobzr/container-package18:11
niemeyer?18:11
rogpeppeniemeyer: yeah18:26
rogpeppeniemeyer: i did accidentally run bzr commit as root once; i suppose that might have done something bad18:26
niemeyerrogpeppe: Hmm, quite possibly18:26
rogpeppeniemeyer: but i did a chown -R rog.rog afterwards to try to clean things up18:26
niemeyerrogpeppe: You could try fiddling, but I suggest rebranching18:26
niemeyerrogpeppe: bzr branch container-package temp-branch18:27
niemeyerrogpeppe: bzr branch -d container-package18:27
niemeyerrogpeppe: bzr branch -m temp-branch container-package18:27
rogpeppebranch -m, yeah18:27
rogpeppeniemeyer: still failed: http://paste.ubuntu.com/1042771/18:30
niemeyerrogpeppe: Crap18:30
niemeyerrogpeppe: See if you have something on ~/.bzr.log18:30
niemeyerrogpeppe: "resource not found" is an error coming out of lpad, IIRC18:31
niemeyerYeah, it is18:31
niemeyerlpad is looking for something in Launchpad that does not exist18:31
niemeyerrogpeppe: Can you please try running with -debug?18:32
niemeyerrogpeppe: Also, can you please paste the result of "bzr info" within ~/.bzr/cobzr/container-package18:34
niemeyerandrewsmedina: ping18:38
rogpeppeniemeyer: last part of $HOME/.bzr.log: http://paste.ubuntu.com/1042796/18:44
niemeyerrogpeppe: Ok, that's not the issue18:44
niemeyerrogpeppe: bzr info?18:44
rogpeppeniemeyer: http://paste.ubuntu.com/1042801/18:45
niemeyerrogpeppe: That's probably the issue: /home/rog/src/go/src/launchpad.net/juju-core/juju/.bzr/cobzr/temp18:45
niemeyerrogpeppe: I wonder what it was before18:45
niemeyerBut I'm not sure, to be hoenst18:46
niemeyerrogpeppe: The output with -debug?18:46
rogpeppeniemeyer: http://paste.ubuntu.com/18:47
rogpeppeoops18:47
rogpeppeniemeyer: http://paste.ubuntu.com/1042810/18:47
niemeyerHah18:47
niemeyerOkay, that's clearly wrong18:48
niemeyerLet's see where it's getting the information from18:48
rogpeppeit doesn't seem to be remembering the push branch18:48
niemeyerrogpeppe: bzr info within juju-core/juju?18:48
rogpeppeniemeyer: at the start of that paste18:49
niemeyerVery awkward.. why is it not resolving the path18:50
niemeyerrogpeppe: Do you have changes in your local lbox?18:51
rogpeppeniemeyer: nope18:51
niemeyerrogpeppe: When I execute locally, it doesn't look up information for branches starting with "." in Launchpad18:57
niemeyerrogpeppe: The code seems to back that up18:58
niemeyerrogpeppe: I'm a bit puzzled about how it's doing that there18:58
niemeyerAh, I think I see18:59
niemeyerHmmm.. or maybe not18:59
niemeyerrogpeppe: Here is the output of mine: http://paste.ubuntu.com/1042850/19:13
niemeyerrogpeppe: Reproducing the same scenario19:14
niemeyerwith push --remember et al19:14
niemeyerrogpeppe: I'm out of ideas really.. the only option is diving in and seeing why it's attempting to load ".bzr/..." from Launchpad19:14
niemeyerrogpeppe: It shouldn't ever do that19:14
rogpeppeniemeyer: oh now, this is weird. i committed a new change, then did bzr push --remember ...; and it said "No new revisions or tags to push"19:20
niemeyerrogpeppe: Huh.. things aren't quite alright there19:22
niemeyerrogpeppe: I'm not entirely sure of what that push --remember does with a bound branch19:23
niemeyerrogpeppe: Theoretically whenever you commit, it's already being pushed onto the bound branch19:24
rogpeppeniemeyer: i think i stuffed up bzr when i ran it as root :-(19:30
niemeyerrogpeppe: It'd be nice to see why lbox is misbehaving, though19:56
niemeyerrogpeppe: It's being mislead in a way it shouldn't19:56
niemeyerrogpeppe: If we find out, we can make it have a saner behavior in the future19:57

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