/srv/irclogs.ubuntu.com/2009/01/20/#upstart.txt

=== sadmac_ is now known as sadmac
=== magnetic is now known as foolano
sadmac2notting: read my blog?18:23
nottingsaw it. have not looked at the code.18:24
sadmac2cool18:24
Keybukion_: I wrote a new allocator over the weekend ;)19:08
ion_Ooo19:09
sadmac2Keybuk: get my email?19:09
Keybuksadmac2: yes.  I still think your state machine is crazy19:09
Keybukion_: nih_alloc and nih_free still work as before (alloc with parent, free anyway)19:10
Keybukbut now you have nih_alloc_ref (add a new parent), nih_alloc_unref (drop a parent) and nih_discard (throw away only if there are no parents)19:10
sadmac2Keybuk: and I still haven't seen you propose a mechanism behind that pretty syntax of yours19:10
ion_keybuk: Alright19:10
ion_keybuk: Does unref automatically discard?19:10
Keybukion_: yes19:11
Keybuksadmac2: err, I've told you exactly what I'm going to do - it hasn't changed since plumbers19:11
sadmac2Keybuk: really? because I haven't read about it the same way twice19:12
sadmac2depsolving keeps disappearing and reappearing...19:12
Keybuk"depsolving" ?19:12
sadmac2if you start foo, which depends on bar, does it start both or just error and tell the user "Fix it?" I've heard you tell it both ways19:12
Keybukno you haven't19:13
sadmac2there was an auto keyword at plumbers19:14
sadmac2that vanished last time we spoke19:14
Keybukerr, that vanished after a lengthy debate both on the mailing list and on here19:16
sadmac2must've missed it here. Dunno where it was on the mailing list19:17
Keybuk"upstart configuration", Nov 200819:17
sadmac2ah, so its add a manual now19:18
Keybukno19:18
sadmac2the functionality is still there then19:18
Keybukit's treat disabling jobs as a separate thing to their definition19:19
Keybuka sysadmin can flag a job as disabled19:19
Keybukbit more like SMF19:19
KeybukI ran it by our server team here, their eyes lit up with joy, so it's a keeper19:19
sadmac2ok, so the fundamental difference is in your system states/jobs are first class objects19:21
sadmac2where my system essentially doesn't have a first class object19:21
sadmac2can you solve all the use cases with yours? mounting? (dbus I know you've done)19:23
KeybukI suspect that leads to a lot of differences, both fundamental and trivial19:23
sadmac2I'm fairly certain yours could be implemented on top of mine (not that we should, but its very significant that we can).19:23
Keybukstateless mounting still can't be solved in yours, so I don't see that to be a useful example19:23
sadmac2can you mount at all?19:24
sadmac2can you manage the state for stateful mounting?19:24
Keybukyes, of course19:24
sadmac20.5 can't do /either/ that's the importance of the case19:24
KeybukI can manage the state for stateful mounting without Upstart at all19:25
Keybukjust by using udev and some shell scripts19:25
Keybukso I'm not sure that's a useful example either19:25
sadmac2I don't know that you can easily express virtual states either (explanation follows):19:25
sadmac2so my usecase would be SELinux19:26
sadmac2its damn useful to know if the system is enforcing or not and act based on this.19:26
sadmac2you can check if the system is enforcing by running getenforce19:26
sadmac2but its hard to get an event stream from which you can derive it19:27
sadmac2in my model its not hard to describe states coming from anywhere. so you could define:19:27
sadmac2selinux: test-by /usr/bin/getenforce19:27
Keybukand it would run that how many times a second?19:28
sadmac2Keybuk: it would run it when it needed to know. When the user lists states or when dependency checking is interested in the selinux state19:28
sadmac2the rest of the time selinux would be neither up nor down19:28
sadmac2its "quantum." neither running nor not running until observed19:29
Keybukit needs to know continually19:29
Keybukotherwise how would it know when to stop a service because selinux is no longer being enforced?19:29
Keybukalso would it only check that if a sysadmin issues a start command?19:30
Keybukotherwise when would it check that for other reasons?19:30
sadmac2when the service came up19:30
sadmac2Keybuk: and this can be used in combination with regular ons and when (event1..event2)19:30
Keybukhow can the service come up if it's waiting on a dependency using test-by?19:31
sadmac2Keybuk: if there's an exec stanza, then it goes by the usual method (it can verify the test after execing, or not, that's a bit more of a philisophical question)19:32
Keybuksorry19:33
Keybukbut it sounds like you really haven't thought this through19:33
Keybuksince you're not bothering to answer the question19:33
sadmac2Keybuk: on setenforce(1)..until setenforce(0)19:34
sadmac2Keybuk: the events can still stop it19:35
Keybukok, let's do a worked example19:35
sadmac2Keybuk: /but/ we don't get the initial setenforce, because its done in initrd (and there be pjones)19:35
Keybukgive me a real example of a service that would depend on selinux in this fashion19:35
sadmac2so the additional test-by is necessary19:35
sadmac2Keybuk: setroubleshootd19:36
sadmac2no, that runs in permissive too. If we had one for "disabled" then that works19:36
Keybukok, let's use setroubleshootd for a moment19:36
Keybukhow would its definition be expressed?19:37
sadmac2setroubleshootd when selinux19:37
Keybukno : s ?19:37
Keybukno paths or arguments ?19:37
sadmac2that's just the setroubleshootd ->selinux dep19:38
Keybuksetroubleshootd has no other dependencies (not even filesystem writable or mounted?)19:38
Keybukplease don't shorthand19:38
Keybukgive the full example19:38
Keybukuse pastebin if you like19:38
sadmac2setroubleshootd19:38
sadmac2    when selinux19:38
sadmac2    when can-exec("/usr/bin/selinux")19:39
sadmac2    exec /usr/bin/selinux19:39
sadmac2can-exec test-by [ -x %1 ]19:40
sadmac2selinux19:40
sadmac2    test-by getenforce19:40
sadmac2    when (setenforce(1)..setenforce(0))19:40
sadmac2#eof19:40
Keybukok19:40
Keybuknow give me a worked example of a system boot19:40
Keybukit's just come up19:40
KeybukUpstart has started19:40
Keybuknow what happens?19:40
Keybukwell, assumedly it parses the job definitions19:41
Keybukso let's say it's done that <g>19:41
Keybuknow what?19:41
sadmac2shit. missing a line19:41
sadmac2can-exec when mounted19:42
sadmac2^^for efficiency. not mandatory19:42
Keybukyou haven't defined mounted in the above, so please do that19:42
Keybuk(feel free to just claim it's a state that comes up at some useful point)19:42
sadmac2Keybuk: its a state that comes up whenever a filesystem is mounted.19:43
Keybukwhat brings that state up?19:43
KeybukI think if you're going to rely on such a thing right now, you need to define it ;)19:43
Keybukit might be easier for your example just to assume that there's only one filesystem and no such state19:43
sadmac2yeah, ignore that. there's some particulars to this stage of boot I'm not thinking of19:44
sadmac2ok, so we're up19:44
Keybukok19:45
Keybukso we're up19:45
Keybukwhat happens now?19:45
sadmac2we trip an initial event, say startup.19:47
sadmac2this triggers a whole bunch of states not relevant to this example.19:47
Keybukperhaps19:47
Keybukthough that event is not referenced in your above example19:47
Keybukso let's ignore it19:47
sadmac2ok.19:48
Keybukupstart has started, it has parsed its configuration, what happens next?19:48
sadmac2it triggers some state which wants setroubleshootd19:49
sadmac2setroubleshootd in turn wants selinux19:49
sadmac2selinux was enabled with setenforce, but this happened in initrd, so we don't know19:49
sadmac2this being a fresh boot, the state is indeterminate, so we run test-by19:49
sadmac2getenforce tells us selinux is up. we clear that dependency for selinux'19:50
sadmac2can-exec is never triggered by anything but the test-by.19:50
sadmac2so we run the test stanza there19:50
sadmac2it tells us we are allowed to execute /usr/sbin/selinux.19:51
sadmac2*/usr/bin/setroubleshoot19:51
sadmac2we bring the state tentatively up, and tell the service manager to run /usr/bin/setroubleshoot19:52
sadmac2it returns a service handle, which we add to our parameters, and come all the way up19:52
sadmac2this triggers a netsplit19:54
Keybukwb20:11
Keybuk<sadmac2> this triggers a whole bunch of states not relevant to this example.20:11
Keybuk<Keybuk> so let's ignore them20:11
Keybuk your example is all that interests me20:11
Keybuk and it is self-contained20:11
Keybuk it makes no reference to other events, or other states20:11
Keybuk upstart has started, it has parsed its configuration, what happens next?20:11
Keybuk-- 20:11
Keybukthat's as far as things got before the split20:11
sadmac_Keybuk: ok, what'd we collectively miss?20:16
=== sadmac_ is now known as sadmac
Keybuk<Keybuk> wb20:18
Keybuk <sadmac2> this triggers a whole bunch of states not relevant to this example.20:18
Keybuk <Keybuk> so let's ignore them20:18
Keybuk  your example is all that interests me20:18
Keybuk  and it is self-contained20:18
Keybuk  it makes no reference to other events, or other states20:18
Keybuk  upstart has started, it has parsed its configuration, what happens next?20:18
Keybuk -- 20:18
Keybuk that's as far as things got before the split20:18
Keybuk--> sadmac_ (n=sadmac@nat/redhat/x-6753e36432a1150f) has joined #upstart20:18
sadmacKeybuk: ok, well, we need one more state: running_normal20:20
sadmacKeybuk: it has lots and lots and lots of deps. one of them is setroubleshoot20:20
Keybuka goal state20:21
sadmacif you so please20:21
Keybukone that lists the services that should be running in normal configuration?20:21
sadmacyes20:21
KeybukI consider this a failure20:21
Keybukif we're going to have goals, let's just use initng20:22
sadmacumm, what?20:22
sadmacwhy?20:22
Keybukthe reasons I wrote Upstart, instead of just modifying something that already exists, is that I expressly did not want goals, runlevels, or anything similar20:23
Keybukit's the _only_ difference between Upstart and those other systems20:23
sadmacKeybuk: and its the _most_ requested feature I get from people20:23
Keybukthen those people should use initng or launchd or smf20:23
sadmacKeybuk: the advantage here is 1) goals aren't mutualy exclusive20:23
Keybukthey aren't mutually exclusive in initng either20:23
sadmac2) goals are named, and there are infinitely many20:24
Keybukthey are named in initng20:24
sadmac3) they can be expressed in terms of each other20:24
Keybukgoals in initng can depend on each other20:24
sadmacKeybuk: ok, how do I start a predefined subset of my usual services from the command line?20:24
Keybukin initng?  ngc start wibble I think20:24
Keybukit's been a while since I played with it20:25
sadmacin upstart20:25
Keybukin my plan for Upstart ?20:26
sadmacyes20:26
Keybuk  start my-predefined-subset-of-my-usual-services20:26
Keybukwhich is a file that looks something like:20:26
Keybuk  while service1 and service2 and service320:26
sadmaca goal state20:26
Keybukyou can also just do:20:26
Keybuk  start service120:26
Keybuk  start service220:26
Keybuk  start service320:26
Keybukand that has the same effect20:26
Keybukno, it's not a goal20:26
sadmaca set of goal states20:26
sadmacyes it is20:27
Keybukno, it really isn't20:27
sadmacwhy not?20:27
Keybuklet's put this discussion on abeyance for a moment20:28
Keybukand go back to your example20:28
Keybuk<sadmac2> setroubleshootd20:28
Keybuk     when selinux20:28
Keybuk     when can-exec("/usr/bin/selinux")20:28
Keybuk     exec /usr/bin/selinux20:28
Keybuk can-exec test-by [ -x %1 ]20:28
Keybuk selinux20:28
Keybuk     test-by getenforce20:28
Keybuk     when (setenforce(1)..setenforce(0))20:28
Keybukthat is what you defined20:28
Keybukand upstart has started, has parsed its configuration, and is now waiting20:28
Keybukwhat happens next?20:28
sadmacit knows its supposed to start running_normal (from other configuration, kernel cmdline, your pick)20:29
sadmacand so it does, and it depsolves it as it starts it20:29
Keybukrunning_normal isn't defined above20:29
Keybukso please, again, do not reference anything outside your example20:29
sadmacI defined it as I came in20:29
sadmacin syntax..20:29
sadmacrunning_normal:20:30
sadmac    when setroubleshoot20:30
Keybukok20:30
sadmac    when <lots of other stuff we won't talk about>20:30
Keybukupstart is waiting20:30
Keybukwhat tells it to start "running_normal"?20:30
Keybukwhat tells it to start "setroubleshootd"?20:30
Keybukwhat tells it to start "selinux?"20:30
sadmacupstart's first action on running is always to start some kind of "strap state" which in our case is configured (one way or another) as running_normal20:31
Keybukok20:31
Keybukthat is what I call a "goal"20:31
sadmacit does a solve-and-start on the strap state20:31
Keybukgoal, strap state, runlevel, etc.20:31
sadmacok20:31
Keybukupstart has a predefined state it tries to reach20:31
sadmacI'm not disputing its a goal20:31
Keybukthis state is defined as a series of dependencies20:31
Keybukto reach it, it solves the dependency set, starting each service in term20:32
Keybukperhaps applying some kind of ordering to that20:32
Keybukcongratulations, you've designed a dependency-based init daemon20:32
Keybukhttp://initng.org/  - enjoy ;P20:32
sadmacKeybuk: what of this strategy are you escaping with upstart?20:32
KeybukUpstart, in its very original definition, is an event-based system20:33
Keybuknot a dependency-based system20:33
sadmacwhich is broken20:33
Keybukfrom the very first document I wrote on the subject, I outlined this as the distinction between Upstart and what else exists out there today20:33
Keybukif that is broken, then Upstart is a failed project and should be abandoned20:34
Keybukour efforts would be better spent on the pre-existing dependency based init daemons20:34
sadmacwhat are we changing then?20:34
Keybuk(if you consider that not broken)20:34
sadmacwhat does your plan do that is not a goal?20:34
Keybukif you truly believe that Upstart, as an event-based init daemon, is broken20:35
Keybukand you believe that a dependency-based init daemon works, then you should look into one of the dependency-based daemons20:35
Keybukinitng is the prime example here20:35
Keybukif the licence isn't a problem, SMF might be appealing - though it isn't as flexible20:35
sadmacok20:35
sadmacbut how is an event based init daemon /that solves the problems in 0.5/ still different?20:36
Keybukthe difference between the two can be defined quite simply20:38
Keybuka dependency-based init daemon knows where it's going, and figures out how to get there20:38
Keybukan event-based init daemon has no idea, and just does whatever it can20:38
sadmacok, I see your problem. let me adjust my example20:39
sadmacto setroubleshoot add:20:39
sadmacwhen running_normal20:39
sadmacauto20:39
sadmac(the auto is an artifact of the present syntax. It can be massaged out)20:40
sadmacand delete running_normal's definition altogether20:40
sadmacsame result20:40
sadmacactually, that's better20:40
sadmacnow there's no depsolving in standard boot20:40
Keybukso let's go back to the same worked example20:40
Keybukupstart has parsed its configuration20:41
Keybukwhat does it do next?20:41
sadmacwell, it marks running_normal as up, by config. This is now just a marker though. It has no deps20:41
Keybuka ground state?20:42
Keybukie. replace startup with a state?20:42
sadmacyes20:42
Keybuk(would just "on startup" not be a valid example there?)20:42
sadmacok. I think in the long run this way is better for a few reasons, but sure.20:43
sadmacrunning_normal on startup20:43
Keybukthat fulfills one of setroubleshootd's when clauses20:43
Keybukbut not the other20:43
Keybuksorry, not the other TWO20:43
Keybukit has a dep on the can-exec("/usr/sbin/selinux") state20:44
Keybukand the selinux state itself20:44
sadmacand it doesn't /trigger/ it, let's go into that for a second and then we'll look at those20:44
sadmacso running normal comes up.20:44
sadmacas upstart finishes doing this, it adds an event to the event queue: trigger-auto-services20:45
sadmacthis causes setroubleshootd to be brought into question20:45
sadmacupstart iterates through setroubleshootd's deps. theres running_normal. that's satisfied.20:46
sadmacthere's can_exec. upstart looks at the can_exec state and sees that it is undetermined and has a test_by20:46
sadmacit runs the test by and finds that /usr/bin/setroubleshootd is accessible20:47
sadmacso can_exec is up20:47
sadmacnote that it does not /come/ up20:47
sadmacit /is/ up20:47
sadmacupstart just didn't know it before :)20:47
sadmacselinux is much the same way. its test_by is run and it is determined to be up.20:47
Keybukfor the sake of argument20:48
sadmacsetroubleshootd's when's now satisfied, it leaps upward20:48
Keybuklet's say that selinux is not up20:48
Keybukthe test-by fails20:48
sadmactest-by fails, selinux remains undetermined, and no setroubleshootd20:48
sadmac/now/20:49
sadmacsuppose we added this line to our config20:49
Keybukno20:49
Keybukno changing things20:49
Keybuksetroubleshootd didn't come up on boot20:49
sadmacfine20:49
Keybukthe sysadmin notices that, and realises that selinux wasn't enabled20:50
Keybukand enables selinux20:50
Keybukwhat happens now?20:50
Keybuknothing20:50
sadmacno20:50
sadmacselinux had 2 lines of config20:51
Keybuknothing tells your system to re-evaluate its test-by clauses20:51
sadmaclook at number 220:51
sadmacand let me elaborate20:51
sadmacwhen (setenforce(1)..setenforce(0))20:51
sadmacthe sysadmin brings up selinux20:51
Keybukyou didn't define setenforce in your example, so I ignored it20:51
sadmacyou didn't mention this hypothetical appendix in your example20:53
Keybukerr20:53
sadmacso I didn't elaborate on the mechanisms that would make that case work20:53
Keybukthe whole point of working an example is to find out what happens ;)20:53
sadmacno, I /know/ what happens20:53
Keybukthat means working through all the cases20:53
sadmacthe point is to tell you20:53
sadmacok, we'll define setenforce20:54
sadmacsetenforce, through whatever syntax is defined on inotify noticing a change in /selinux/enforcing20:54
sadmac(yes, said file supports inotify)20:54
sadmacit is emitted with one argument: the contents of that file.20:55
* sadmac needs selinux auto20:56
sadmacyeah, I'll work on getting the auto thing out of the syntax20:56
sadmacits kinda a pain20:56
sadmacso the sysadmin changes enforcing, and this satisfies selinux's one and only when clause20:57
sadmacfrom here there's a couple things it could do, and I'm flexible as to which:20:58
sadmacwe could re-run the test-by to be sure (not certain I like that)20:58
Keybukthis is my fundamental issue with test-by20:58
Keybukyou have to re-run it periodically20:59
sadmacor, and this is my assumption, we simply jump right up. once up, if we are configured with a debug flag, we run the test clause, and if it disagrees with what we just did, we through -EDUMBASS20:59
sadmacKeybuk: but we've run it exactly 2 times now, both times deterministically20:59
sadmacno interval timer yet21:00
sadmacKeybuk: the other thing is even if its unreliable it can still be useful in some form. for example21:00
sadmacmount(type: nfs, host: *)21:00
sadmac   when network-up(%host)21:00
sadmacnetwork-up test-by ping %host21:01
sadmaceven the ingrained unreliabilities there are better than we could do otherwise.21:01
sadmacwhen it fails due to insufficient repitition the mount just takes longer to timeout21:02
sadmacwhen it works though we have a bit more verification and probably a quicker abort,21:02
Keybukto be fair, I should give how I'd do it21:08
KeybukI'm not familar with selinux, but judging above the above21:08
Keybukselinux would look like:21:08
Keybuk  pre-start exec getenforce || setenforce21:08
Keybuk  post-stop exec setenforce 021:08
Keybuk--21:09
Keybuksetroubleshootd would look like:21:09
Keybuk  while selinux21:09
Keybuk  exec /usr/sbin/selinux21:09
Keybukthe worked example would be21:09
Keybukupstart parses its configuration21:09
Keybukthe selinux job has no while condition, so can be immediately started21:09
Keybukif selinux was enabled already, getenforce would succeed so the state would be up21:09
Keybukif selinux was not enabled already, getenforce would fail, so setenforce is run and the state would be up21:10
Keybuk(it setenforce failed, then selinux would be down)21:10
Keybukselinux coming up fulfills the while condition for setroubleshootd21:10
Keybukso that would exec /usr/sbin/selinux and come up21:10
sadmacwhat if sbin isn't mounted21:10
Keybukno need for any startup event or ground state, etc.21:11
Keybukyou mean /usr ;-)21:11
sadmacKeybuk: you've known saner storage admins than me I gues21:11
sadmacs21:11
sadmac:P21:11
Keybuk/sbin cannot be on a separate filesystem21:11
Keybukit contains init21:11
Keybukanyway21:12
Keybuknow, the above has a slight disadvantage in that it requires you to not use setenforce directly, but instead use "stop selinux" or "start selinux" as the commands21:12
Keybukthat in of itself isn't insane, but it's maybe annoying to experienced sysadmins21:12
KeybukI'd solve that the same way you would21:12
Keybukredefine selinux in terms of the contents of /selinux/enforcing21:12
Keybukthat might be something like21:13
Keybuk  while file-contains /selinux/enforcing 121:13
Keybukwhere file-contains was a built-in that used inotify21:13
sadmacyou've mostly talked me out of test-by21:13
sadmacbarring that then, what else is different between the mechanisms?21:15
sadmacsyntax is somewhat an artifact and somewhat not. I don't care about the syntax but the differences in mine are an artifact of it doing things yours doesn't21:16
Keybukthe fact that everything my way is first class21:16
Keybukand it's massively simpler to understand21:16
sadmacnot really21:17
KeybukI'll go back to what I said months ago21:17
Keybukwhen I figured it out21:17
sadmacfoo(bar: baz)  == all foos with bar = baz have these properties:21:17
Keybukyours can be summed up as21:17
Keybuk<state>: <actions>21:17
Keybukie. when the state on the left is true, the actions on the right are performed21:17
sadmacno21:18
sadmacthat's very wrong21:18
sadmacbecause there are no actions21:18
Keybukthat's how you defined it yourself not so long ago ;)21:18
sadmacits declarative, and its backward21:18
Keybukoh, no21:18
Keybuksorry21:18
Keybuk<state>: <tests>21:18
Keybukthe state on the left is true, while all of the tests on the right are true21:18
sadmacI wouldn't go with that either21:18
Keybukconfusing it with something else I was thinking of21:18
sadmac<set of states>: <properties>21:18
sadmacthe state[s!] on the left behave in the manner described on the right21:19
sadmacmy model never talks about one state21:20
sadmacit always talks about sets of them21:20
sadmacmounted(type: nfs, mountpoint: /) is a subset of mounted(type: nfs) is a subset of mounted()21:21
sadmacif you want a model for it, its awk21:22
sadmacpattern: transformation21:22
sadmacKeybuk: if you put filename: at the top of all your files, how does yours behave differently than mine?21:38
sadmacserious question.21:38
Keybukprobably in terms of such things as instancing21:38
sadmacyeah. that is it21:39
Keybuknot to mention arguments, which your system fundamentally relies on21:40
sadmac_Keybuk: what'd I miss? last thing I saw was last thing I said to you21:47
Keybuk<Keybuk> not to mention arguments, which your system fundamentally relies on21:47
=== sadmac_ is now known as sadmac
sadmacKeybuk: you don't have any arguments at all?21:47
Keybuklet me describe things as I see them21:51
Keybukyou define in files, or over D-Bus, services, tasks, states and other objects you would like Upstart to control21:52
Keybukas far as Upstart is concerned, these are all just different names for the same thing21:52
sadmacok21:52
Keybuklet's call them Objects for now21:52
Keybuk(to avoid any inference of behaviour from previous versions)21:53
sadmacsame so far. except I don't give them different names21:53
KeybukObjects have three basic attributes21:53
Keybuk - the condition in which they may be running21:53
Keybuk - an activation which starts them21:53
Keybuk - and what to do21:53
Keybuka fun fictional example that uses all three21:54
Keybuk  while apache221:54
Keybuk  on control-alt-delete21:54
Keybuk  exec echo "don't kill my web server" | wall21:54
sadmacok21:54
Keybukif an object has no condition, then it may be running at all times21:55
Keybukif an object has no activation, it will be activated as soon as the condition is true21:55
Keybukif an object has nothing to do, it is simply a state21:55
Keybuk  while apache221:55
Keybukis valid, except exceedingly pointless21:55
Keybuk  on control-alt-delete21:55
Keybuk  exec shutdown -r now21:55
Keybukis valid, it may be run at any time when control-alt-delete is pressed21:56
Keybuk  exec /sbin/udevd21:56
Keybukis valid, it defines a service that should always be running21:56
Keybukok so far?21:57
sadmacyes21:57
Keybukok, great21:57
KeybukObjects are just definitions21:57
KeybukInstances are the important thing21:58
Keybukwhen an Object is running, what we really mean is "there is an Instance of Object"21:58
Keybukwhen an Object is not running, what we really mean is "there are no Instances of Object"21:58
Keybukwhen I start apache2, I am not starting the apache2 Object, I am creating an Instance of the apache2 Object and starting that instance21:59
Keybuk(not quite true actually, but the definition suffices for now)21:59
sadmacok22:00
Keybukit would be more truthful to say that you start and stop an Instance of the apache2 Object - you don't create it22:00
KeybukObjects reference each other in their matches22:01
Keybukif an Instance of an Object is created, then an Instance of all Objects that reference it are created as well22:02
Keybukthat's a very complicated way of saying something very simple22:03
Keybukyou can have as many copies of apache2 running as you like22:03
Keybukand for each copy of apache2 that you run, you will get a second copy of everything that depends on apache2 as well22:03
sadmacwhat if you try to run something that depends on apache2 after that?22:03
KeybukUpstart only exposes *Instances*22:04
Keybukif there is something defined that depends on apache2, you will see two copies of it in the list22:04
Keybukso you'd inherently be picking which one you want to run (or probably both)22:04
Keybukand Upstart knows which apache2 instance each is linked to22:05
KeybukInstances have two additional attributes over Objects22:05
Keybuk - state (up or down)22:06
Keybuk - environment/properties (FOO=BAR)22:06
Keybukan Instance's environment is taken from the exported list of environment of Instances that created it - and optionally the sysadmin's own start command22:06
sadmachow do you prevent the rooting problem?22:07
Keybuk"the rooting problem" ?22:07
sadmacok, so you have fooservice which depends on barservice22:07
Keybukerr22:07
Keybukno I don't22:08
KeybukI can have fooservice which includes barservice in its condition22:08
sadmacok then22:08
KeybukI *very* explicitly avoided the term "depends on"22:08
Keybukfooservice is conditional on barservice? :p22:08
sadmac17:03 < Keybuk> and for each copy of apache2 that you run, you will get a second copy of everything that depends on apache2 as well22:08
sadmacdepends on22:08
sadmacgotcha!22:08
Keybukoh, damn22:08
Keybuk:p22:08
Keybukgot me22:08
KeybukI'm trying very hard not to call them jobs :p22:09
Keybukanyway22:09
Keybukthe rooting problem22:09
Keybukfooservice has while barservice in it22:09
sadmacok, so you have 2 copies of fooservice, and 2 copies of barservice (instances rather22:09
Keybukright22:10
sadmacnow bazservice comes along, and it has when fooservice, and when barservice22:10
sadmachow come you don't get 4 copies of it?22:10
Keybukok22:10
KeybukI'll talk this one through forwards22:11
Keybukwe have a barservice Object22:11
Keybukwe have a fooservice Object22:11
Keybukwe have a bazservice Object22:11
Keybukfooservice links to barservice22:11
Keybukbazservice links to fooservice and barservice22:11
Keybukright?22:12
Keybukwe create an instance of barservice22:12
sadmack22:12
Keybuklet's call it bar122:12
Keybukthis tracks back its links22:12
Keybukfooservice has a link, so we get a new instance "foo1" that links to bar122:12
Keybukbazservice has a link to fooservice, so we get a new instance "baz1" that links to "foo1" that links to "bar1"22:13
Keybukbazservice has a link to barservice, but there's already the baz1->bar1 instance22:13
Keybukso no instance needs to be created22:13
sadmacwhat ensures that order22:13
Keybuklet's create the second instance the other way22:13
Keybukwe create an instance of barservice "bar2"22:13
sadmacsuppose we evaluate "bazservice has a link to barservice" first?22:14
Keybukbazservice has a link to barservice, but its condition on fooservice is not yet met, so no instance is created22:14
Keybukfooservice has a link, so we get a new instance "foo2" that links to "bar2"22:15
Keybukbazservice has a link to fooservice, so we get a new instance "baz2" that links to "foo2" that links to "bar2"22:15
sadmacok, swap those last two:22:15
Keybukyou can't swap the last two22:15
Keybukit's a tree22:15
Keybuka -> b -> c22:16
sadmacwe have foo1, bar1, foo2, bar222:16
Keybuk -> c22:16
sadmacwe go to evaluate bazservice:22:16
Keybukwe don't "go to" do anything, we follow trees22:16
sadmacwhat's to keep bazservice from grabbing bar1, then foo222:16
Keybukwe have a tree22:16
sadmacoh, I get it now22:16
Keybuka -> b -> c22:17
Keybuk  -> c22:17
sadmacbut the deps aren't necessarily a tree22:17
sadmacin fact they aren't now22:17
Keybukthere are two valid ways to iterate that22:17
Keybuka, b, c, c22:17
Keybukor a, c, b, c22:17
Keybukeither way, c always ends up last ;)22:17
Keybukthey damned well are trees22:17
sadmacok, so consider only one foo1 and one bar122:17
sadmaccut the 2s22:17
Keybukok22:17
Keybukyou have22:18
sadmacso we have foo1->bar1, baz1->foo1, baz1->bar122:18
Keybukbar122:18
sadmactriangle22:18
Keybukfoo1->bar122:18
Keybukbaz1->foo1,bar122:18
sadmacthat's triangular22:18
sadmacthats not a tree22:18
Keybukno it's not?22:18
sadmacdraw it22:19
Keybuka -> b -> c22:19
Keybuk  -> c22:19
Keybukthat's a tree22:19
KeybukI can do it the other way too22:19
sadmacthose 2 cs are the same node22:19
Keybukc -> b -> a22:19
Keybuk     b -> a22:19
Keybuk          a22:19
Keybukthat's still a tree22:19
Keybukjust a baobab ;P22:19
sadmacno, it has a cycle22:19
Keybuksure22:20
Keybukit's a bit of a twisty tree ;)22:20
Keybukbut it's still a tree22:20
sadmacits not a tree22:20
sadmacits a directed graph22:20
Keybuk(actually it is a digraph because foo could depend on baz)22:21
Keybukbut we're not considering that case here :p22:21
sadmacdigraph is short for directed22:21
KeybukI know22:21
sadmacif you can start at any node and get to another by more than one route without backtracking its not a tree22:21
Keybukexxxxcept22:22
Keybukthat the only way to iterate it is as a tree22:22
Keybukit's self-breaking22:22
Keybukso while the mesh of objects is a digraph22:22
Keybukthe mesh of instances is a tree22:22
Keybukactually, it's more of a bag than anything else, but hey :p22:22
sadmacso it has an MST22:22
sadmacthat just makes it a graph22:22
sadmacand well connected22:22
Keybukso now we're finished arguing about terminology, you can see that it works? :p22:23
sadmacmore or less22:23
sadmacgo on22:23
Keybukwell, that's it really22:23
sadmacok22:24
sadmacmine actually doesn't have states the more I think about it.22:24
sadmacI keep wanting to call them that, but they're not22:24
Keybukyou can never end up with four copies of baz because the instances ref-count each other22:24
Keybukyou'd have two instances ref-counting the same instance22:24
Keybukand that's not allowed by model22:24
Keybukoh, one more thing22:25
Keybukyou can avoid inheriting instances22:25
Keybukso you only get one instance no matter how many instances of your parent there are22:25
Keybukbut in that case, you don't get any environment from them22:25
Keybuk  any <Object>22:26
Keybuka good example to all of the above is a D-Bus interface to Bind9 (replacing rndc?)22:27
sadmacright22:27
Keybuk  while dbus and bind922:27
Keybuk  exec /usr/sbin/bind9dbd22:27
Keybukyou get a copy for each dbus bus daemon you run and each bind9 bus daemon you run22:27
Keybukinterconnecting each of them22:27
Keybuk(dbus exports the session bus address, assumedly bind9 exports the socket address)22:28
Keybukif you had another service that depended on that and dbus22:28
Keybuk  while bind9dbd and dbus22:28
Keybukyou get a copy for each bind9dbd22:29
Keybukconnected to that dbus daemon22:29
Keybukit doesn't multiply22:29
Keybukin fact, in many cases, it gives you fewer than you might actually expect, but usually the number you need22:29
Keybukerr, sorry, you get a copy for each dbus connected to a bind9dbd on that dbus daemon22:30
Keybukhad that backwards22:30
sadmacsounds ok22:30
sadmacits actually more complicated than mine  XD22:31
Keybukit's far simpler to describe though22:31
Keybukwithout technical terms22:31
sadmacKeybuk: most of the difficulty is I've been insistent on calling them states and dealing with it in this way22:32
KeybukTo define your DNS service, create a file /etc/init/bind9 and in that put "exec /usr/sbin/bind9"22:32
sadmacKeybuk: I think I can explain it now22:32
Keybukif that DNS service may only be running during certain times, add "while blah and blah or blah" to that file22:32
sadmacKeybuk: so you have a computer on/under your desk, right?22:34
Keybukyes22:34
sadmacnow, there's a lot of things you could say about this computer. "Its fast" (kind of subjective) "Its purple" (maybe maybe not) etc.22:35
sadmacmy "state machine" manages statements like this22:35
sadmacwhen you configure it, you tell it what can and cannot be true. It then reads events and works out what is true.22:35
sadmac"Apache is running" implies that "The harddisk is mounted"22:36
Keybukhow do I run apache when the harddisk isn't mounted?22:36
sadmac"Apache is running" implies that "The harddisk is not mounted"22:37
sadmacnow obviously this is too verbose, so we allow shorthand22:37
Keybukno22:37
KeybukI mean22:37
KeybukI'm a sysadmin22:38
sadmacapache when not disk22:38
KeybukI have booted, and the hard disk failed to mount22:38
Keybukbut I need to start apache22:38
sadmacthe example is contrived22:38
Keybukhardly22:38
sadmacno I mean perhaps the rule is bad22:38
Keybukreplace apache with any other service that might normally be only running in a full multi-user condition but for which I might need22:38
Keybukhere's a good one22:38
Keybuksyslog22:39
KeybukI often need to start that one when debugging22:39
Keybukyour system *only* permits you to do the things the daemon allows22:39
Keybukthere's no separation22:39
sadmacKeybuk: my system is necessarily equivalent to yours22:39
sadmacits second order logic. you can define all of computing with it22:39
sadmacunless yours isn't a piece of software...22:40
Keybukwell, use my example then22:40
Keybukunless I'm mistaken, in order to have two dbus daemons, I would need to define two different dbus daemons22:40
sadmacno22:40
sadmacwell, that's getting ahead actually22:41
Keybukwell, dbus with two different possible arguments22:41
sadmacok, that's true22:41
Keybukthe point being, the person who wrote the dbus service has to allow, up front, the sysadmin to have multiple copies of it22:41
Keybukit's kinda like the 0.5 instance model22:42
Keybukthe service has to define the limits of instantiation22:42
sadmacwhy do you need 2 identical copies of the same service?22:42
Keybukchroot22:42
Keybuknamespace22:42
sadmac2 /identical/ copies22:42
Keybukno, you're missing my point22:42
Keybukyour system requires that the service define the ways in which they may be different22:43
sadmacyes22:43
sadmacwith the exception that they propagate their arguments22:43
Keybukif you want to allow dbus to be run on different bus addresses, the service has to, up-front, accept an argument to allow that22:43
sadmac(this is a recent change)22:43
sadmacso different deps yields a different service22:43
Keybukif you want to allow dbus to be run in different chroots, the service has to, up-front, accept an argument to allow that22:43
Keybukit all has to be up-front designed22:44
sadmacKeybuk: watch closely. this isn't far from possible:22:44
sadmac*(*): when namespace22:44
Keybukuse the chroot example?22:45
sadmacdbus: exec /usr/bin/dbus-daemon | us_set %bus_id22:45
Keybuk*(%chroot): chroot %chroot ?22:45
Keybukeverything takes a chroot argument that specifies its chroot?22:45
sadmacKeybuk: propagation has been made automatic now22:45
sadmacso no %s22:45
Keybukok22:46
Keybukso the dbus example22:46
Keybukthe bus_id is actually set by starting dbus22:46
sadmacright22:46
sadmacyou can see in the script how it works22:47
sadmac17:45 < sadmac> dbus: exec /usr/bin/dbus-daemon | us_set %bus_id22:47
Keybukhow do you create a second one?22:47
sadmacKeybuk: if you say start dbus, you get dbus(bus_id: deadbeef)22:47
sadmacif you say it again you get dbus(bus_id: feedface)22:48
Keybukso if I say start bind9, but there's a bind9 running22:48
Keybukhow does that *not* create another bind9?22:48
sadmacbecause bind9's script doesn't set any variables inside of it22:48
Keybukso it has to parse its own exec/script stuff to figure out whether it might set any variables?22:49
Keybukwhat happens if that just looks like:22:49
Keybuk  script22:49
sadmacKeybuk: it doesn't have to know ahead of time22:49
Keybuk    echo < FOO22:49
Keybukyou might want to use us_set %bus_id22:49
KeybukFOO22:49
Keybuk  end script22:49
Keybukyes it does22:49
sadmacnope22:49
Keybukit has to know *before* it starts bind9!22:49
sadmacno it doesn't22:49
Keybukit doesn't know that it shouldn't start another dbus-daemon until it's started it22:49
Keybukbecause it doesn't know what the value of that variable is until it's read the output22:49
Keybuktherefore it cannot know *not* to start bind9 either22:50
sadmacKeybuk: but it knows the first time a variable was set22:50
Keybukno it doesn't22:50
sadmacyes it does22:50
sadmacKeybuk: it attempted to start dbus(*)22:50
sadmacKeybuk: only dbus(bus_id: deadbeef) came up22:50
sadmacKeybuk: another (infinity-1) services didn't launch22:51
sadmacits worth trying again to launch one of them22:51
sadmacfoo(bar: baz) is a statement. A sentence22:54
sadmacIt reads "any thing foo such that bar = baz is true"22:55
sadmacif you also say foo22:55
sadmacit reads "any thing foo is true"22:55
sadmacif the second is true, the first must be by definition22:55
sadmacso if foo() is up, then foo(bar: baz) is up by definition, but the converse is /not/ true22:55
sadmacso for your bind9 example22:58
sadmacthe first one starts bind9()22:58
sadmacthe second one can't hope to start bind9(foo: bar), bind9(chicken: never), bind9(wibble: wobble) because these are /already true conditions/22:59
sadmacKeybuk: with me?22:59
Keybukyeah23:13
KeybukI still say your state machine is insanely complicated23:13
KeybukI prefer mine23:13
sadmacits logic23:22
sadmacits not hard23:22
sadmacplus the last 3 ways you got it wrong all would have yielded correct configuration files in most situations :D23:23
sadmacIn a way I agree that its complicated, but I think the user has to understand it less completely23:23
sadmacmost guesses will result in you operating it correctly23:23
sadmacplus implementing it is really nice23:24

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