Skip to content
  • Leigh B. Stoller's avatar
    Here is a checkpoint of the admission control stuff I have been working on. · 54f55585
    Leigh B. Stoller authored
    The last part is the stuff to hook it in from assign_wrapper, and some
    additional support in assign that Rob is adding for me. This comment is
    from the top of new file db/libadminctrl.pm.in and describes everything in
    detail.
    
    # Admission control policies. These are the ones I could think of, although
    # not all of these are implemented.
    #
    #  * Number of experiments per type/class (only one expt using robots).
    #
    #  * Number of experiments per project
    #  * Number of experiments per subgroup
    #  * Number of experiments per user
    #
    #  * Number of nodes per project      (nodes really means pc testnodes)
    #  * Number of nodes per subgroup
    #  * Number of nodes per user
    #
    #  * Number of nodes of a class per project
    #  * Number of nodes of a class per group
    #  * Number of nodes of a class per user
    #
    #  * Number of nodes of a type per project
    #  * Number of nodes of a type per group
    #  * Number of nodes of a type per user
    #
    #  * Number of nodes with attribute(s) per project
    #  * Number of nodes with attribute(s) per group
    #  * Number of nodes with attribute(s) per user
    #
    # So we have group (pid/gid) policies and user policies. These are stored
    # into two different tables, group_policies and user_policies, indexed in
    # the obvious manner. Each row of the table defines a count (experiments,
    # nodes, etc) and a type of thing being counted (experiments, nodes, types,
    # classes, etc). When we test for admission, we look for each matching row
    # and test each condition. All conditions must pass. No conditions means a
    # pass. There is also some "auxdata" which holds extra information needed
    # for the policy (say, the type of node being restricted).
    #
    #      uid:     a uid
    #   policy:     'experiments', 'nodes', 'type', 'class', 'attribute'
    #    count:     a number
    #  auxdata:     a string (optional)
    #
    # Example: A user policy of ('mike', 'nodes', 10) says that poor mike is
    # not allowed to have more 10 nodes at a time, while ('mike', 'type',
    # '10', 'pc850') says that mike cannot allocate more than 10 pc850s.
    #
    # The group_policies table:
    #
    #      pid:     a pid
    #      gid:     a gid
    #   policy:     'experiments', 'nodes', 'type', 'class', 'attribute'
    #    count:     a number
    #  auxdata:     a string (optional)
    #
    # Example: A project policy of ('testbed', 'testbed', 'experiments', 10)
    # says that the testbed project may not have more then 10 experiments
    # swapped in at a time, while ('testbed', 'TG1', 'nodes', 10) says that the
    # TG1 subgroup of the testbed project may not use more than 10 nodes at
    # time.
    #
    # In addition to group and user policies (which are policies that apply to
    # specific users/projects/subgroups), we also need policies that apply to
    # all users/projects/subgroups (ie: do not want to specify a particular
    # restriction for every user!). To indicate such a policy, we use a special
    # tag in the tables (for the user or pid/gid):
    #
    #      '+'  -  The policy applies to all users (or project/groups).
    #
    # Example: ('+','experiments',10) says that no user may have more then 10
    # experiments swapped in at a time. The rule overrides anything more
    # specific (say a particular user is restricted to 20 experiments; the above
    # rule overrides that and the user (all users) is restricted to 10.
    #
    # Sometimes, you want one of these special rules to apply to everyone, but
    # *allow* it to be overridden by a more specific rule. For that we use:
    #
    #      '-'  -  The policy applies to all users (or project/groups),
    #              but can be overridden by a more specific rule.
    #
    # Example: The rules:
    #
    #	('-','type',0, 'garcia')
    #       ('testbed', 'testbed', 'type', 10, 'garcia')
    #
    # says that no one is allowed to allocate garcias, unless there is specific
    # rule that allows it; in this case the testbed project can allocate them.
    #
    # There are other global policies we would like to enforce. For example,
    # "only one experiment can be using the robot testbed." Encoding this kind
    # of policy is harder, and leads down a path that can get arbitrarily
    # complex. Tha path leads to ruination, and so we want to avoid it at
    # all costs.
    #
    # Instead we define a simple global policies table that applies to all
    # experiments currently active on the testbed:
    #
    #   policy:     'nodes', 'type', 'class', 'attribute'
    #     test:     'max', others I cannot think of right now ...
    #    count:     a number
    #  auxdata:     a string
    #
    # Example: A global policy of ('nodes', 'max', 10, '') say that the maximum
    # number of nodes that may be allocated across the testbed is 10. Thats not
    # a very realistic policy of course, but ('type', 'max', 1, 'garcia') says
    # that a max of one garcia can be allocated across the testbed, which
    # effectively means only one experiment will be able to use them at once.
    # This is of course very weak, but I want to step back and give it some
    # more thought before I redo this part.
    #
    # Is that clear? Hope so, cause it gets more complicated. Some admission
    # control tests can be done early in the swap phase, before we really do
    # anything (before assign_wrapper). Others (type and class) tests cannot
    # be done here; only assign can figure out how an experiment is going to map
    # to physical nodes (remember virtual types too), and in that case we need
    # to tell assign what the "constraints" are and let it figure out what is
    # possible.
    #
    # So, in addition to the simple checks we can do, we also generate an array
    # to return to assign_wrapper with the maximum counts of each node type and
    # class that is limited by the policies. assign_wrapper will dump those
    # values into the ptop file so that assign can enforce those maximum values
    # regardless of what hardware is actually available to use. As per discussion
    # with Rob, that will look like:
    #
    #	set-type-limit <type> <limit>
    #
    # and assign will spit out a new type of violation that assign_wrapper will
    # parse.
    #
    # NOTES:
    #
    #  1) Admission control is skipped in admin mode; returns okay.
    #  2) Admission control is skipped when the pid is emulab-ops; returns okay.
    #  3) When calculating current usage, nodes reserved to emulab-ops are
    #     ignored.
    #  4) The sitevar "swap/use_admission_control" controls the use of admission
    #     control; defaults to 1 (on).
    #  5) The current policies can be viewed in the web interface. See
    #     https://www.emulab.net/showpolicies.php3
    #  6) The global policy stuff is weak. I plan to step back and think about it
    #     some more before redoing it, but it will tide us over for now.
    #
    54f55585