def delete(vserver): # is it running? lines = commands.getoutput('vserver-stat').splitlines() for line in lines: if line.split()[7] == vserver: print 'Vserver "%s" appears to be running, stop it first.' % vserver return config = vsutil.get_vserver_config(vserver) vserver_path = os.path.join(cfg.VSERVERS_ROOT, vserver) print 'Deleting %s....' % vserver_path cmd = 'chattr -iR %s' % os.path.join(vserver_path, 'lib/modules') print cmd commands.getoutput(cmd) cmd = 'rm -rf %s' % vserver_path print cmd commands.getoutput(cmd) context_path = os.path.join(cfg.VSERVERS_ROOT, config['context']) if os.path.exists(context_path): cmd = 'rm -rf %s' % context_path print cmd commands.getoutput(cmd) config_path = os.path.join(cfg.ETC_VSERVERS, vserver) cmd = 'rm -rf %s' % config_path print cmd commands.getoutput(cmd) rrd_path = os.path.join(cfg.VAR_DB_OPENVPS, vserver + '.rrd') cmd = 'rm %s' % rrd_path print cmd commands.getoutput(cmd) # remove disk limits cmd = '%s --xid %s --remove %s' % (cfg.VDLIMIT, config['context'], cfg.VSERVERS_ROOT) print cmd s = commands.getoutput(cmd) print s if 'invalid option' in s: # old vdlimit (XXX this can go away soon) print ' WARNING! OLD VDLIMIT! Upgrade your util-vserver to 0.30.207+. Using old vdlimit:' cmd = '%s -d -x %s %s' % (cfg.VDLIMIT, config['context'], cfg.VSERVERS_ROOT) print ' ', cmd print commands.getoutput(cmd)
def delete(vserver): # is it running? lines = commands.getoutput('vserver-stat').splitlines() for line in lines: if line.split()[7] == vserver: print 'Vserver "%s" appears to be running, stop it first.' % vserver return config = vsutil.get_vserver_config(vserver) vserver_path = os.path.join(cfg.VSERVERS_ROOT, vserver) print 'Deleting %s....' % vserver_path cmd = 'chattr -iR %s' % os.path.join(vserver_path, 'lib/modules') print cmd commands.getoutput(cmd) cmd = 'rm -rf %s' % vserver_path print cmd commands.getoutput(cmd) context_path = os.path.join(cfg.VSERVERS_ROOT, config['context']) if os.path.exists(context_path): cmd = 'rm -rf %s' % context_path print cmd commands.getoutput(cmd) config_path = os.path.join(cfg.ETC_VSERVERS, vserver) cmd = 'rm -rf %s' % config_path print cmd commands.getoutput(cmd) rrd_path = os.path.join(cfg.VAR_DB_OPENVPS, vserver+'.rrd') cmd = 'rm %s' % rrd_path print cmd commands.getoutput(cmd) # remove disk limits cmd = '%s --xid %s --remove %s' % (cfg.VDLIMIT, config['context'], cfg.VSERVERS_ROOT) print cmd s = commands.getoutput(cmd) print s if 'invalid option' in s: # old vdlimit (XXX this can go away soon) print ' WARNING! OLD VDLIMIT! Upgrade your util-vserver to 0.30.207+. Using old vdlimit:' cmd = '%s -d -x %s %s' % (cfg.VDLIMIT, config['context'], cfg.VSERVERS_ROOT) print ' ', cmd print commands.getoutput(cmd)
def dump(vserver_name, refserver, outfile, pace=cfg.PACE[0]): # Save the difference between reference and the server in an # archive The archive is encrypted. This is because you have to # trust it before you try restoring it. It is also better for any # backed up data to be encrypted always. # pace counter p = 0 # this will also strip trailing slashes vserver, refserver = os.path.abspath(os.path.join(cfg.VSERVERS_ROOT, vserver_name)), \ os.path.abspath(refserver) print 'Dumping %s in reference to %s ... (this will take a while)' % ( vserver, refserver) # this will prevent some warnings os.chdir(cfg.VSERVERS_ROOT) # first we need a header. for now the header format is: # "openvps-dump|Fedora Core release 2 (Tettnang)|2004010101|userid|ctxid|ip|hmac" # where the fields are: # * \0openvps-dump (constant) (the \0 makes it apear like a binary file to less) # * /etc/fedora-release from reference server # * /etc/openvps-release from reference (default to YYYYMMDDHHMMSS # * name of vserver # * context id of vserver # * ips in format dev:ip/mask,dev:ip/mask # * current disk limits (the argument to -S of vdlim) # * hmac of the preceeding string config = vsutil.get_vserver_config(vserver_name) header = ['\0openvps-dump'] header.append( open(os.path.join(refserver, 'etc/fedora-release')).read().strip()) if os.path.exists(os.path.join(refserver, 'etc/openvps-release')): header.append( open(os.path.join(refserver, 'etc/openvps-release')).read().strip()) else: header.append(time.strftime('%Y%m%d%H%M%S', time.localtime())) header.append(vserver_name) header.append(config['context']) header.append(','.join([ '%s:%s/%s' % (i['dev'], i['ip'], i['mask']) for i in config['interfaces'] ])) dl = vsutil.get_disk_limits(config['context']) if dl: header.append('%s,%s,%s,%s,%s' % (dl['b_used'], dl['b_total'], dl['i_used'], dl['i_total'], dl['root'])) else: print 'Wargning: no disk limits for xid %s' % config['context'] header.append('None') # turn it into string header = '|'.join(header) # sign it digest = hmac.new(cfg.DUMP_SECRET, header).hexdigest() # now write to our file open(outfile, 'w').write('%s|%s|\0' % (header, digest)) # open a pipe to cpio fd_r, fd_w = os.pipe() # write the password to the new file descriptor so openssl can read it os.write(fd_w, cfg.DUMP_SECRET + '\n') # cpio will be fed the list of files to archive. the output is compressed using # bzip2, then encrypted with openssl using blowfish cmd = '/bin/cpio -oHcrc | /usr/bin/bzip2 | /usr/bin/openssl bf -salt -pass fd:%d >> %s' % ( fd_r, outfile) pipe = os.popen(cmd, 'w', 0) # the first things to go into the archive should be the config and rrd # config cfg_dir = os.path.join(cfg.ETC_VSERVERS, vserver_name) cmd = '/usr/bin/find %s -print' % cfg_dir cfg_files = commands.getoutput(cmd) pipe.write(cfg_files + '\n') # the rrd rrd_path = os.path.join(cfg.VAR_DB_OPENVPS, vserver_name + '.rrd') pipe.write(rrd_path + '\n') #print source, dest for root, dirs, files in os.walk(vserver, topdown=False): for file in files + dirs: if pace and p >= pace: sys.stdout.write('.') sys.stdout.flush() time.sleep(cfg.PACE[1]) p = 0 else: p += 1 src = os.path.join(root, file) # reldst is they way it would look inside vserver reldst = os.path.join(max(root[len(vserver):], '/'), file) dst = os.path.join(refserver, reldst[1:]) if os.path.exists(dst): if os.path.islink(dst) or os.path.isdir( dst) or not os.path.isfile(dst): # If this is a link, dir or other non-file, their # mere existence is sufficient, no need to compare # inodes since these are never unified. But we # need to make sure they are not skipped (copy # means they will be there after cloning, touch # doesn't apply here) c, t, s = match_path(file) if not s: continue else: # this is a regular file that exists in both # reference and our server, let's compare inodes src_stat = os.lstat(src) dst_stat = os.lstat(dst) if src_stat.st_ino == dst_stat.st_ino: # inodes match, this is a unified file, no # reason to back it up continue pipe.write(src + '\n') os.close(fd_w) pipe.close()
def dump(vserver_name, refserver, outfile, pace=cfg.PACE[0]): # Save the difference between reference and the server in an # archive The archive is encrypted. This is because you have to # trust it before you try restoring it. It is also better for any # backed up data to be encrypted always. # pace counter p = 0 # this will also strip trailing slashes vserver, refserver = os.path.abspath(os.path.join(cfg.VSERVERS_ROOT, vserver_name)), \ os.path.abspath(refserver) print 'Dumping %s in reference to %s ... (this will take a while)' % (vserver, refserver) # this will prevent some warnings os.chdir(cfg.VSERVERS_ROOT) # first we need a header. for now the header format is: # "openvps-dump|Fedora Core release 2 (Tettnang)|2004010101|userid|ctxid|ip|hmac" # where the fields are: # * \0openvps-dump (constant) (the \0 makes it apear like a binary file to less) # * /etc/fedora-release from reference server # * /etc/openvps-release from reference (default to YYYYMMDDHHMMSS # * name of vserver # * context id of vserver # * ips in format dev:ip/mask,dev:ip/mask # * current disk limits (the argument to -S of vdlim) # * hmac of the preceeding string config = vsutil.get_vserver_config(vserver_name) header = ['\0openvps-dump'] header.append(open(os.path.join(refserver, 'etc/fedora-release')).read().strip()) if os.path.exists(os.path.join(refserver, 'etc/openvps-release')): header.append(open(os.path.join(refserver, 'etc/openvps-release')).read().strip()) else: header.append(time.strftime('%Y%m%d%H%M%S', time.localtime())) header.append(vserver_name) header.append(config['context']) header.append(','.join(['%s:%s/%s' % (i['dev'], i['ip'], i['mask']) for i in config['interfaces']])) dl = vsutil.get_disk_limits(config['context']) if dl: header.append('%s,%s,%s,%s,%s' % (dl['b_used'], dl['b_total'], dl['i_used'], dl['i_total'], dl['root'])) else: print 'Wargning: no disk limits for xid %s' % config['context'] header.append('None') # turn it into string header = '|'.join(header) # sign it digest = hmac.new(cfg.DUMP_SECRET, header).hexdigest() # now write to our file open(outfile, 'w').write('%s|%s|\0' % (header, digest)) # open a pipe to cpio fd_r, fd_w = os.pipe() # write the password to the new file descriptor so openssl can read it os.write(fd_w, cfg.DUMP_SECRET+'\n') # cpio will be fed the list of files to archive. the output is compressed using # bzip2, then encrypted with openssl using blowfish cmd = '/bin/cpio -oHcrc | /usr/bin/bzip2 | /usr/bin/openssl bf -salt -pass fd:%d >> %s' % (fd_r, outfile) pipe = os.popen(cmd, 'w', 0) # the first things to go into the archive should be the config and rrd # config cfg_dir = os.path.join(cfg.ETC_VSERVERS, vserver_name) cmd = '/usr/bin/find %s -print' % cfg_dir cfg_files = commands.getoutput(cmd) pipe.write(cfg_files+'\n') # the rrd rrd_path = os.path.join(cfg.VAR_DB_OPENVPS, vserver_name+'.rrd') pipe.write(rrd_path+'\n') #print source, dest for root, dirs, files in os.walk(vserver, topdown=False): for file in files + dirs: if pace and p >= pace: sys.stdout.write('.'); sys.stdout.flush() time.sleep(cfg.PACE[1]) p = 0 else: p += 1 src = os.path.join(root, file) # reldst is they way it would look inside vserver reldst = os.path.join(max(root[len(vserver):], '/'), file) dst = os.path.join(refserver, reldst[1:]) if os.path.exists(dst): if os.path.islink(dst) or os.path.isdir(dst) or not os.path.isfile(dst): # If this is a link, dir or other non-file, their # mere existence is sufficient, no need to compare # inodes since these are never unified. But we # need to make sure they are not skipped (copy # means they will be there after cloning, touch # doesn't apply here) c, t, s = match_path(file) if not s: continue else: # this is a regular file that exists in both # reference and our server, let's compare inodes src_stat = os.lstat(src) dst_stat = os.lstat(dst) if src_stat.st_ino == dst_stat.st_ino: # inodes match, this is a unified file, no # reason to back it up continue pipe.write(src+'\n') os.close(fd_w) pipe.close()