]> andersk Git - moira.git/blob - incremental/afs/afs_create.pl
Retry volume releases three times, and don't treat a failure as fatal.
[moira.git] / incremental / afs / afs_create.pl
1 #!/usr/athena/bin/perl
2 # Usage: afs_create locker type cell path quota user group
3
4 require "/moira/bin/afs_utils.pl";
5
6 $protodir="/moira/dotfiles";
7 $quota=1;
8
9 %proc =
10     ("ATHENA.MIT.EDU", 'athena_proc' );
11
12 umask(0);
13
14 die "Usage: $0 locker type cell path user group\n" if (@ARGV != 6);
15 ($locker,$type,$cell,$path,$user,$group) = @ARGV;
16
17 # Lookup volume type
18 ($c = $cell) =~ s/\./_/g;
19 $vtype = eval "\$vtypes_${c}{$type}";
20 die "Cannot create $type volumes in $cell\n" unless $vtype;
21 $vname = $vtype . "." . $locker;
22 $vname =~ s/[^-A-Za-z0-9_.]//g;         # strip out illegal characters
23
24 # Find free space/Create volume
25 $tries = 0; $code = 1;
26 while ($tries<3 && $code) {
27     ($asrv,$apart) = &afs_find($cell,$type,$quota,@except);
28     die "Unable to find space to create $vname in $cell\n" unless ($asrv&&$apart);
29     $code = system("$vos create $asrv $apart $vname -cell $cell >/dev/null");
30     push(@except, $asrv);
31     $tries++;
32 }
33 &fatal("Unable to create $vname in $cell") if ($code); # Too many create errors
34 push(@clean, "$vos remove $asrv $apart $vname -cell $cell >/dev/null");
35
36 # Create mountpoint and set quota
37 $path =~ s:^/afs/([^.]):/afs/.\1:;
38 system("$fs checkv >/dev/null; $fs mkm $path $vname");
39 &fatal("Unable to create $path") if ($?);
40 push(@clean, "$fs rmm $path");
41
42 # Obtain user/group information (uid >= 0, gid <= 0)
43 $uid = $gid = 0;
44 open(PTS, "$pts ex $user -cell $cell|");
45 chop($_ = <PTS>);
46 close(PTS);
47 ($uid,$uid,$uid,$uid) = split(/[:,] /, $_) unless ($?);
48
49 open(PTS, "$pts ex system:$group -cell $cell|");
50 chop($_ = <PTS>);
51 close(PTS);
52 ($gid,$gid,$gid,$gid) = split(/[:,] /, $_) unless ($?);
53
54 # Dispatch to the cell-specific creation routines
55 eval "&$proc{$cell}";
56 &fatal($@) if ($@);
57
58 # Set the filesystem quota
59 system("$fs sq $path $quota");
60 &fatal("Unable to set the quota on $path") if ($?);
61
62 # Release the parent volume
63 ($p = $path) =~ s:/[^/]+$::;
64 open(FS, "$fs lv $p|") || &fatal("Can't get information about $p");
65 chop($_ = <FS>);
66 close(FS);
67 &fatal("Can't get information about $p") if ($?);
68 @tmp = (split(/ /,$_));
69 if ($tmp[$#tmp] !~ /user\../) {
70     $tries = 0; $code = 1;
71     while ($tries<3 && $code) {
72         $code = system("$vos release $tmp[$#tmp] -cell $cell >/dev/null");
73         $tries++;
74     }
75     warn "Couldn't release $tmp[$#tmp] in cell $cell" if ($code) # Don't treat as fatal.
76 }
77
78 # Update the quota records.
79 &afs_quota_adj($cell,$asrv,$apart,$quota,0);
80 exit(0);
81
82 sub fatal
83 {
84     local($cmd);
85     $_ = join(' ',@_);
86     s/\n$//;
87
88     while (@clean) {
89         $cmd = pop(@clean);
90         warn "$locker: Cleanup failed: $cmd\n" if (system("$cmd"));
91     }
92     die "$locker: $_\n";
93 }
94
95 # Cell specific procedures
96 sub athena_proc
97 {
98     # Default acls:
99     #
100     # ACTIVITY  <user> all <group> all system:anyuser rl
101     # APROJ     <user> all <group> all system:anyuser rl
102     # AREF      <user> all <group> rl
103     # CONTRIB   <user> all system:anyuser rl
104     # COURSE    <user> all <group> all system:facdev all system:authuser rl
105     # HOMEDIR   <user> all
106     # LEASE     <user> all
107     # ORG       <user> all <group> all system:cwisfac all system:anyuser rl
108     # PROJECT   <user> all <group> all
109     # REF       <user> all system:anyuser rl
110     # SW        <user> all system:swmaint all system:authuser rl
111     # SYSTEM    system:administrators all system:anyuser rl
112     # UROP      <user> all <group> all system:facdev all system:authuser rl
113     #
114     # Notes:
115     # 1. All directories also have "system:expunge ld".
116
117     @acl=("system:expunge ld");
118     push(@acl,"system:facdev all") if ($type =~ /^(COURSE|UROP)/);
119     push(@acl,"system:swmaint all") if ($type =~ /^(SW)/);
120     push(@acl,"system:cwisfac all") if ($type =~ /^(ORG)/);
121     push(@acl,"system:administrators all") if ($type =~ /^(SYSTEM)/);
122     push(@acl,"$user all")
123         if ($uid != 0 && $type =~ /^(ACTIVITY|APROJ|AREF|CONTRIB|COURSE|HOMEDIR|LEASE|ORG|PROJECT|REF|SW|UROP)/);
124     push(@acl,"system:$group all")
125         if ($gid != 0 && $type =~ /^(ACTIVITY|APROJ|COURSE|ORG|PROJECT|UROP)/);
126     push(@acl,"system:$group rl") if ($gid != 0 && $type =~ /^(AREF)/);
127     push(@acl,"system:authuser rl")
128         if ($type =~ /^(COURSE|SW|UROP)/);
129     push(@acl,"system:anyuser rl")
130         if ($type =~ /^(ACTIVITY|APROJ|CONTRIB|ORG|REF|SYSTEM)/);
131
132     if ($type !~ /^(AREF|ORG|SYSTEM)/) {
133         system("$vos backup $vname >/dev/null");
134         system("$fs mkm $path/OldFiles $vname.backup");
135         warn "$locker: Unable to create OldFiles mountpoint\n" if ($?);
136     }
137
138     if ($type =~ /ACTIVITY|APROJ|PROJECT/) {
139         system("/moira/bin/uchown $path $gid");
140         die "Unable to set volume ownership\n" if ($?);
141     } elsif ($type =~ /HOMEDIR|UROP/) {
142         chown($uid,0,$path) ||
143             die "Unable to set volume ownership\n";
144     }
145
146     if ($type eq "COURSE") {
147         mkdir("$path/www",0755) &&
148             chown(0,0,"$path/www") ||
149                 die "Unable to create subdirectories\n";
150         system("$fs sa $path/www @acl system:anyuser rl -clear") &&
151             die "Unable to set acl on www directory\n";
152
153         system("$fs sa $path @acl system:anyuser l -clear") &&
154             die "Unable to set acl on top-level directory\n";
155         return;
156     }
157
158     if ($type eq "HOMEDIR") {
159         die "Unable to get uid for user\n" unless ($uid);
160
161         chmod(0755, $path);
162         mkdir("$path/Public",0755) && mkdir("$path/www",0755) &&
163             mkdir("$path/Private",0700) && mkdir("$path/Mail", 0700) &&
164                 chown($uid,0,"$path/Public","$path/www",
165                       "$path/Private","$path/Mail") ||
166                           die "Unable to create subdirectories\n";
167         system("$fs sa -dir $path/Public $path/www -acl @acl system:anyuser rl -clear") &&
168             die "Unable to set acl on Public directory";
169         system("$fs sa -dir $path/Private $path/Mail -acl @acl -clear") &&
170             die "Unable to set acl on Private and/or Mail directories\n";
171
172         opendir(DIR,$protodir) || die "Unable to open prototype directory\n";
173         @files=readdir(DIR);
174         closedir(DIR);
175
176         for $i (@files) {
177             next if ($i eq "." || $i eq "..");
178             next unless -f "$protodir/$i";
179             open(IN,"<$protodir/$i") || die "Unable to open $protodir/$i\n";
180             open(OUT,">$path/$i") || die "Unable to create $i\n";
181             while ($_=<IN>) { print OUT $_; };
182             close(OUT);
183             close(IN);
184             chown($uid,0,"$path/$i");
185         }
186         system("$fs sa $path @acl system:anyuser l -clear") &&
187             die "Unable to set acl on top-level directory\n";
188         return;
189     }
190
191     system("$fs sa $path @acl -clear") &&
192         die "Unable to set acl of $path\n";
193 }
This page took 0.051405 seconds and 5 git commands to generate.