[05:25] davecheney: mornin' boss [05:28] wrtp: woop woop [05:28] davecheney: how's tricks? [05:29] wrtp: so, i added the a feature to environ.Instances, if you pass nil, you get whatever it knows about at that point [05:29] you may find it upsetting [05:29] davecheney: i think it's probably the best way forward at this point [05:30] davecheney: the other alternative was to add a bool "all" argument to request all instances in addition to the ones requested. [05:30] http://paste.ubuntu.com/1029872/ [05:30] s/the other/another/ [05:30] the PA calls environ.Instance(nil) in a loop anyway [05:30] so I think we can cope with it eventually discovering all machines [05:31] davecheney: seems reasonable. what a pity ec2 makes everything so darn hard. [05:32] wrtp: is has to be, it's cloud scale [05:32] wrtp: http://paste.ubuntu.com/1029874/ [05:32] I think it's fine to call this in a loop [05:32] environs.Instance(nil) that is [05:32] davecheney: i suppose so, but the eventual consistency stuff seems a little unnecessary. [05:33] wrtp: it does sound a little overengineered [05:33] it not like the console is fast or anything because of it [05:34] :-) [05:35] davecheney: i thought the provisioning agent only needed to get the instance list on startup [05:39] davecheney: at least, that's how i understood your message on the mailing list [05:41] Morning. [05:41] wrtp: well, the pythonic version did it periodically [05:41] TheMue: hiya [05:41] TheMue: hello! [05:42] wrtp: also, findUnknownInstances() can probably cache it's results after the first run [05:42] davecheney: i suppose that's useful if there might be several provisioning agents running concurrently. [05:42] it's more to fix the problem of [05:42] add machine, stop PA, remove machine, start PA == instance is lost and not shutdown [05:44] davecheney: yeah, but that could happen in a 2nd PA instance, i think, so the "unknown instance" thing could happen for the first PA instance even when it wasn't shut down. [05:44] wrtp: i'm aware of, but not putting any effort towards concurrent PAs at this point [05:44] davecheney: ok. [05:55] TheMue_: internet troubles ? === TheMue_ is now known as TheMue [06:07] davecheney: Mobile access. ;) [06:11] TheMue: i'll speak slowly then [06:11] TheMue: mobile data speeds in australia are pitiful [06:15] davecheney: Here it's mostly ok. [06:17] bugger, after implementing code that shuts down unkonwn instances, the other side of the unit tests have broken [06:17] FAIL: provisioning_test.go:245: ProvisioningSuite.TestProvisioningDoesNotProvisionTheSameMachineAfterRestart [06:17] Error: provisioner started an instance [06:47] TheMue: wrtp have you ever had visilibity issues between different zookeeper connections [06:47] davecheney: no [06:47] ie, you write somethig with connection A, but it isn't visible to connection B ? [06:48] davecheney: using the same server? [06:48] yup, localhost [06:48] davecheney: nope. i suspect a bug in your code :-) [06:48] yeah, good call [06:51] davecheney, wrtp: I have suspicions that two connections to the same local server *can* have rather different views of what time it is [06:52] fwereade: interesting. more than just transient phase difference you mean? [06:52] fwereade: the problem I am seeing is, in a test, I start an instance, then write the provider id back to the state with machine.SetInstanceId [06:52] davecheney, wrtp: they'll see the same history, sure, but I don't think any guarantees are made about distinct connections being synchronized in any way [06:53] then I close that state connection, open another one, but the Id is not there [06:53] fwereade: aren't they looking at the same underlying state? [06:54] http://codereview.appspot.com/6307049/diff/2001/cmd/jujud/provisioning_test.go [06:54] ^ line 245 etc [06:55] wrtp, I'm afraid I don't know exactly what form that underlying state takes; but given the terms in which the guarantees are couched I wouldn't find it surprising [06:55] davecheney: my first inclination would be to put a debugging print inside zk to print out what attributes are being set [06:56] yeah, i'll keep digging [06:56] fwereade: i think i would, but then again i haven't delved too deeply into zk storage internals. [06:56] this is almost certainly my fault [06:57] fwereade: when you've a moment, a chat about upgrade would be good [06:58] wrtp, specifically: [06:58] Timeliness [06:58] The clients view of the system is guaranteed to be up-to-date within a certain time bound. (On the order of tens of seconds.) Either system changes will be seen by a client within this bound, or the client will detect a service outage. [06:58] fwereade: surely that applies only when you've got multiple servers? [06:58] wrtp: i'd think so [06:58] crap [06:59] that is weird [06:59] Sometimes developers mistakenly assume one other guarantee that ZooKeeper does not in fact make. This is: [06:59] Simultaneously Conistent Cross-Client Views [06:59] davecheney, wrtp: but I *hadn't* previously noticed the sync() call they mention for getting round this [07:00] davecheney, wrtp: all above from Sometimes developers mistakenly assume one other guarantee that ZooKeeper does not in fact make. This is: [07:00] Simultaneously Conistent Cross-Client Views [07:00] er, http://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html#ch_zkGuarantees [07:01] fwereade: "ZooKeeper by itself doesn't guarantee that changes occur synchronously *across all servers*" [07:01] which is fair [07:01] fwereade: i still think it's talking about cross-server consistency, not single-server consistency [07:02] fwereade: i may of course be wrong :-) [07:02] wrtp, Single System Image [07:02] A client will see the same view of the service regardless of the server that it connects to. [07:02] fwereade: i'm not sure i see the relevance of that [07:03] fwereade: we've only got one server. [07:04] wrtp, for that to hold, a client can't just be getting the latest state from whatever server it happens to connect to... can it? [07:04] wrtp, I agree that I haven't seen anything specifically stating that there are no additional guarantees with single servers [07:05] fwereade: i don't see why not. isn't that the whole point, in fact? [07:05] wrtp, I think the whole point is that everyone sees the same history but not necessarily at the same time [07:09] fwereade: i guess i'm just having trouble seeing how this would happen in the single-server case. a write would have to put the data into a slow pipeline, to be written eventually, but the write consistency guarantees mean that a write must always see the latest view, i think, so on a single server i can't see that happening. [07:09] davecheney: you could try putting a sleep after the zk write and see if that made a difference. [07:10] fwereade: sounds like 'everyone will see the same events, in the same order, eventually' [07:10] uh oh, australia is lagging out [07:10] wrtp: nope didn't help, _but_ if I did NOT call st.Close() on the first connection, before opening the second everything worked [07:11] davecheney, I don't even think it guarantees that everyone will see the same events... just a consistent series of state snapshots, if you like [07:11] davecheney: interesting. maybe the close is losing events or something. [07:11] 'everyone will see most of what happened, probably in order [07:11] wrtp: indeed, I wonder if we need an explicit flush [07:12] davecheney: the close is happening in the same thread, right? [07:12] davecheney, I think it does guarantee "in order", if somewhat more weakly than I would prefer [07:12] wrtp: yes, i kill the tomb, which closes in a defer [07:12] davecheney: you might want to try reproducing the behaviour in a less convoluted setting. [07:13] wrtp: yes [07:15] wrtp: i'm certainly seeing some scarey things hapen around close [07:15] will do a simple test case [08:13] fwereade: ping [08:23] wrtp, pong [08:24] fwereade: upgrades... [08:24] wrtp, ah yes [08:24] fwereade: this was my first thought: http://paste.ubuntu.com/1030040/ [08:25] fwereade: but then i realised that "exit and let upstart start new version" is asking for trouble [08:25] wrtp, really? handing responsibility over to upstart seems pretty sane to me [08:25] wrtp, what are you worried about? [08:26] fwereade: i'm worried about what happens if someone uploads a dodgy set of tools. suddently everything will break. [08:26] suddenly [08:26] wrtp, hm [08:26] fwereade: i have a solution [08:26] fwereade: which you might or might not like [08:27] * fwereade listens [08:28] fwereade: it would be nice if a program could upgrade itself, but it can't do that and still have upstart handle the case where it crashes. [08:29] fwereade: so the idea is to add another "upgrader" command [08:29] fwereade: which handles the rendezvous between the old and the new versions [08:30] wrtp, that sounds fine until there's a problem with the upgrader :p [08:30] wrtp, actually, I think I see another problem [08:30] fwereade: the idea is that the upgrader is simple enough that it never needs upgrading itself. [08:30] wrtp, sometimes the args we use to start the agents will change [08:30] fwereade: that's fine. i've catered for that. [08:30] wrtp, so we can't necessarily just reuse the upstart script [08:30] ah [08:30] cool :) [08:31] wrtp, I'm reasonably happy with the upgrader idea [08:31] fwereade: the idea is that when you upgrade, you actually run both programs together for a while. [08:31] fwereade: the new program connects to the state, does some checks and then says "ok, i'm ready to start" [08:31] wrtp, my only objection is that "the upgrader is simple enough that it never needs upgrading itself" feels a touch optimistic to me [08:32] wrtp, I don't really like running 2 at a time [08:32] fwereade: then the old program shuts down and the upgrader tells the new program to go ahead [08:32] fwereade: the nice thing about running them both at the same time is that you get zero down time [08:33] wrtp, yeah, it's just my gut reaction [08:33] wrtp, I will probably come around to it [08:34] fwereade: i've built the upgrader part already (although i've still got some compiler errors) [08:34] fwereade: i think it's possible to do some exhaustive verification of it to check that it's correct [08:35] fwereade: it's 280 lines of code [08:35] fwereade: which is bigger than i'd hoped, but still pretty small [08:36] fwereade: at the moment, the assumption is that it talks to the commands that it runs via stdin and stdout. that could change. [08:37] wrtp, cool [08:37] wrtp, sorry, I have to go help cath with the car for a bit :/ [08:37] fwereade: np [08:38] wrtp, idea sounds broadly sane but I'd like to see an implementation ;) [08:38] fwereade: later this morning, i hope :-) [08:38] wrtp, sweet === TheMue_ is now known as TheMue [09:55] TheMue, is it sane to have settings on a service relation? [09:56] fwereade_: Today we have on a relation. But I don't know yet how they are used. [09:57] TheMue, it seems to me that *unit* relation settings are sane (and are set by units in their hooks) and *service* settings are sane (set by the user via command line) [09:57] TheMue, but that we don't currently have a use case for *relation* or *service relation* settings [09:58] fwereade_: Did you check Py state where those settings are changed? [09:58] fwereade_: Not that we only create that node and nothing else. [09:59] TheMue, what I'm dancing towards is a suggestion that we drop all creation of role/settings nodes in state.AddRelation, because I think they're meaningless until we add units [10:01] fwereade_: Sounds reasonable. [10:01] TheMue, sweet, I think it makes things simpler [10:02] fwereade_: Yes. Not much, but every bit counts. [10:08] morning. [10:08] Aram: hiya [10:21] Aram: Moin. [10:27] Aram, heyhey [10:35] fwereade_: here's the WIP. i've compiled it only, no tests yet. https://codereview.appspot.com/6307061 [10:37] wrtp, cheers [11:12] TheMue, are there any existing tests for the scope stuff in AddRelation? [11:14] fwereade_: Only the validation of the value, it's in my last proposals. [11:15] fwereade_: What exactly do you want to see tested? [11:19] TheMue, sorry, lost history; did you respond? [11:19] fwereade: Hehe, modern technology. [11:19] fwereade: I said that my latest proposal does a value validation, but nothing else. [11:19] fwereade: And I asked what do you want to see tested. [11:20] fwereade: We've not yet reached the parts that add container scoped paths in ZK. [11:20] TheMue, what is meant to happen when the scope doesn't match [11:20] TheMue, that's edging its way towards a proposal on my end [11:22] fwereade: One moment. [11:24] fwereade: https://bugs.launchpad.net/juju-core/+bug/1007373 See latest question, it is still open. [11:24] fwereade: Today, in Py as in Go, only one endpoint has to be container, that's enough. [11:24] TheMue, I think that's correct; but we need to verify that we store ScopeContainer on each [11:25] TheMue, that's what you do, but it's not tested AFAICS [11:26] fwereade: You're right. [11:26] TheMue, I was also wondering why we return the ServiceRelations from AddRelation; seems to me it would make more sense to return just the Relation, and give that a Services method [11:27] fwereade: Did you checked the callers of AddRelation() [11:27] TheMue, there aren't any [11:28] fwereade: In Py? [11:28] fwereade: Interesting. [11:28] TheMue, but if there were, they could just as easily extract the service relations from the service [11:28] TheMue, sorry, not in py [11:28] fwereade: The you maybe see the reason. [11:29] fwereade: But a relation has not enough information for all services, it would have to dynamically retrieve them again. So maybe it's better to only return the service relations, they have a Relation() method. [11:30] TheMue, sorry, I don;t see the reason [11:30] TheMue, the only client discards the result [11:31] fwereade: Hmm, then the old reason for it may be gone. [11:32] TheMue, and honestly I don't see what good the Relation type actually does (maybe status?) [11:32] TheMue, given a service, I will definitely want to know what relations it's in [11:33] TheMue, but for that I want ServiceRelations, I think [11:33] TheMue, hmm, actually, even for status a bare Relation type is pretty useless I think [11:34] TheMue, I think it should actually be AddRelation(...) error [11:34] fwereade: It's used in RemoveRelation() ;) [11:34] TheMue, why don't we just pass the same endpoints, calculated in the same way? [11:35] morning mramm [11:35] fwereade: We can do, no problem. [11:35] mramm: Moin. [11:36] TheMue, I don't *think* there are any other use cases... but I may be missing something [11:36] fwereade: But that change would affect all callers too. [11:36] TheMue, how many? [11:37] TheMue, AFAICS the only use of get_relation_state is in remove-relation, which then uses it to... remove the relation [11:37] fwereade: I don't know. I only want to take care that a redesign of todays API instead of pure porting doesn't cost too much time (up to 12.10). [11:38] fwereade: And you know, our last API change is now gone almost completely back into the former solution. [11:38] TheMue, but a bit of checking of the existing API, and seeing that parts of it are 100% useless, saves us an awful lot of implementation time [11:38] TheMue, which one? [11:39] fwereade: I'm not safe enough in todays Py code and the history which lead to it. So if you see opportinities in those changes please talk to Gustavo. [11:40] fwereade: The topology related relation stuff we talked about at UDS. [11:41] TheMue, this one: Services map[string]*topoRelationService [11:41] ? [11:42] fwereade: That's one of the parts, and some implementation details. The last proposals almost looked like the first ones. [11:43] TheMue, well, I guess this is the same area... but you are aware that we're burning time implementing putative multi-endpoint relation support that isn't on any roadmap I know of? [11:44] TheMue, based on that I can deal with the data format change [11:44] fwereade: Yep [11:45] TheMue, ok, I just don't understand why it's worth spending time on this [11:45] fwereade: By the way, did you read my error handling mail? [11:45] TheMue, I thought you seemed to make a solid case but I haven't got much more of a response [11:46] TheMue, anyway, sorry about that whole review cycle [11:46] TheMue, I have no idea on what basis niemeyer makes that sort of API decision though [11:47] TheMue, the AddRelation(args...) business is a known ugliness in python which I'm sure niemeyer complained about himself at one stage [11:47] fwereade: That's no problem. It's only that I'm maybe not the best discussion partner for some ideas due to my lack of the project history and many design motivations. [11:48] TheMue, yeah, understood -- but I think it's worthwhile talking to you about these things anyway [11:48] fwereade: That's true. [11:49] * fwereade tries to figure out what he's actually doing [11:50] TheMue, do we have Service.Relations() yet? [11:51] TheMue, wait, sorry, ignore me [11:51] fwereade: No [11:52] fwereade: I'm currently taking a deeper look into our code base regarding error handling. [11:53] TheMue, ok, cool [11:53] fwereade: There are many places where errors just passed up. Not only ZK, topology or os. [11:53] TheMue, I think the thing I *need* now is Service.Relations; I'll get to work on that [11:54] TheMue, I think we should also fix the interface to AddRelation and RemoveRelation [11:54] fwereade: IMHO we should seperate between errors containing possible additional informations (as own types) and the visualization of this error as message, log entry, something else on the UI level (commands, logs, web). [11:54] TheMue, would you have any objection to a CL that combined the two? they're somewhat intertwined [11:55] fwereade: Combining Add and Remove? [11:56] TheMue, making Add return error, and Remove take endpoints... like add [11:58] fwereade: So instead of a relation to remove I would have to get the endpoints, then (internally) search a matching relation and then delete it? Where do you get the EPs from? And did you take a look into todays RemoveRelation code? [11:59] TheMue, how do you get a relation instance to remove now? [11:59] TheMue, the answer is "you can't" [11:59] fwereade: Are there no callers of remove_relation_state in Py today? [12:00] TheMue, the only called uses a relation it got from get_relation_state, which takes endpoints and returns a relation [12:00] TheMue, that place is the only client of get_relation_state [12:00] TheMue, the actual operation is "given these endpoints, which came from the command line, remove the corresponding relation" [12:01] TheMue, just like Addrelation but in reverse [12:01] fwereade: OK, I see. So it sounds reasonable. [12:01] TheMue, cool, thanks [12:35] I wonder why Gustavo made mgo take bson.{M,D} arguments instead of using reflection to determine the type of arguments, it's not like you buy any type safety since you can put whatever crap you want inside the bson objects. [12:35] err = k.nodes.Update(bson.M{"_id": parent}, bson.M{"$push": bson.M{"children": path}}) [12:36] there's a lot of bson.M noise. [12:36] if you use bson.D it's even worse. [12:36] surely we can do better. [12:54] Aram: what would you want that update line to look like? [12:54] thinking. [13:50] jimbaker, the branch is looking much nicer [14:34] fwereade: did you have a look at the upgrade interface in https://codereview.appspot.com/6307061/diff/1/upgrade/upgrade.go ? does it look kinda reasonable? all agents would call Start, and then Upgrade when they need to upgrade. [14:36] wrtp, sorry: yeah, it looks sensible, but for some reason I'm a bit suspicious of stdin/stdout [14:36] wrtp, trying to figure out whether I'm just being irrational [14:36] fwereade: yeah, i wondered about that. [14:37] fwereade: it would be perfectly possible to use e.g. unix sockets in the same framework [14:37] wrtp, indeed, but then I'm not reaally sure what that buys us [14:37] fwereade: but in the end, stdin/stdout seem to give us exactly what we want, i think. [14:37] wrtp, indeed :) [14:37] fwereade: i don't think we're gonna use it for anything else [14:38] wrtp, consider my reaction to be "tentative approval" then :) [14:38] fwereade: and i've added some safeguards in there in case anyone prints random stuff [14:38] fwereade: thanks [14:39] fwereade: i think the upgrader implementation is really quite neat, BTW. i'm happy to have written it, even if it goes in the bin on monday. [14:39] wrtp, haha, yeah, it's nice :) [14:40] fwereade: in particular the way that cmd.run recursively calls itself in a new goroutine and talks to the new version of itself via a channel. [14:41] fwereade: i started doing it without goroutines and realised it was surprisingly hard to do nicely. [14:43] wrtp, ++goroutines :) [14:43] fwereade: +1 === Guest_ is now known as smaddock [15:00] TheMue, if you have a moment I would appreciate a look over https://codereview.appspot.com/6303060 which we discussed earlier [15:01] *click* [15:10] hmm, linux really isn't good at coping with runaway processes. whatever happened to time sharing? [15:14] fwereade: It will conflict a bit with my latest validation, but so far LGTM. [15:14] fwereade: I'm interested what niemeyer will say. [15:21] I've written the longest commit message of my life [15:22] http://paste.ubuntu.com/1030536/ [15:33] TheMue: fwereade wrtp: I don't understand something about bzr, say I did these 5 commits in my branch. I want to propose a merge. After the merge is done, will my 5 changes appear in the trunk history or just the merge proposal? [15:34] Aram: just the merge proposal [15:34] hmm. [15:34] that's unfortunate. [15:35] Aram: if you want that commit to appear, you should have it as part of the merge proposal description [15:35] Aram: that's what we'll read when looking over the CL anyway [15:35] Aram: so you might as well put it there. [15:35] TheMue, cool [15:36] thanks. I know this is how contribuiting to the Go project also works, but I find it counter intuitive in a distributed versioning system world. it feels more like cvs to me. [15:37] Aram: seems reasonable to me. the commits aren't lost, they're just one level deeper. [15:37] oh? You can still access them? [15:37] Aram: yeah [15:37] how? [15:38] Aram: bzr log -n 0 [15:38] Aram: or -n 2 to show just two levels [15:38] interesting. [15:45] ugh, lbox uses exp/html [15:45] I guess I should install the ppa? [15:47] Aram: yeah, i just install the ppa [15:52] wrtp: [15:52] 2012/06/08 17:50:06 Authenticating in Launchpad... [15:52] Go to your browser now and authorize access to Launchpad. [15:52] [15:52] how do I do that? [15:53] Aram: i guess your browser should have come up with a new window, assuming you're using a standard web browser. i doubt it'll work with lynx :-) [15:53] ah, damn. [15:53] this is a headless box [15:53] hmm... [15:53] Aram, you can do it on a box with a head, and transfer the auth token [15:53] Aram, actually you don't even need to do that [15:54] Aram, you can go to lp, and authorize the app separately [15:54] and copy the token [15:54] maybe.. ;-0 [15:55] hmm.. no that doesn't quite work [15:55] i was looking at https://launchpad.net/~/+oauth-tokens [15:55] you can't actualy retrieve the token there though, just manage the apps [15:55] yes, no option to add [15:56] * Aram is installing a browser in his headless box [15:57] hmm.. it might work with lynx [15:58] great, chrome doesn't like remote X. [15:58] lol [15:58] I have the URL now though [15:59] and I can do it, I think [16:07] I think I finally did it. [16:08] wrtp: fwereade: TheMue: care to review a small branch? (my first, heh...): https://codereview.appspot.com/6298062/ [16:08] Aram, gladly :) [16:10] Aram: will do [16:10] thanks. [16:11] Aram: Today only time for a quick look, have to leave now. Will look again tomorrow. So far ok, only seperating comments like // ------ are uncommon in our project. [16:12] I know, I want to delete those, niemeyer wrote them though [16:12] heh [16:12] Aram: Even if I like them because I'm adding optical seperators in my private code too. ;) [16:12] there's a lot of dead code. [16:13] So, I'm off, birthday party of sister-in-law. [16:13] enjoy [16:13] Have a nice weekend. [16:13] likewise [16:13] Aram: Thx. [16:22] Aram: i'd delete 'em. gustavo's deleted them in another project recently AFAIR. [16:22] Aram: but maybe in another branch... [16:22] yes. [16:36] fwereade: any chance you could have a glance at this before i post it to the list? http://paste.ubuntu.com/1030658/ [16:36] wrtp, reading [16:38] wrtp, sorry, another problem has just crystallized in my brain [16:38] fwereade: go on [16:38] wrtp, how will this handle zk data format changes? when we need to stop everything, fix zk, and restart everything? [16:39] wrtp, not that the original proposal was explicit about that either... [16:39] wrtp, and not that I can see anything that will make it *harder* than the original [16:39] fwereade: i did have a plan for that... let me think [16:40] wrtp, but that does all look good otherwise [16:48] fwereade: here's a possibility - if the version is tagged as "pending", then all agents download the new version, stop what they're doing, then wait for the "pending" tag to be removed. *then* they go through the normal upgrade procedure. [16:50] fwereade: it's possible we might want to alternate between two server ports, so that new-major-version agents can connect to the new version of the db while others are still hanging on to the old one. [16:50] wrtp, first bit sounds sane, bit nervous about the second part [16:51] wrtp, I don;t think we ever want 2 things connected to the same db that aren't in agreement about what data formats are in play ;) [16:51] fwereade: me neither. hence before we bring up the new db, we make sure that everything in the system is halted, waiting for the pending tag to be removed. [16:52] wrtp, if we can halt everything we can also tell them to drop their connections, surely? [16:52] fwereade: yes, but we can't then tell them when to reconnect, right? [16:53] wrtp, the laws of logic be a harsh mistress [16:56] fwereade: i'm not sure i can see a way of reliably upgrading the db without using two db instances. [16:58] fwereade: and also we'd like to be able to switch the underlying db technology too. [16:58] wrtp, hmm, yeah, makes sense [17:01] Aram: there's a convention of using "pathPkg" as an alternative name when importing "path". [17:02] fwereade: last thing i saw from you was "[17:55:53] wrtp, the laws of logic be a harsh mistress" [17:02] fwereade: in case i missed anything [17:02] wrtp, you missed a "yeah, makes sense" [17:02] fwereade: cool, thanks [17:11] right, i'm off for the weekend. see y'all monday. [17:11] fwereade: have a good weekend. enjoy the lovely sun which we haint got. [17:13] wrtp, cheers, enjoy :) [17:31] wrtp: ok, thanks, will change [17:35] wrtp, you stop the activity, wait till everyone is stopped, upgrade, then reboot the agents [17:35] wrtp, have a good weekend [17:36] er. upgrade == upgrade, run migrations === meetingology` is now known as meetingology