Detangled steps. No step makes calls into another step.
[bootmanager.git] / source / steps / InstallBootstrapRPM.py
1 #!/usr/bin/python2
2
3 # Copyright (c) 2003 Intel Corporation
4 # All rights reserved.
5 #
6 # Copyright (c) 2004-2006 The Trustees of Princeton University
7 # All rights reserved.
8 # expected /proc/partitions format
9
10 import os, sys, string
11 import popen2
12 import shutil
13
14 from Exceptions import *
15 import utils
16 import BootServerRequest
17
18
19 def Run( vars, log ):
20     """
21     Download enough files to run rpm and yum from a chroot in
22     the system image directory
23     
24     Expect the following variables from the store:
25     SYSIMG_PATH          the path where the system image will be mounted
26     PARTITIONS           dictionary of generic part. types (root/swap)
27                          and their associated devices.
28     SUPPORT_FILE_DIR     directory on the boot servers containing
29                          scripts and support files
30     NODE_ID              the id of this machine
31     
32     Sets the following variables:
33     TEMP_BOOTCD_PATH     where the boot cd is remounted in the temp
34                          path
35     ROOT_MOUNTED         set to 1 when the the base logical volumes
36                          are mounted.
37     """
38
39     log.write( "\n\nStep: Install: Bootstrapping RPM.\n" )
40
41     # make sure we have the variables we need
42     try:
43         SYSIMG_PATH= vars["SYSIMG_PATH"]
44         if SYSIMG_PATH == "":
45             raise ValueError, "SYSIMG_PATH"
46
47         PARTITIONS= vars["PARTITIONS"]
48         if PARTITIONS == None:
49             raise ValueError, "PARTITIONS"
50
51         SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"]
52         if SUPPORT_FILE_DIR == None:
53             raise ValueError, "SUPPORT_FILE_DIR"
54
55         NODE_ID= vars["NODE_ID"]
56         if NODE_ID == "":
57             raise ValueError, "NODE_ID"
58
59     except KeyError, var:
60         raise BootManagerException, "Missing variable in vars: %s\n" % var
61     except ValueError, var:
62         raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
63
64
65     try:
66         # make sure the required partitions exist
67         val= PARTITIONS["root"]
68         val= PARTITIONS["swap"]
69         val= PARTITIONS["vservers"]
70     except KeyError, part:
71         log.write( "Missing partition in PARTITIONS: %s\n" % part )
72         return 0   
73
74     bs_request= BootServerRequest.BootServerRequest()
75     
76     log.write( "turning on swap space\n" )
77     utils.sysexec( "swapon %s" % PARTITIONS["swap"], log )
78
79     # make sure the sysimg dir is present
80     utils.makedirs( SYSIMG_PATH )
81
82     log.write( "mounting root file system\n" )
83     utils.sysexec( "mount -t ext3 %s %s" % (PARTITIONS["root"],SYSIMG_PATH), log )
84
85     log.write( "mounting vserver partition in root file system\n" )
86     utils.makedirs( SYSIMG_PATH + "/vservers" )
87     utils.sysexec( "mount -t ext3 %s %s/vservers" % (PARTITIONS["vservers"],
88                                                      SYSIMG_PATH), log )
89
90     vars['ROOT_MOUNTED']= 1
91     
92
93     # download and extract support tarball for
94     # this step, which has everything
95     # we need to successfully run
96     for step_support_file in [ "PlanetLab-Bootstrap.tar.bz2",
97                                "alpina-BootstrapRPM.tar.bz2" ]: 
98         source_file= "%s/%s" % (SUPPORT_FILE_DIR,step_support_file)
99         dest_file= "%s/%s" % (SYSIMG_PATH, step_support_file)
100
101         # 30 is the connect timeout, 7200 is the max transfer time
102         # in seconds (2 hours)
103         log.write( "downloading %s\n" % step_support_file )
104         result= bs_request.DownloadFile( source_file, None, None,
105                                          1, 1, dest_file,
106                                          30, 7200)
107         if result:
108             # New bootstrap tarball contains everything necessary to
109             # boot, no need to bootstrap further.
110             vars['SKIP_INSTALL_BASE']= (step_support_file == "PlanetLab-Bootstrap.tar.bz2")
111             break
112
113     if not result:
114         raise BootManagerException, "Unable to download %s from server." % \
115               source_file
116
117     log.write( "extracting %s in %s\n" % (dest_file,SYSIMG_PATH) )
118     result= utils.sysexec( "tar -C %s -xpjf %s" % (SYSIMG_PATH,dest_file), log )
119     utils.removefile( dest_file )
120
121     # copy resolv.conf from the base system into our temp dir
122     # so DNS lookups work correctly while we are chrooted
123     log.write( "Copying resolv.conf to temp dir\n" )
124     utils.sysexec( "cp /etc/resolv.conf %s/etc/" % SYSIMG_PATH, log )
125
126     # Copy the boot server certificate(s) and GPG public key to
127     # /usr/boot in the temp dir.
128     log.write( "Copying boot server certificates and public key\n" )
129
130     if os.path.exists("/usr/boot"):
131         utils.makedirs(SYSIMG_PATH + "/usr")
132         shutil.copytree("/usr/boot", SYSIMG_PATH + "/usr/boot")
133     elif os.path.exists("/usr/bootme"):
134         utils.makedirs(SYSIMG_PATH + "/usr/boot")
135         boot_server = file("/usr/bootme/BOOTSERVER").readline().strip()
136         shutil.copy("/usr/bootme/cacert/" + boot_server + "/cacert.pem",
137                     SYSIMG_PATH + "/usr/boot/cacert.pem")
138         file(SYSIMG_PATH + "/usr/boot/boot_server", "w").write(boot_server)
139         shutil.copy("/usr/bootme/pubring.gpg", SYSIMG_PATH + "/usr/boot/pubring.gpg")
140         
141     # For backward compatibility
142     if os.path.exists("/usr/bootme"):
143         utils.makedirs(SYSIMG_PATH + "/mnt/cdrom")
144         shutil.copytree("/usr/bootme", SYSIMG_PATH + "/mnt/cdrom/bootme")
145
146     # Import the GPG key into the RPM database so that RPMS can be verified
147     utils.makedirs(SYSIMG_PATH + "/etc/pki/rpm-gpg")
148     utils.sysexec("gpg --homedir=/root --export --armor" \
149                   " --no-default-keyring --keyring %s/usr/boot/pubring.gpg" \
150                   " >%s/etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab" % (SYSIMG_PATH, SYSIMG_PATH))
151     utils.sysexec("chroot %s rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab" % \
152                   SYSIMG_PATH)
153
154     return 1