2 # Marta Carbone - UniPi
5 # This class requires the rpm package containing
6 # the picobsd image to be installed
7 # on the Central Site system.
14 from PLC.Faults import * # faults library
15 from PLC.Method import Method # base class for methods
16 from PLC.Parameter import Parameter # use the Parameter wrapper
17 from PLC.Auth import Auth # import the Auth parameter
18 from PLC.DummyBoxes import DummyBox, DummyBoxes # main class for a DummyBox
19 from PLC.Methods.GetBootMedium import compute_key # key generation function
21 WORK_DIR = "/var/tmp/DummynetBoxMedium"
22 BASE_IMAGE = "/usr/share/dummynet/picobsd.bin"
24 class GetDummyBoxMedium(Method):
26 This method is used to get a boot image of the DummyNetBox
27 equipped with the configuration file.
29 We need to provide the dummybox_id of the DummyNetBox
31 Since every time a new configuration file will be generater,
32 THIS OPERATION WILL INVALIDATE ANY PREVIOUSLY DUMMYNETBOX BOOT MEDIUM.
33 # XXX add checks for picobsd.bin existence
35 Returns the iso image customized for the DummyNetBox with the new
36 key integrated in the image, and update the key fields in the database.
38 # I added the session role, because this method should be called from the web
39 roles = ['admin', 'pi', 'tech', 'session']
43 Parameter(int, "A dummybox_id")
46 returns = Parameter(str, "DummynetBox boot medium")
48 # Generate a new configuration file in the working directory
49 # input parameters follows:
50 # self is used to access instance data,
51 # dummybox is the dummybox_id,
52 # new_key is the new generated key,
53 # configfile is the output file of the configuration.
54 def generate_conf_file(self, dummybox, new_key, configfile):
56 # Generate the dummynet box configuration file
57 today = datetime.date.today()
59 file += "# This is the dummynetbox configuration file\n"
60 file += "# and was generated the %s\n" % str(today)
62 host_domain = dummybox['hostname']
63 host_domain = host_domain.split('.', 1)
64 file += 'HOST_NAME="%s"\n' % host_domain[0]
65 file += 'DOMAIN_NAME="%s"\n' % host_domain[1]
67 file += 'IP_ADDRESS="%s"\n' % dummybox['ip']
68 file += 'IP_NETMASK="%s"\n' % dummybox['netmask']
69 file += 'IP_GATEWAY="%s"\n' % dummybox['gateway']
70 file += 'IP_DNS1="%s"\n' % dummybox['dns1']
71 file += 'IP_DNS2="%s"\n' % dummybox['dns2']
72 file += 'DUMMYBOX_ID="%s"\n' % dummybox['dummybox_id']
73 file += 'DUMMYBOX_KEY="%s"\n' % new_key
75 file += 'CS_IP="%s"\n' % self.api.config.PLC_API_HOST
77 # write the configuration file
78 # WORK_DIR must be writable
79 FILE = open(configfile, "w")
85 # Here starts the execution of the call
86 def call(self, auth, dummybox_id):
88 # Check for dummybox existence
89 dummyboxes = DummyBoxes(self.api, [dummybox_id])
91 raise PLCInvalidArgument, "No such DummyBox %s" % dummybox_id
93 dummybox = dummyboxes[0]
95 # Get the dummynet box hostname
96 dummybox_hostname = dummybox['hostname']
97 IMAGE_NAME = str(WORK_DIR) + "/dummybox_" + dummybox_hostname + ".bin"
98 configfile = WORK_DIR + '/dummybox.conf'
99 lockfile = WORK_DIR + '/lockfile'
102 assert self.caller is not None
103 if 'admin' not in self.caller['roles']:
104 if dummybox['site_id'] not in self.caller['site_ids']:
105 raise PLCPermissionDenied, "Not allowed to generate an iso image for %s %s" % \
106 (dummybox['hostname'], dummybox_id)
108 # Start the generation of the image
110 new_key = compute_key()
112 # create working dir and lock file for concurrent runs
113 if not os.path.exists(WORK_DIR):
114 print "Creating working directory %s" % WORK_DIR
117 if os.path.exists(lockfile):
118 raise PLCInvalidArgument, "Lockfile %s exist, try again " % lockfile
120 print "Executing "+"touch %s" % lockfile
121 os.system("touch %s" % lockfile)
123 # generate the configuration file
124 conf_file = self.generate_conf_file(dummybox, new_key, configfile)
126 # build the shell script to customize the dummynetbox image
127 # copy the raw file and find the configuration file position
128 shell_script = "(cp %s %s; export MATCH=`grep -abo START_USER_DATA %s | cut -d: -f1`; " \
129 % (BASE_IMAGE, IMAGE_NAME, IMAGE_NAME)
131 # cat the configuration file in the raw image
132 shell_script += "cat %s | dd of=%s seek=$MATCH conv=notrunc bs=1)" \
133 % (configfile, IMAGE_NAME)
135 # check returned values, 0 means OK, remove the lock file
136 os.system(shell_script)
137 os.system("rm %s" % (lockfile))
139 # if all goes fine store the key in the database
140 dummybox['key'] = new_key
145 return base64.b64encode(file(IMAGE_NAME).read())