This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
wiki:some_examples_of_admission_rules [2017/05/10 10:49] – [Example 5:] neyron | wiki:some_examples_of_admission_rules [2020/04/07 21:52] – [Example 5: verify correct resources definitions] neyron | ||
---|---|---|---|
Line 138: | Line 138: | ||
</ | </ | ||
- | ==== Example 4: | + | ==== Example 4: limit access to a queue, based on usernames set in a file ==== |
- | + | ||
- | Limit access to a queue, based on usernames set in a file | + | |
==Answer== | ==Answer== | ||
Line 163: | Line 161: | ||
- | ==== Example 5: ==== | + | ==== Example 5: give a more privilege to the owners of nodes ==== |
Give a more privilege to the owners of nodes (e.g. people who payed for the nodes) to submit, by restricting others to besteffort jobs: | Give a more privilege to the owners of nodes (e.g. people who payed for the nodes) to submit, by restricting others to besteffort jobs: | ||
* non-owners compete on the resources according to the scheduling policy of the besteffort queue ; | * non-owners compete on the resources according to the scheduling policy of the besteffort queue ; | ||
Line 169: | Line 167: | ||
==Answer== | ==Answer== | ||
- | * First add a property to resources: // | + | * First add a property to resources: // |
* Then add an admission rule which describes the team list with regard to unix users and groups. | * Then add an admission rule which describes the team list with regard to unix users and groups. | ||
- | * Non-besteffort jobs will automatically bound to resources set with // | + | * Non-besteffort jobs will automatically bound to resources set with // |
* Besteffort jobs do not have constraints: | * Besteffort jobs do not have constraints: | ||
<code perl> | <code perl> | ||
- | # Description : set dedicated property | + | # Description : set dedicated property |
my @projects; | my @projects; | ||
Line 186: | Line 184: | ||
push(@projects, | push(@projects, | ||
- | my $dedicated_none | + | my $jobaddedprop |
- | my $user_in_one_group | + | |
- | foreach my $project (@projects) { | + | # original : IGRIDA admission rule |
- | my @members; | + | # modified : nef @ Inria Sophia |
- | foreach (@{$project-> | + | |
- | my $gr; | + | if (!(grep(/ |
- | (undef, | + | # Any user can run besteffort jobs on any resource : |
- | my @group_members = split(/ | + | # no additional verification, |
- | push(@members, | + | |
- | } | + | # Search for projects to which the user belongs |
- | | + | |
- | my %h = map { $_ => 1 } @members; | + | my @members; |
- | if ( $h{$user} eq 1 ) { | + | foreach (@{$project-> |
- | if (!(grep(/ | + | my $gr; |
- | $jobproperties = " | + | (undef, |
- | print(" | + | my @group_members = split(/ |
- | $user_in_one_group = 1; | + | # |
+ | push(@members, | ||
} | } | ||
- | | + | push(@members, |
- | if (!(grep(/ | + | my %h = map { $_ => 1 } @members; |
- | $dedicated_none | + | |
- | } | + | if ( $h{$user} eq 1 ) { |
- | if ((grep(/ | + | |
- | die(" | + | $jobaddedprop .= " OR dedicated=\' |
+ | } else { | ||
+ | if ((grep(/ | ||
+ | die(" | ||
+ | } | ||
} | } | ||
} | } | ||
- | } | ||
- | if (($dedicated_none | + | |
- | if (!(grep(/^besteffort/, @{$type_list}))) { | + | |
- | $jobproperties = " | + | # Always need to limit request to permitted nodes |
+ | if ($queue_name ne " | ||
+ | if (grep(/\S/, $jobproperties)) { | ||
+ | $jobproperties = " | ||
+ | } else { | ||
+ | $jobproperties | ||
+ | } | ||
+ | print(" | ||
} | } | ||
+ | |||
} | } | ||
</ | </ | ||
Line 224: | Line 233: | ||
That set up: | That set up: | ||
* For a user of team ' | * For a user of team ' | ||
- | * => property set: '' | + | * => property set: '' |
- | * That user can also use non dedicated nodes: '' | + | * That user can also force use of dedicated nodes only: '' |
- | * => property set: '' | + | * => property set: '' |
- | * For a user that does not belong to a team which owns nodes1: '' | + | * For a user of teams ' |
- | * => property set: '' | + | * => property set: '' |
+ | * For a user that does not belong to a team which owns nodes: '' | ||
+ | * => property set: '' | ||
* And for that user: '' | * And for that user: '' | ||
* => '' | * => '' | ||
* But with: '' | * But with: '' | ||
- | (Note that there are some known limitations in that property filtering, which could allow malicious users to overcome the usage policy) | + | (There may be some limitations in that property filtering, which could allow malicious users to overcome the usage policy) |
+ | ==== Example 5: verify correct resources definitions ==== | ||
+ | |||
+ | Verify that the < | ||
+ | |||
+ | OAR resource request hierarchies are implicit in the OAR database, but they can be enforced by an admission rule. | ||
+ | |||
+ | Lets assume that valid resources hierarchies are: | ||
+ | |||
+ | * switch > cluster > host > cpu > gpu > core | ||
+ | * cluster > switch > host > cpu > gpu > core | ||
+ | * cluster > switch > host > disk | ||
+ | * switch > cluster > host > disk | ||
+ | * license | ||
+ | |||
+ | Here both switch > cluster, or cluster > switch can be valid (some clusters spread their nodes on many switches, some clusters share a same switch). Disks are special resources to reserve disks on hosts, independently from cpu, gpu and cores. Licenses are yet a completly independente type of resources. | ||
+ | |||
+ | Any of those resources properties can define a valid hierarchy or resources, for instance: | ||
+ | * < | ||
+ | * → get 2 cores on different switches | ||
+ | * < | ||
+ | * → get 2 disks of 2 different hosts but on a same cluster | ||
+ | * < | ||
+ | * → get 1 license | ||
+ | |||
+ | But incorrect hierachry should raise an error: | ||
+ | * oarsub -l gpu=1/ | ||
+ | * → cannot get 2 hosts for a same gpu | ||
+ | * oarsub -l host=1/ | ||
+ | * → cannot mix disk and core | ||
+ | |||
+ | ==Answer== | ||
+ | |||
+ | <code perl> | ||
+ | |||
+ | # definition of the valid implicit hierarchies of resources. | ||
+ | my %valid_children = ( | ||
+ | # both cluster > switch and switch > cluster are relevant | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | |||
+ | # nodes is synonym of host | ||
+ | my %aliases = ( | ||
+ | " | ||
+ | ); | ||
+ | |||
+ | # valid values are in one of the possible hierarchies | ||
+ | my %valid_resources; | ||
+ | foreach my $key (keys %valid_children) { | ||
+ | $valid_resources{$key} = undef; | ||
+ | foreach my $child (@{%valid_children{$key}}) { | ||
+ | $valid_resources{$child} = undef; | ||
+ | } | ||
+ | } | ||
+ | my @valid_resources = keys %valid_resources; | ||
+ | |||
+ | # test the user's request for possible errors | ||
+ | foreach my $mold (@{$ref_resource_list}) { # loop on all moldable resources requests (oarsub -l ... -l ...) | ||
+ | foreach my $r (@{$mold-> | ||
+ | my @resources_hierarchy; | ||
+ | my $parent_resource; | ||
+ | foreach my $h (@{$r-> | ||
+ | if(!grep { $_ eq $h-> | ||
+ | die(" | ||
+ | } | ||
+ | if (!grep { $_ eq $h-> | ||
+ | push @resources_hierarchy, | ||
+ | } else { | ||
+ | # catching the case `oarsub -l / | ||
+ | push @resources_hierarchy, | ||
+ | die(" | ||
+ | } | ||
+ | if (defined($parent_resource)) { | ||
+ | if (!grep { $_ eq $h-> | ||
+ | die(" | ||
+ | } | ||
+ | } | ||
+ | if (exists $aliases{$h-> | ||
+ | $parent_resource = $aliases{$h-> | ||
+ | } else { | ||
+ | $parent_resource = $h-> | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ |