[01:36] wallyworld_: ah, removed that [01:37] wallyworld_: any reference there now is by mistake [01:37] ah ok :-) [01:37] i'll let you fix that and take another look after i finish this bit of work i'm doing [01:39] kk [01:57] I'm beginning to realise that my mental model of the state stuff is just plain wrong [02:03] at least you had a mental model [02:04] ooooooooooooh, juju totally doens't work with the mongodb we ship with raring [02:04] that is a slight problem [04:13] davecheney: plz fix, kthxbye [04:13] :) [05:40] dimitern: hey there [05:41] dimitern: for the tasks you are doing or done, put your launchpad id in square brackets at the start [05:41] thumper: heyhey [05:41] thumper: in the blueprint? [05:41] dimitern: yeah, the work items [05:41] thumper: ok, will do [05:42] so like this: [thumper] doing foo: INPROGRESS [05:42] dimitern: I'm just touching up the last part of plugins, using text/template etc [05:42] thumper: ah, cool! [05:43] thumper: my point (not that i explained it properly i think) with time.duration vs. floats is you can convert one to the other when generating the script [05:44] thumper: and still have a nice to read code rather than floats [05:44] hmm... yeah, perhaps for a public thing, but really worth it for a test? [05:44] also, with some refactoring on the templates, things are more obvious [05:44] well, tests are people too :) [05:46] i mean we need to read and maintain them as well as other code, and readability helps (with that i'll leave it to your discretion, i don't absolutely insist on it) [05:50] thumper: wrt to api authorization, who do you think should be allowed to call machine.Series(), m.Constraints() and m.Status() - everyone, only admins or only the environment manager node? [05:52] thumper: the cli will need to use all of these in different commands, so maybe restrict them to whoever can use the cli and stop there? [05:52] dimitern: sorry, not thought too much about api auth, so not much help here === tasdomas_afk is now known as tasdomas [05:54] thumper: np. how's it going in containerland? [05:54] dimitern: emailed people earlier [05:55] thumper: ah, missed that, thanks [05:55] thumper: have you seen my mail about the copyrights headers? [06:01] thumper: reading the containers page you wrote, and i remember a discussion we had with william on the way back from oakland about nesting: [06:03] thumper: the idea basically was to expand machine-id to contain a "path" like /:/:/... where all ids are still numbers, and the type is the container type used (lxc, kvm, etc.) e.g. "0/lxc:1/kvm:2" [06:05] thumper: this has some advantages: (1) scoping/namespacing, (2) ability to "move" up the "tree" when needed (e.g. set an ip address request going down from root to most deeply nested level, then back up (setting up networking on each level, etc). [06:06] yeah, I remember the discussion, but we also talked about having the machine namespace flat [06:08] thumper: not sure it's the same discussion (i wasn't there on the one you mention, we talked about this later), but william seemed to like the idea; anyways just mentioning lest i forget [06:10] * dimitern bbiab [06:18] * thumper is away now [06:19] dimitern: if I have time.Duration in the struct instead of a float, how do I get the Seconds in the template? [06:19] with a float {{.Seconds}} works [06:19] sorry, with a float {{.Sleep}} works [06:19] but I need Sleep.Seconds() [06:19] can't see how to do that in the template [06:19] * thumper now away to eat [07:19] thumper: well, i suppose something like this should work: http://play.golang.org/p/5g5fsv-3zn [07:21] thumper: btw sleep(1) also supports arguments like "1m 23s" [07:26] dimitern: that isn't inside the template {{ ... }} bits [07:26] thumper: look at {{printf}} [07:26] *: morning [07:27] dimitern: nm {{.Sleep.Seconds}} works [07:29] TheMue: hiya [07:33] wallyworld_: consistency isn't everything you know :) [07:33] dimitern: last proposal updated, I'm signing off for the night now [07:33] ciao everyone [08:09] mornin' all [08:27] rogpeppe1: morning [08:29] rogpeppe1: morning [08:32] rogpeppe1: i have a question already [08:32] :) [08:32] dimitern: ok [08:34] rogpeppe1: so in order to implement state.AllMachines() -> []*state.Machine, error [08:34] rogpeppe1: what should I put in AllMachinesResults.Machines? []params.Machine or params.MachineInfo? the client expects to have actual machine objects there [08:35] dimitern: []params.Machine [08:35] dimitern: as long as we're keeping Machine separate from MachineInfo [08:35] rogpeppe1: ok [08:35] dimitern: or []*params.Machine if it's more convenient [08:35] rogpeppe1: and then the user can do like machines[0].Id() right? [08:36] dimitern: api.State.AllMachines should look just as it does in state [08:37] dimitern: so you'll need to map the slice, making a *api.Machine for every params.Machine [08:37] rogpeppe1: wait.. actually params.Machine is not right - I need apiclient.Machine [08:37] rogpeppe1: oh yeah [08:37] rogpeppe1: thanks [08:37] dimitern: np [08:38] rogpeppe1: already implemented LifecycleWatcher and EnvironConfigWatcher - no trouble so far [08:38] dimitern: cool [08:40] rogpeppe1: hmm.. params does not import api though - will there be a problem if I import it? [08:40] dimitern: yes [08:41] dimitern: why do you want to import api into params? [08:41] rogpeppe1: to define the slice of machines [08:41] rogpeppe1: in AllMachinesResults [08:41] dimitern: that must be []params.Machine, no? [08:42] rogpeppe1: ah, it'll be api.Machine at client side, i see [08:42] dimitern: yup [08:46] rogpeppe1: do you think it's worth having if len(machines) == 0 { return params.AllMachinesResults{}, nil } (or maybe Machines: make([]*params.Machine, 0) is better) ? [08:47] dimitern: i don't mind. whatever is easiest. [08:47] rogpeppe1: wasn't sure how to convey best the case "empty slice" [08:48] rogpeppe1: but it's up to the client I guess anyway [08:48] dimitern: i think it may be better to always return an empty slice. that way the json representation is [] not nil. [08:49] rogpeppe1: yeah, that what i was thinking [08:49] * rogpeppe1 wishes a nil slice encoded as json [] anyway [08:53] rogpeppe1: strictly speaking a nil slice should be either null or undefined in json [08:54] dimitern: i'm not sure. the difference between a nil slice and an empty slice in Go is a subtle one that really isn't that useful to leak out into json. [08:55] dimitern: i can't see a particular use case for allowing a slice to encode as null [08:55] rogpeppe1: yeah actually json doesn't have such a distinction [08:56] dimitern: well anything can be null in json [08:58] rogpeppe1: i'm thinking it's worth having some helper to convert from state.Machine to params.Machine, so we have it at once place, right? [08:58] dimitern: definitely [09:05] rogpeppe1: so can we assume all places using state.IsNotFound(err) will be changed to use api.ErrCode(err) == api.CodeNotFound? [09:05] rogpeppe1: or we need a helper for each such case [10:06] rogpeppe1: ping [10:06] dimitern: pong [10:06] rogpeppe1: ^^ [10:06] dimitern: ah, sorry, i didn't see that [10:06] dimitern: yes, we should assume that [10:07] rogpeppe1: cool [10:07] dimitern: although we could add a help too if we wanted [10:07] helper [10:07] rogpeppe1: let's see how it'll work when we start changing the agents [10:07] dimitern: +1 [10:08] rogpeppe1: i'm having difficulty with state.AllMachines at the client side - what should I put in the objType arg of call() ? [10:09] dimitern: i think we probably need a srvState type [10:10] rogpeppe1: ok, will add it then [10:10] dimitern: and srvRoot.State(id string) (*srvState, error) [10:10] dimitern: then you'll use State as the obj type [10:10] rogpeppe1: yeah, like the other objects [10:10] dimitern: yup [10:11] rogpeppe1: but what about st.id ? [10:11] rogpeppe1: i can add it but how shoud i initialize it? [10:11] dimitern: st.id ? [10:12] rogpeppe1: st.call("State", st.id ... [10:12] dimitern: ah, i think we should enforce it as blank [10:13] rogpeppe1: in srvRoot State(id string) ? [10:13] dimitern: at some point in the future, we'll potentially be able to connect to several states through the API, and then the id will be useful [10:13] dimitern: yes [10:13] rogpeppe1: ok [10:13] dimitern: same as with Client [10:18] whoops, forgot about OCR :) === ChanServ changed the topic of #juju-dev to: https://juju.ubuntu.com | On-call reviewer: danilos | Bugs: 8 Critical, 68 High - https://bugs.launchpad.net/juju-core/ [10:19] danilos: hiya [10:19] rogpeppe1, heya [10:19] danilos: yo [10:23] rogpeppe1: actually AllMachinesResults now will have Machines []string instead (ids) and client-side I'll range over it and call st.Machine(id) for each, right? [10:23] dimitern: i don't think you should do that [10:24] dimitern: i think you should return all the info [10:24] rogpeppe1: I only need the id to wrap it with a api.Machine [10:24] rogpeppe1: but that I don't have in params.Machine [10:24] dimitern: i don't think you want an extra n round trips [10:25] dimitern: ah, well params.Machine should have it [10:25] rogpeppe1: all details? [10:25] rogpeppe1: or only the ones I need right now [10:25] dimitern: just what you need right now [10:27] rogpeppe1: ok, this also means changing srvMachine.Get() to return the Id (now both this and the range loop in AllMachines use the same helper: stateMachineToParams(stm *state.Machine) *params.Machine) [10:27] dimitern: that seems fine. it should only affect stateMachineToParams, right? [10:27] rogpeppe1: yeah [10:28] rogpeppe1: and I'll have the reverse helper in apiclient: paramsMachineToAPI(?) [10:29] dimitern: sounds reasonable. [10:29] rogpeppe1: except I can't do it that [10:29] dimitern: no? [10:30] rogpeppe1: ah, no sorry api.Machine has doc which is params.Machine [10:30] dimitern: yu [10:30] p [10:37] rogpeppe1: who should be able to call m.Constraints() and m.Status() wrt permission checks? everyone (deny: "user-admin", "user-other") ? [10:39] dimitern: i think allow: "machine-0", "machine-1" [10:39] rogpeppe1: how about juju status? [10:39] dimitern: that wil be part of the client API [10:40] rogpeppe1: really? that simplifies things then ok [10:41] dimitern: yeah, we already have an isAgent check in srvRoot.Machine, i think [10:41] rogpeppe1: strictly speaking only the environ manager uses these two now [10:41] rogpeppe1: so allow "machine-0" to be as restrictive as possible [10:41] dimitern: i think it's reasonable that a machine can get its own info [10:42] rogpeppe1: it *sounds* reasonable but we never cared about this in the machiner [10:43] dimitern: i'm ok if you want to deny access to everything but the environ manager [10:43] rogpeppe1: let's do that for now, we can expand it later when we get to the MA itself and the other tasks [11:01] wallyworld_: is there anything particularly in your chain of branches that I can unblock. I've reviewed a bunch of stuff, but I don't have the knowledge of the thread that you do. [11:03] jam: thanks for asking. just one more :-) https://codereview.appspot.com/9606046/ [11:03] thanks very much. you and dimitern have been very awesome in doing all the reviews [11:03] wallyworld_: yeah, I was looking at that one now [11:03] though it seems not in-the-critical-path to getting the others landed [11:04] it needs to be done so that https://codereview.appspot.com/9603044/ can land [11:30] danilos: poke [11:33] danilos: if you want a review to do https://codereview.appspot.com/9545045/ [11:33] it's an easy one [11:45] wallyworld_, you've got conflicts in there (or at least the conflict markers) [11:46] * wallyworld_ checks [11:59] jam: i got permission denied trying to add you/mark etc as a watcher on my rt #61613 [11:59] <_mup_> Bug #61613: Can't run liferea with main window hidden [12:01] wallyworld_: I get an error as well. [12:02] :-( [12:02] rogpeppe1, TheMue: sorry guys I'll have to skip kanban today - i did move all my cards accordingly [12:02] wallyworld_: try just replying to the ticket, and then including john.meinel@canonical.com in a CC field [12:02] dimitern: np [12:04] wallyworld_: I just sent an email to derykc [12:04] deryck [12:04] i just cc'ed [12:04] wallyworld_: I saw the email [12:04] that was quick [12:04] i only *just* hit send [12:04] wallyworld_: though it just puts me in a one-time message [12:04] vs the default CC [12:05] so we want someone to update it. [12:05] better than nothing i guess === dimitern is now known as dimitern|afk [12:18] dimitern|afk:ok [12:37] mgz, ping === hazmat` is now known as hazmat [12:56] rogpeppe1: btw, I know found on my own what I wanted to ask by digging into the whole coudinit stuff [12:56] TheMue: cool [13:00] mgz: I figured out the bug for tarmac [13:00] jam: btw, the roundtrips to mongo are 70ms? that sounds like a lot: is that on the unix socket or over tcp/ip? [13:01] danilos: that is running from the client sitting in the hotel in Oakland [13:01] stuff like 'juju status' is evaluated client-side ATM [13:01] jam: oh, right, I see [13:01] mgz: It turns out that Tarmac uses launchpad's API to find "bzr_identity" for a given branch. [13:01] jam: if it went through api server it would have gone much quicker, understood [13:02] so if you say [lp:~go-bot/goose/trunk] tarmac connects to lp, but then tries to load the config item for lp:goose [13:02] (the canonical name) [13:02] and since that doesn't have any config, it just says "ok, everything Approved is ready to land" [13:02] danilos: presumably the api server has much lower overhead, yes. [13:02] mgz: which also explains why everything worked in testingb [13:03] because it *wasn't* lp:goose yet [13:04] jam: ack, thanks for explaining it [13:05] danilos, jam, mgz, TheMue: i'd appreciate a review of this: https://codereview.appspot.com/9643043 [13:05] rogpeppe1, taking a look [13:06] rogpeppe1: *click* [13:22] rogpeppe1: done [13:22] TheMue: thanks === BradCrittenden is now known as bac [13:32] TheMue: responded [13:33] rogpeppe1: *clickAgain* [13:39] Heya [13:40] rogpeppe1: We have a meeting in ~50 [13:40] niemeyer: ah, thanks - i hadn't seen an invite [13:41] niemeyer: anything you want to chat about prior to it? === rogpeppe1 is now known as rogpeppe [13:41] rogpeppe1: You seem to be there in the event [13:41] rogpeppe: Hmm.. given it's still a preliminary meeting, we can probably exchange ideas during it [13:42] rogpeppe: Have you read that document + comments? [13:42] niemeyer: not ye [13:42] t [13:43] rogpeppe: replied again [13:43] rogpeppe: That might be good to have a quick look before the call [13:43] niemeyer: i definitely will do === wedgwood_away is now known as wedgwood [13:58] danilos: responded === tasdomas is now known as tasdomas_afk [14:36] rogpeppe, LGTM, worker.Runner/worker.Worker does sound better, but ultimately your call (this might make it easier to extract in the future) [15:32] bac: Eyup lad. Are you using anything like socket.io in juju-gui? === wedgwood is now known as wedgwood_away [15:34] allenap: no [15:35] bac: Just plain websocket, or something in YUI? Btw, "eyup lad" is a greeting in gmblish. [15:36] In case you didn't know whether to feel insulted or not. [15:37] allenap: i always default to insulted until proven otherwise [15:38] allenap: we use the reconnecting-websocket.js package [15:42] bac: Was there a conscious decision to use that over something else, or was it just convenient and close to hand? (Wow it's small; that's neat.) Would you recommend it? [15:43] allenap: i wasn't in on that decision. you may want to quiz hazmat [15:44] allenap, its a very thin layer over websocket.. to you know reconnect ;-) [15:45] allenap, we're basically using a raw websocket, the gui has several abstractions built on that.. the gui itself while yui.. focuses mostly on the backbone app framework style of yui [15:46] allenap, socket.io is basically just particular conventions around websocket, pub/sub .. chatrooms, etc. most of which aren't relevant here. [15:48] hazmat: Have you had any issues with websockets that might have been dealt with by something like socket.io, or does the reconnecting logic cover it? [15:48] allenap, none [15:49] hazmat: Brilliant, thanks, and thank bac too. [15:49] s/thank/thanks [15:50] * hazmat relocates === wedgwood_away is now known as wedgwood === tasdomas_afk is now known as tasdomas [17:28] * rogpeppe is done for the day. see y'all tomorrow. === tasdomas is now known as tasdomas_afk === deryck is now known as deryck[lunch] === deryck[lunch] is now known as deryck [20:18] jam: any way to get some action on #1182224 I think it should be quite easy, at least from the outside looking in? [20:18] <_mup_> Bug #1182224: relation-list returns null with json-output [21:11] good morning juju folks [21:21] Wait, it is actually morning somewhere else! [21:21] sure... [21:21] thumper: oh, that's because you're in the same country as me [21:21] 9:21am in NZ [21:21] kyhwana: where are you? [21:22] The 'tron [21:22] * thumper doesn't know where the 'tron is [21:22] O.o [21:23] Hamiltron? [21:23] oh... [21:23] * thumper is in Dunedin, so not up with all that north island slang [21:24] ahh [22:15] kyhwana: what do you do for work, and what's your interest level with juju? [22:15] * thumper is curious [22:15] thumper: I'm a "systems engineer" for a uh, company that makes "packet acquisition and generation" cards+appliances. [22:16] and interest in juju is mostly personal admin stuff [22:16] * thumper nods [22:17] though, I bet I could use it to deploy build environments. Hmm === ChanServ changed the topic of #juju-dev to: https://juju.ubuntu.com | On-call reviewer: - | Bugs: 8 Critical, 68 High - https://bugs.launchpad.net/juju-core/ [22:34] thumper: re https://launchpad.net/bugs/1182224 seems the problem is in json.Marshal, it should marshall an empty list to [] not nil: http://play.golang.org/p/QIMUVJMVPR [22:34] <_mup_> Bug #1182224: relation-list returns null with json-output [22:34] sidnei: it does [22:34] * sidnei just wrote his first go program :) [22:34] sidnei: it isn't bein given an empty slice [22:35] sidnei: it is a nil [22:35] which relates to null in json [22:35] * thumper is fixing the code [22:35] sure it's a nill not an empty slice? [22:35] * sidnei staring at uniter/context.go [22:36] sidnei: I did [22:36] UnitNames starts with units []string, and returns that at the bottom, i would expect it to be an empty slice or whatever that's called [22:37] sidnei: it starts with an uninitialized slice [22:37] which is nil [22:37] * thumper is adding one line of code [22:37] i see, uninitialized [22:37] units = []string{} [22:37] append can handle a nil to append to [22:38] and interestingly, if you have 'var value []string' [22:38] v := reflect.ValueOf(value) [22:38] v.Len() == 0 [22:38] v.IsNil() -> true [22:39] v.Kind() -> "slice" [22:39] so the HasLen matcher succeeds with 0 on nil [22:39] I've changed the tests to be "DeepEquals, []string{}" [22:39] thumper: so why this results in nil: http://play.golang.org/p/6T6mLG2FY0 [22:40] oh poos [22:40] phew, so im not crazy [22:41] * thumper pokes it with a stick [22:42] * sidnei goes drink a beer [22:47] hmm.. [22:52] sidnei: you are crazy [22:52] sidnei: it just took me some time to work it out [22:53] sidnei: http://play.golang.org/p/xHa0rd-0cn [23:07] has there been any progress with juju-core deploying to armhf recently? [23:11] mwhudson: I believe it is being looked at actively [23:11] mwhudson: particularly as with go 1.1, it fixes some things [23:11] we are pushing to get go 1.1 in the repos, and arm is kinda dependent on that [23:11] ok [23:11] i think that was going to be my next question :) [23:11] we are getting arm deployments into a CI system for us [23:12] is there a ppa with go 1.1 in it yet? [23:12] probably [23:12] look for ~gophers [23:13] ... for armhf [23:13] hmm... I think PPAs still need special tweaking to build for armhf don't they? [23:13] as it isn't a default target (ISTR) [23:13] yeah [23:14] is go mostly written in go? [23:14] i can imagine there are bootstrapping issues looming [23:14] possibly [23:14] I think davecheney has tested arm locally [23:14] and it is all good [23:14] but for what value of good, I don't know === wedgwood is now known as wedgwood_away [23:31] * thumper is spending time considering jam's comments