5.3.12
[infrastructure.git] / scripts / need-review / alpha-repo.py
1 #!/usr/bin/python
2 # $Id$
3 # expected argument is a URL on build.onelab.eu
4 # this would then update the alpha node repo from that place
5 # NOTE
6 # the actual list of rpms that are needed or nodes is hard-coded
7
8 import sys, os, os.path, glob, commands
9 from optparse import OptionParser
10
11 standard_repo = '/var/www/html/install-rpms/onelab-i386'
12 alpha_repo = '%s-alpha'%standard_repo
13
14 #################### from module-tools
15 def prompt (question,default=True):
16     
17     choices = []
18     if default is True: choices.append('[y]')
19     else : choices.append('y')
20     if default is False: choices.append('[n]')
21     else : choices.append('n')
22
23     try:
24         answer=raw_input(question + " " + "/".join(choices) + " ? ")
25         if not answer:
26             return default
27         answer=answer[0].lower()
28         if answer == 'y':
29             return True
30         elif answer == 'n':
31             return False
32         return prompt(question,default)
33     except:
34         raise
35
36 ##########
37 def run (command,options,force=False):
38     if ( force or not options.dry_run):
39         print 'Running',command
40         os.system(command)
41     else:
42         print 'Would run',command
43
44 # rewrite the http part into a rsync part
45 def http_to_rsync (http):
46     result = http.replace ('http://build.onelab.eu/','root@build.onelab.eu:/build/')
47     # canonicalize : strip last / if present
48     while (result[-1]=='/'): result=result[0:-1]
49     return result
50
51 def rsync_xfer(http,repo,options):
52     xfer='%s/xfer'%repo
53     command='mkdir -p %s' % xfer
54     run(command,options)
55
56     command='rsync -av'
57     if options.dry_run: command += ' -n'
58     command += ' ' + http_to_rsync(http) +  ' ' + xfer
59     run (command,options)
60
61 def rpm_name (rpm_file):
62     status,output = commands.getstatusoutput("rpm -q --qf '%%{NAME}' -p %s " % rpm_file)
63     return output
64
65 def extract_contents (standard):
66     patt= '%s/*.rpm' % standard 
67     rpm_files=glob.glob(patt)
68     contents = [ rpm_name(rpm_file) for rpm_file in rpm_files]
69     return contents
70
71 def install_standard_rpm_name (repo,rpm_name,options):
72     former_alpha_rpms = set(glob.glob ('%s/%s*rpm'%(repo,rpm_name)))
73     xfer_patt= '%s/xfer/RPMS/*/%s*.rpm' % (repo, rpm_name);
74     xfer_rpm_names=glob.glob(xfer_patt)
75     for xfer_rpm_name in xfer_rpm_names:
76         command = 'mv %s %s' % ( xfer_rpm_name, repo)
77         if prompt('Adopt %s'%os.path.basename(xfer_rpm_name)):
78             run(command,options)
79             try:
80                 former_alpha_rpms.remove('%s/%s'%(repo,rpm_name))
81             except:
82                 pass
83     for former in former_alpha_rpms:
84         if prompt ('Remove old %s'%os.path.basename(former)):
85             command.run("rm %s"%former,options)
86
87 def remaining_rpms (root):
88     command="find %s -name '*.rpm'"%root
89     status,output = commands.getstatusoutput(command)
90     return output.split("\n")
91
92 def scan_remaining (repo,options):
93     for rpm in remaining_rpms('%s/xfer' % repo):
94         basename=os.path.basename(rpm)
95         command="mv %s %s/%s"%(rpm,repo,basename)
96         if prompt('Adopt %s'%basename,False):
97             run (command,options)
98
99 def main ():
100     usage="Usage:%prog http://build.onelab.eu/.../RPMS"
101     parser=OptionParser(usage=usage)
102     parser.add_option("-n","--dry-run",action="store_true",dest="dry_run",default=False,
103                       help="dry run") 
104     parser.add_option("-r","--repo",action="store",dest="repo",default=alpha_repo,
105                       help="the repo to populate")
106     parser.add_option("-s","--std",action="store",dest="standard",default=standard_repo,
107                       help="the standard repo, used to compute the set of rpms")
108     (options, args) = parser.parse_args()
109     if len(args) != 1:
110         parser.print_help()
111         sys.exit(1)
112
113     http=args[0]
114     repo=options.repo
115     standard=options.standard
116
117     ### in case we have leftovers from a previous run days ago, better clean it up
118     xfer='%s/xfer'%repo
119     if os.path.isdir(xfer):
120         if prompt('Want to clean up %s'%xfer,False):
121             run('rm -rf %s'%xfer,options)
122
123     # go get the stuff
124     if prompt ('Need to fetch rpms from %s ' % http):
125         rsync_xfer(http,repo,options)
126     
127     # install yumgroups
128     if prompt ('Install yumgroups'):
129         command="mv %s/xfer/RPMS/yumgroups.xml %s/"%(repo,repo)
130         run(command,options)
131
132     # compute the set of rpms currently in the standard repo
133     # i.e. the ones that come with noderepo
134     if prompt ('Get list of standard rpms from %s ' % standard):
135         rpm_names=extract_contents(standard)
136
137     # interactively propose to move them in the right place
138     if prompt ('Moving standard rpms to %s' % repo):
139         for rpm_name in rpm_names:
140             install_standard_rpm_name(repo,rpm_name,options)
141
142     # once here, we have moved all the rpms that belonged to the standard noderepo
143     # let's manually scan the ones that remain in xfer/
144     # as there might be new rpms in this new build
145     # the list proposed here contains mostly server-side rpms, 
146     # so the prompt default is False
147     if prompt ('Scan remaining rpms for double-check'):
148         scan_remaining(repo,options)
149
150     if prompt ('Nuke repodata (force complete reindexing)'):
151         command="rm -rf %s/repodata %s/signed-stamps"%(repo,repo)
152         run(command,options)
153
154     if prompt ('Reindex'):
155         run('service plc start packages',options)
156
157 if __name__ == '__main__':
158     main()