def checkRepositories(): ''' check if repos are healthty and update db-information ''' # correct format of backupPath os.path.join(config['general']['backupPath'], '') # build path to repos based on given passwords repos = [ os.path.join(config['general']['backupPath'], directory) for directory in os.listdir(os.path.join(gitProjectDir, 'passwords')) ] # check if each corresponding repo is valid status = [ 'no error' in __shell__('restic -r {} --password-file {} --no-cache check'.format( repo, os.path.join(gitProjectDir, 'passwords', repo.split('/')[-1]))) for repo in repos ] # update repository data in db for j, repo in enumerate(repos): statusNum = [1 if stat else 0 for stat in [status[j]]][0] repoSpace = __shell__('du -sh {}'.format(repo)).split('\t')[0] try: repositories.objects.update_or_create( name=repo.split('/')[-1], absolPath=repo, diskSpace=repoSpace, lastUpdate=now( ), #--> doing that initially (defined in index/models.py) health=statusNum) except: col = repositories.objects.get(absolPath=repo) col.name = repo.split('/')[-1] col.diskSpace = repoSpace col.lastUpdate = now( ) #--> doing that initially (defined in index/models.py) col.health = statusNum col.save() # execute shell "command after"-option __shell__(config['check']['executeCommandAfterCheck']) # call diskSpace-warning if necessary __warnIfLowSpace__() # if enabled, send notification # ------------------------------- result = '' if __optionIsEnabled__(config['notify']['sendMailNotifications']): result = mailingNotification().manageMailing() # if result returned something, an error occurred if result: __log__(result) return render(request, 'checkOutput.html', {'output': result})
def delete(request, absolPath, snapID): ''' backend for /snapshpots/<str:absolPath>/delete/<str:snapID> ''' __shell__('restic -r {} forget {} --prune --password-file {}'.format( absolPath.replace('.', '/'), snapID, os.path.join(gitProjectDir, 'passwords', absolPath.split('.')[-1]))) return redirect('/snapshots/{}'.format(absolPath))
def restore(request, absolPath, snapID): ''' backend for /snapshots/restore ''' if request.method == 'POST': form = restoreForm(request.POST) if not form.is_valid(): return render(request, 'checkOutput.html', {'output': 'Form was not valid, sorry!'}) __shell__( 'restic -r {} restore --no-cache {} --target {} --password-file {}' .format( absolPath.replace('.', '/'), snapID, form['restorePath'].value(), os.path.join(gitProjectDir, 'passwords', absolPath.split('.')[-1]))) return redirect('/')
def doIntegrationAndSavePW(self): ''' This function executes the previously rendered ansible-backend and returns the exit message. ''' result = __shell__( 'ansible-playbook ./integrate/ansible_rendered/setup.yml -e \"ansible_user={0}\" -e \"ansible_ssh_pass={1}\" -e \"ansible_become_pass={1}\"' .format(self.user, self.pw)) passwdpath = os.path.join(gitProjectDir, 'passwords', ''.join(self.repoPath.split('/')[-1])) with open(passwdpath, 'w') as pwfile: pwfile.write(self.resticPW) if 'error' in result or 'Failed' in result or 'fatal' in result: __shell__('rm {}'.format(passwdpath)) return __log__( 'Error occurred while trying to integrate: {}'.format(result)) return result
def __getLastDate__(): ''' This function returns last date of overall checks ''' values = repositories.objects.values_list().values() # if empty, there was no initial check if not values: __shell__(os.path.join(BASE_DIR, 'bin/update.py')) return __getLastDate__() if len(values) == 1: return values[0]['lastUpdate'] for j in range(1, len(values)): latest = values[j]['lastUpdate'] if values[j - 1]['lastUpdate'] > latest: latest = values[j - 1]['lastUpdate'] return latest
def updateSnapshots(self, absolPath): ''' This method is called from updateSnapshots and returns correct formatted infro for each snapshot. ''' absolPath = absolPath.replace('.', '/') passwordFile = os.path.join(gitProjectDir, 'passwords', absolPath.split('/')[-1]) snapshots = __shell__( 'restic -r {} --password-file {} snapshots'.format( absolPath, passwordFile)) return self.__formatSnapshotStr__(snapshots, absolPath)
def __getFreeDiskSpace__(): ''' This function returns str that describes available disk space and corresponding mount-path ''' # get mount-point root = os.path.join(config['general']['backupPath'], '') # make sure path ends with / output = __shell__('df -h', old=True) mountPoint = __getMountPoint__(output, root) overallSpace, availableSpace = __getOverallSpace__(output, mountPoint) return '{} out of {} left on {}'.format(availableSpace, overallSpace, mountPoint)
def __init__(self, user, pw, dest, repoPath, backupPath, localUser, localPassword, resticPW=''.join( [chr(random.randint(41, 125)) for i in range(128)])): self.user = user self.pw = pw self.dest = dest self.repoPath = os.path.join(gitProjectDir, repoPath) self.backupPath = backupPath self.resticPW = resticPW self.localUser = localUser self.localPassword = localPassword self.ownHost = __shell__('cat /etc/hostname'.replace('\n', ''))
def repos(request): ''' fetch backup data from postgres and render it to template ''' # get repo data and append snapshots-uri to link repos = list(repositories.objects.order_by('name').values()) for repo in repos: repo['snapshotsURI'] = '/snapshots/{}'.format( repo['absolPath'].replace('/', '.')) general = { 'hostname': __shell__('cat /etc/hostname').replace('\n', ''), 'path': config['general']['backupPath'], 'space': __getFreeDiskSpace__(), 'lastCheck': __getLastDate__(), 'status': __getOverallHealth__() } return render(request, 'repositories.html', { 'repos': repos, 'general': general })