[955] | 1 | #!/usr/bin/env python
|
---|
| 2 | # -*- coding: utf-8 -*-
|
---|
| 3 | #
|
---|
| 4 |
|
---|
| 5 | from PyQt4 import QtGui, QtCore
|
---|
| 6 | from PyQt4.QtCore import *
|
---|
| 7 | from PyQt4.QtGui import *
|
---|
| 8 |
|
---|
| 9 | import socket
|
---|
| 10 | import string
|
---|
| 11 | import random
|
---|
| 12 | import Ui_baseconfigwizard
|
---|
| 13 |
|
---|
| 14 |
|
---|
| 15 | from nosferatu import bacresources, prettynames, auto_types
|
---|
| 16 |
|
---|
| 17 |
|
---|
| 18 |
|
---|
| 19 | # TODO: move this into base_classes
|
---|
| 20 |
|
---|
| 21 |
|
---|
| 22 | # default values when creating a new resource
|
---|
| 23 | defaults = {
|
---|
| 24 | 'catalog' : 'MyCatalog',
|
---|
| 25 | 'messages': 'Standard',
|
---|
| 26 | 'type' : 'Backup',
|
---|
| 27 | 'piddirectory' : ['/var/run',
|
---|
| 28 | '/opt/bacula/working',
|
---|
| 29 | '"C:\\\\Program Files\\\\Bacula\\\\working"'],
|
---|
| 30 | 'workingdirectory' : ['/var/lib/bacula',
|
---|
| 31 | '/opt/bacula/working',
|
---|
| 32 | '"C:\\\\Program Files\\\\Bacula\\\\working"'],
|
---|
| 33 | 'queryfile' : [ '/usr/lib/bacula/query.sql',
|
---|
| 34 | '"/opt/bacula/scripts/query.sql"'],
|
---|
| 35 | 'type': auto_types.jobtypes,
|
---|
| 36 | 'level': auto_types.joblevels,
|
---|
| 37 |
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 |
|
---|
| 41 | class baseconfigwizard(QtGui.QWizard, Ui_baseconfigwizard.Ui_Wizard,):
|
---|
| 42 | '''
|
---|
| 43 | This wizard will do a base configuration of any bacula resource type.
|
---|
| 44 | It displays all required items of the given resource and configures them
|
---|
| 45 | If the configuration is successful, the resource will be given back,
|
---|
| 46 | else None
|
---|
| 47 | If the dirconfig is given, available resources are filled into
|
---|
| 48 | comboboxes (e.g. available filesets, etc)
|
---|
| 49 | '''
|
---|
| 50 |
|
---|
| 51 | def __init__(self, resource, dirconfig = None ,parent = None):
|
---|
| 52 | super(baseconfigwizard, self).__init__()
|
---|
| 53 | self.setupUi(self)
|
---|
| 54 | self.resource = resource
|
---|
| 55 | self.dirconfig = dirconfig
|
---|
| 56 |
|
---|
| 57 | print "got the following resource to configure: %s " % (resource)
|
---|
| 58 |
|
---|
| 59 |
|
---|
| 60 | self.groupBox.setTitle('basic configuration of a "%s" resource.' % (resource.resourcetype))
|
---|
| 61 | self.groupBox_2.setTitle('please provide the following information for the %s:' % (prettynames.PrettyNames[resource.resourcetype]))
|
---|
| 62 | introtext = "The following information has to be configured:\n"
|
---|
| 63 |
|
---|
| 64 | for item in resource.items:
|
---|
| 65 | if item.required:
|
---|
| 66 | introtext += resource.resourcetype + ' ' +item.name + '\n'
|
---|
| 67 |
|
---|
| 68 |
|
---|
| 69 | self.introtextEdit.setText(introtext)
|
---|
| 70 |
|
---|
| 71 | row = 0
|
---|
| 72 | for item in resource.items:
|
---|
| 73 | if item.required:
|
---|
| 74 |
|
---|
| 75 | if self.dirconfig is not None: # fill the defaults with the resource types found in the director config
|
---|
| 76 | for res in self.dirconfig.validresourcesset:
|
---|
| 77 | ressources = self.dirconfig.getResourcesListByResType(res)
|
---|
| 78 | for r in ressources:
|
---|
| 79 | #print r.items_dict['name'].storage.value
|
---|
| 80 | if not defaults.has_key(res):
|
---|
| 81 | defaults[res] = []
|
---|
| 82 | if type(defaults[res]) is list:
|
---|
| 83 | if not r.items_dict['name'].storage.value in set(defaults[res]):
|
---|
| 84 | defaults[res].append(r.items_dict['name'].storage.value)
|
---|
| 85 |
|
---|
| 86 |
|
---|
| 87 | # put the label
|
---|
| 88 | newlabel = QtGui.QLabel(self.scrollAreaWidgetContents)
|
---|
| 89 | #labeltext = prettynames.PrettyNames[resource.resourcetype] +' ' + prettynames.PrettyNames[item.name]
|
---|
| 90 | labeltext = prettynames.PrettyNames[item.name]
|
---|
| 91 | newlabel.setText(labeltext)
|
---|
| 92 | self.gridLayout_4.addWidget(newlabel, row, 0, 1, 1)
|
---|
| 93 |
|
---|
| 94 | # do we have default value information?
|
---|
| 95 | if defaults.has_key(item.name):
|
---|
| 96 | t = type(defaults[item.name])
|
---|
| 97 | if t is str:
|
---|
| 98 | newwidget = QtGui.QLineEdit(self.scrollAreaWidgetContents)
|
---|
| 99 | self.wizardPage2.registerField(item.name + '*', newwidget) # register all fields as "required"
|
---|
| 100 | newwidget.setText(defaults[item.name]) # set defaults
|
---|
| 101 |
|
---|
| 102 | elif t is list:
|
---|
| 103 | newwidget = QtGui.QComboBox(self.scrollAreaWidgetContents)
|
---|
| 104 | self.wizardPage2.registerField(item.name + '*', newwidget) # register all fields as "required"
|
---|
| 105 | newwidget.addItems(defaults[item.name])
|
---|
| 106 | newwidget.setEditable(True)
|
---|
| 107 | newwidget.setCurrentIndex(0)
|
---|
| 108 | #print defaults[item.name]
|
---|
| 109 |
|
---|
| 110 | else:
|
---|
| 111 | newwidget = QtGui.QLineEdit(self.scrollAreaWidgetContents)
|
---|
| 112 | self.wizardPage2.registerField(item.name + '*', newwidget) # register all fields as "required"
|
---|
| 113 | #self.wizardPage2.registerField(item.name + '*', newwidget) # register all fields as "required"
|
---|
| 114 |
|
---|
| 115 | self.gridLayout_4.addWidget(newwidget, row, 1, 1, 1) # add new widget (lineedit/combobox)
|
---|
| 116 | #self.wizardPage2.registerField(item.name + '*', newwidget) # register all fields as "required"
|
---|
| 117 |
|
---|
| 118 | if item.name == 'address':
|
---|
| 119 | newButton = QtGui.QPushButton(self.scrollAreaWidgetContents)
|
---|
| 120 | newButton.setText('check')
|
---|
| 121 | self.gridLayout_4.addWidget(newButton, row, 2, 1, 1)
|
---|
| 122 | self.addressLineEdit = newwidget
|
---|
| 123 | self.connect(newButton,
|
---|
| 124 | SIGNAL("clicked()"),
|
---|
| 125 | self.onaddrCheckButtonClicked
|
---|
| 126 | )
|
---|
| 127 |
|
---|
| 128 |
|
---|
| 129 | elif item.name == 'password':
|
---|
| 130 | newButton = QtGui.QPushButton(self.scrollAreaWidgetContents)
|
---|
| 131 | newButton.setText('generate')
|
---|
| 132 | self.gridLayout_4.addWidget(newButton, row, 2, 1, 1)
|
---|
| 133 | self.passwordLineEdit = newwidget
|
---|
| 134 | self.connect(newButton,
|
---|
| 135 | SIGNAL("clicked()"),
|
---|
| 136 | self.onpwgenPasswdClicked
|
---|
| 137 | )
|
---|
| 138 | row += 1
|
---|
| 139 |
|
---|
| 140 |
|
---|
| 141 |
|
---|
| 142 |
|
---|
| 143 |
|
---|
| 144 | def initializePage(self,pagenumber):
|
---|
| 145 | if pagenumber == 2:
|
---|
| 146 | for item in self.resource.items:
|
---|
| 147 | if item.required:
|
---|
| 148 | if defaults.has_key(item.name):
|
---|
| 149 | t = type(defaults[item.name])
|
---|
| 150 | if t is list:
|
---|
| 151 | #print "%s:%s" %(item.name, self.field(item.name))
|
---|
| 152 | idx,x = self.field(item.name).toInt()
|
---|
| 153 | #print item.name , self.field(item.name).toInt()
|
---|
| 154 | item.setValue(defaults[item.name][idx])
|
---|
| 155 | elif t is str:
|
---|
| 156 | item.setValue(str(self.field(item.name).toString()))
|
---|
| 157 | else:
|
---|
| 158 | #print item.name, self.field(item.name).toString()
|
---|
| 159 | item.setValue(str(self.field(item.name).toString()))
|
---|
| 160 |
|
---|
| 161 | self.previewtextEdit.setText(str(self.resource))
|
---|
| 162 |
|
---|
| 163 |
|
---|
| 164 |
|
---|
| 165 |
|
---|
| 166 | def onpwgenPasswdClicked(self):
|
---|
| 167 | self.passwordLineEdit.setText(bacresources.genPw(None,32))
|
---|
| 168 |
|
---|
| 169 | def onaddrCheckButtonClicked(self):
|
---|
| 170 | hostname = str(self.addressLineEdit.text())
|
---|
| 171 | ip = self.check_hostname(hostname)
|
---|
| 172 | if ip != None:
|
---|
| 173 | reply = QMessageBox.information(self,
|
---|
| 174 | "hostname OK",
|
---|
| 175 | "check successful: \n\n \"%s\" \n is at\n %s" % (hostname, ip) ,
|
---|
| 176 | QMessageBox.Ok)
|
---|
| 177 | else:
|
---|
| 178 | reply = QMessageBox.warning(self,
|
---|
| 179 | "hostname ERROR",
|
---|
| 180 | "\"%s\" can NOT be resolved!" % (hostname) ,
|
---|
| 181 | QMessageBox.Ok)
|
---|
| 182 |
|
---|
| 183 |
|
---|
| 184 | def check_hostname(self,hostname):
|
---|
| 185 | '''
|
---|
| 186 | try to resolve the given hostname
|
---|
| 187 | returns the IP or NONE if not resolvable
|
---|
| 188 | '''
|
---|
| 189 | if len(hostname) == 0:
|
---|
| 190 | return None
|
---|
| 191 | try:
|
---|
| 192 | ip = socket.gethostbyname(hostname)
|
---|
| 193 | return ip
|
---|
| 194 | except:
|
---|
| 195 | return None
|
---|
| 196 |
|
---|
| 197 |
|
---|
| 198 |
|
---|
| 199 |
|
---|
| 200 |
|
---|
| 201 |
|
---|
| 202 |
|
---|
| 203 | if __name__ == "__main__":
|
---|
| 204 | import sys
|
---|
| 205 | #def main():
|
---|
| 206 | print "started"
|
---|
| 207 | app = QtGui.QApplication(sys.argv)
|
---|
| 208 | app.setOrganizationDomain("dass-it.de")
|
---|
| 209 | app.setOrganizationName("dassIT GmbH")
|
---|
| 210 | app.setApplicationName("dassModus")
|
---|
| 211 | app.setWindowIcon(QIcon(":/icons/dassit_logo.png"))
|
---|
| 212 |
|
---|
| 213 |
|
---|
| 214 | # create a bacula director configuration
|
---|
| 215 | dirconf = bacresources.DirectorConfig('')
|
---|
| 216 | dirstring = '''
|
---|
| 217 | Director {
|
---|
| 218 | Name = gonzo-dir
|
---|
| 219 | Messages = Daemon
|
---|
| 220 | Password = "0DntXXl7DVkNYYRApYdhKKoy2Huq1CVHwIRAKUwgNA86"
|
---|
| 221 | Pid Directory = "/var/run"
|
---|
| 222 | Query File = "/usr/lib/bacula/query.sql"
|
---|
| 223 | VerID = " | configuration file created on :Thu Jun 17 16:30:45 2010"
|
---|
| 224 | Working Directory = "/var/lib/bacula"
|
---|
| 225 | }
|
---|
| 226 | JobDefs {
|
---|
| 227 | Name = "DefaultJob"
|
---|
| 228 | Client = gonzo-fd
|
---|
| 229 | Fileset = "Full Set"
|
---|
| 230 | Level = Incremental
|
---|
| 231 | Messages = Standard
|
---|
| 232 | Pool = Default
|
---|
| 233 | Schedule = "WeeklyCycle"
|
---|
| 234 | Storage = FileStorage
|
---|
| 235 | Type = Backup
|
---|
| 236 | }
|
---|
| 237 | Job {
|
---|
| 238 | Name = "BackupClient1"
|
---|
| 239 | JobDefs = "DefaultJob"
|
---|
| 240 | Write Bootstrap = "/var/lib/bacula/Client1.bsr"
|
---|
| 241 | }
|
---|
| 242 | Job {
|
---|
| 243 | Name = "BackupCatalog"
|
---|
| 244 | Fileset = "Catalog"
|
---|
| 245 | JobDefs = "DefaultJob"
|
---|
| 246 | Level = Full
|
---|
| 247 | Priority = 11
|
---|
| 248 | Run After Job = "/usr/lib/bacula/delete_catalog_backup"
|
---|
| 249 | Run Before Job = "/usr/lib/bacula/make_catalog_backup bacula bacula"
|
---|
| 250 | Schedule = "WeeklyCycleAfterBackup"
|
---|
| 251 | Write Bootstrap = "/var/lib/bacula/BackupCatalog.bsr"
|
---|
| 252 | }
|
---|
| 253 | Fileset {
|
---|
| 254 | Name = "Full Set"
|
---|
| 255 | Include {
|
---|
| 256 | File = /usr/sbin
|
---|
| 257 | Options {
|
---|
| 258 | Signature = MD5
|
---|
| 259 | }
|
---|
| 260 | }
|
---|
| 261 | Exclude {
|
---|
| 262 | File = /var/lib/bacula
|
---|
| 263 | File = /tmp
|
---|
| 264 | File = /proc
|
---|
| 265 | File = /tmp
|
---|
| 266 | File = /.journal
|
---|
| 267 | File = /.fsck
|
---|
| 268 | }
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | Fileset {
|
---|
| 272 | Name = "Full Set2"
|
---|
| 273 | Include {
|
---|
| 274 | File = /usr/sbin
|
---|
| 275 | Options {
|
---|
| 276 | Signature = MD5
|
---|
| 277 | }
|
---|
| 278 | }
|
---|
| 279 | Exclude {
|
---|
| 280 | File = /var/lib/bacula
|
---|
| 281 | File = /tmp
|
---|
| 282 | File = /proc
|
---|
| 283 | File = /tmp
|
---|
| 284 | File = /.journal
|
---|
| 285 | File = /.fsck
|
---|
| 286 | }
|
---|
| 287 | }
|
---|
| 288 |
|
---|
| 289 |
|
---|
| 290 | Schedule {
|
---|
| 291 | Name = "WeeklyCycle"
|
---|
| 292 | Run = Full 1st sun at 23:05
|
---|
| 293 | Run = Differential 2nd-5th sun at 23:05
|
---|
| 294 | Run = Incremental mon-sat at 23:05
|
---|
| 295 | }
|
---|
| 296 | Client {
|
---|
| 297 | Name = gonzo-fd
|
---|
| 298 | Address = localhost
|
---|
| 299 | Catalog = MyCatalog
|
---|
| 300 | File Retention = 30 days
|
---|
| 301 | Job Retention = 6 months
|
---|
| 302 | Password = "H/cjI5EOGYbiQ1jWb+1DSxQZc8VKncvt9GOuyDKQvE5E"
|
---|
| 303 | }
|
---|
| 304 | Client {
|
---|
| 305 | Name = second-client-fd
|
---|
| 306 | Address = localhost
|
---|
| 307 | Catalog = MyCatalog
|
---|
| 308 | File Retention = 30 days
|
---|
| 309 | Job Retention = 6 months
|
---|
| 310 | Password = "H/cjI5EOGYbiQ1jWb+1DSxQZc8VKncvt9GOuyDKQvE5E"
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 |
|
---|
| 314 | Storage {
|
---|
| 315 | Name = FileStorage
|
---|
| 316 | Address = localhost
|
---|
| 317 | Device = FileStorage
|
---|
| 318 | Media Type = FileStorage
|
---|
| 319 | Password = "/IUTExp+79Y0ipxZ5cZDq26Pp1Vcq5xI0bszHyTa4+TX"
|
---|
| 320 | }
|
---|
| 321 | Messages {
|
---|
| 322 | Name = Standard
|
---|
| 323 | Append = "/var/lib/bacula/log" = all, !skipped
|
---|
| 324 | Catalog = all
|
---|
| 325 | Console = all, !skipped, !saved
|
---|
| 326 | Mail = root@localhost = all, !skipped
|
---|
| 327 | Mail Command = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r"
|
---|
| 328 | Operator = root@localhost = mount
|
---|
| 329 | Operator Command = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | Pool {
|
---|
| 333 | Name = Default
|
---|
| 334 | Pool Type = Backup
|
---|
| 335 | Volume Retention = 365 days
|
---|
| 336 | }
|
---|
| 337 | Pool {
|
---|
| 338 | Name = Scratch
|
---|
| 339 | Pool Type = Backup
|
---|
| 340 | }
|
---|
| 341 |
|
---|
| 342 | '''
|
---|
| 343 | refdirconfig = bacresources.DirectorConfig(dirstring)
|
---|
| 344 |
|
---|
| 345 | for res in dirconf.resources:
|
---|
| 346 | #print res.items_dict['name']
|
---|
| 347 | print res.resourcetype
|
---|
| 348 | if res.resourcetype == "client":
|
---|
| 349 | r = res
|
---|
| 350 |
|
---|
| 351 |
|
---|
| 352 | wizard = baseconfigwizard(r,refdirconfig)
|
---|
| 353 | if wizard.exec_():
|
---|
| 354 | newresource = wizard.resource
|
---|
| 355 | print newresource
|
---|
| 356 | else:
|
---|
| 357 | print "no"
|
---|
| 358 | #wizard.show()
|
---|
| 359 |
|
---|
| 360 |
|
---|
| 361 | sys.exit(app.exec_())
|
---|
| 362 |
|
---|
| 363 |
|
---|