Guest User

Untitled

a guest
Jul 16th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.88 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # backuputils.py
  5. #
  6. # Copyright 2009 Moises Henriquez <M0E.lnx [at] gmail [dot] com>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software
  20. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  21. # MA 02110-1301, USA.
  22.  
  23. """
  24. Backup utilities for vectorlinux.
  25.  
  26. Provides a way to safely perform a system upgrade.
  27. """
  28.  
  29.  
  30. import glob
  31. import os
  32. import sys
  33. import commands
  34. from subprocess import call
  35.  
  36.  
  37. tmpdir = "/tmp/vl-backup"
  38. today = commands.getoutput('date +\%Y-\%m-\%d')
  39. pkgdir = "/var/log/packages"
  40. scriptdir = "/var/log/scripts"
  41.  
  42. tmp_pkg = os.path.join(tmpdir, today,"tmp")
  43. def save_new_packages_list():
  44. """
  45. Create a record of new packages that will get installed as a result of
  46. a system upgrade
  47.  
  48. This list contains packages that must be removed in case of a roll back
  49. file list is called 'rollback'
  50. """
  51. pre = commands.getoutput("slapt-get --upgrade -s")
  52. ret = pre.split("\n")
  53. new = []
  54. for l in ret:
  55. if "is to be upgraded" in l:
  56. pass
  57. else:
  58. pk = l.strip().split(" ")[0]
  59. new.append(pk)
  60. if len(new) <= 0:
  61. return
  62. f = open(os.path.join(tmpdir,today,"rollback"),"w")
  63. f.write("\n".join(new) + "\n")
  64. f.close()
  65.  
  66. def read_preupgrade_report():
  67. """
  68. Reads a short (internal) report of packages to be upgrade
  69. and installed.
  70.  
  71. Takes no arguments and returns a list of package names (upgrades only)
  72. """
  73. pre = commands.getoutput("slapt-get --upgrade -s")
  74. ret = pre.split("\n")
  75. m = 0
  76. new = []
  77. for l in ret:
  78. if "After unpacking" in l:
  79. m = ret.index(l) + 1
  80. while m < (len(ret) - 1):
  81. str = ret[m].split(" ")[0]
  82. new.append(str)
  83. m = m + 1
  84. return new
  85.  
  86. def perform_backup():
  87. """
  88. Performs a backup of existing packages to be upgraded by slapt-get
  89. Also creates a list of new packages to be removed in case the
  90. backup is rolled over.
  91.  
  92. Takes no arguments (yet)
  93. """
  94.  
  95. if os.path.exists(tmpdir) == False:
  96. os.makedirs(tmpdir)
  97. if os.path.exists(os.path.join(tmpdir,today)) == False:
  98. os.makedirs(os.path.join(tmpdir, today))
  99.  
  100.  
  101. for i in read_preupgrade_report():
  102.  
  103. pkg = Package(os.path.join(pkgdir,i))
  104. pkg.backup()
  105.  
  106. def restore_backup(datecode):
  107. """Restores a previously performed backup
  108. Takes one argument ie,
  109.  
  110. restore_backup(2009-11-01)
  111. """
  112. if os.path.exists(os.path.join(tmpdir, datecode)) == False:
  113. print "No records of a backup for %s" % datecode
  114. list = os.listdir(os.path.join(tmpdir, datecode))
  115. for i in list:
  116. pkg = Package(i)
  117. print "Restore %s" % i
  118. try:
  119. res = call('/sbin/removepkg ' + pkg.appname, shell=True)
  120. if res < 0:
  121. print "Finished with",-res
  122. except OSError, e:
  123. print "Error", e
  124. try:
  125. res = call('/sbin/installpkg ' + os.path.join( \
  126. tmpdir, datecode, i), shell=True)
  127. if res < 0:
  128. print "Ended with", -res
  129. except OSError, e:
  130. print "Error",e
  131.  
  132.  
  133. class Package():
  134. """
  135. Returns a package object
  136. Takes one argument, a file path to a package in /var/log/packages/
  137.  
  138. ie:
  139. pkg = Package('/var/log/packages/foo-bar-1.2.3-i586-1vl60')
  140. Use the following methods with it
  141. pkg.backup - Re-creates the original package
  142. OTHER INTERNAL USE METHODS
  143. pkg.generate_desc - Returns the package description (as a list)
  144. pkg.generate_doinst - Returns the package's install script (as a list)
  145. pkg.backup_files - creates backup copies of files in the package. """
  146.  
  147. def __init__(self, name):
  148. self.pkgname = os.path.split(name)[-1]
  149. self.pkgdir = '/var/log/packages/'
  150. self.scriptdir = '/var/log/scripts/'
  151. sp = self.pkgname.rsplit("-",3)
  152. self.appname = os.path.split(sp[0])[-1]
  153. file = open(os.path.join(self.pkgdir,name),'r')
  154. self.data = file.readlines()
  155. file.close()
  156. self.desc = "\n".join(self.generate_desc()) + "\n"
  157.  
  158.  
  159. def generate_desc(self):
  160. """
  161. Returns a package's description as a list"""
  162.  
  163. ret = []
  164.  
  165. for i in self.data:
  166. if i[:len(self.appname)] == self.appname:
  167. ret.append(i.strip())
  168. return ret
  169. def generate_doinst(self):
  170. """
  171. Returns a packages install script (if exists) as a list"""
  172.  
  173. if os.path.exists(os.path.join(self.scriptdir,self.pkgname)) == False:
  174. return
  175. data = open(os.path.join(self.scriptdir,self.pkgname),'r')
  176. file = data.readlines()
  177. ret = []
  178. for i in file:
  179. ret.append(i.strip())
  180. return ret
  181. def backup_files(self):
  182. """
  183. Create backup copies of the files in the package object
  184. """
  185. l = self.data.index("./\n") + 1
  186. n = 0
  187. tmp_pkg = os.path.join(tmpdir, today, "tmp")
  188. if os.path.exists(os.path.join(pkgdir, self.pkgname)) == False:
  189. print "%s is not installed" % self.pkgname
  190. return
  191. commands.getoutput("rm -r " + tmp_pkg)
  192. commands.getoutput("mkdir -p " + tmp_pkg)
  193. n = l
  194. while l < len(self.data):
  195. # print "making dir %s/%s" % (l,len(self.data))
  196. if os.path.isdir(os.path.join("/",self.data[l].strip())) == True:
  197. commands.getoutput("mkdir -p " + os.path.join(tmp_pkg,self.data[l].strip()))
  198. else:
  199. commands.getoutput("mkdir -p " + os.path.dirname(os.path.join(tmp_pkg,self.data[l].strip())))
  200.  
  201. l = l + 1
  202.  
  203. while n < len(self.data):
  204. # print "copying files %s/%s" % (n,len(self.data))
  205. src = os.path.join("/",self.data[n].strip())
  206. trgt = os.path.join(tmpdir,today,"tmp") + src
  207. if os.path.isdir(os.path.join("/",self.data[n].strip())) == True:
  208. pass
  209. else:
  210. # print src + " -> " + trgt
  211. commands.getoutput("cp -arp " + src + " " + trgt)
  212. n = n + 1
  213.  
  214.  
  215. if os.path.isdir(os.path.join(tmp_pkg,"install")) == False:
  216. os.makedirs(os.path.join(tmp_pkg,"install"))
  217. if self.generate_desc() != None:
  218.  
  219. desc = open(os.path.join(tmp_pkg,"install/slack-desc"),'w')
  220. desc.write("\n".join(self.generate_desc()) + "\n")
  221. desc.close()
  222. # Backup the doinst.sh script
  223. if self.generate_doinst() != None:
  224. script = open(os.path.join(tmp_pkg,'install/doinst.sh'),'w')
  225. script.write("\n".join(self.generate_doinst()) + "\n")
  226. script.close()
  227. # cleanup the temp dir
  228. #commands.getoutput("rm -rf " + tmp_pkg + "/*")
  229.  
  230.  
  231.  
  232. def repack(self):
  233. """
  234. Re-create the package using the backed up files
  235. *** For internal use only ***"""
  236. print "Re-packaging %s to %s" % (self.pkgname, os.path.join(tmpdir,today, self.pkgname) + ".txz")
  237. os.chdir(tmp_pkg + "/")
  238.  
  239. commands.getoutput("/sbin/makepkg -l y -c n %s" % (self.pkgname + ".txz"))
  240. commands.getoutput("rm -rf " + tmp_pkg + "/*")
  241.  
  242. os.chdir(tmpdir)
  243.  
  244. def backup(self):
  245. """
  246. Create a complete backup of the package object using the backed up
  247. files. """
  248. self.backup_files()
  249. self.repack()
  250.  
  251. def check_root():
  252. return os.getuid()
  253.  
  254. def safe_upgrade():
  255. """
  256. Performs a safe system upgrade by creating backup copies of packages to be
  257. upgrade before the upgrade."""
  258. if len(read_preupgrade_report()) > 0:
  259. print "Performing backup safety net"
  260. perform_backup()
  261. try:
  262. ret = call("/sbin/slapt-get -y --upgrade",shell=True)
  263. if ret < 0:
  264. print "Error while upgrading packages", -ret
  265. except OSError, e:
  266. print "safe upgrade failed with error",e
  267.  
  268.  
  269. else:
  270. print "No upgrades available"
  271. sys.exit()
  272.  
  273. def main():
  274.  
  275. if check_root() > 0:
  276. print "You must be root to use this"
  277. sys.exit()
  278.  
  279. if __name__ == '__main__':
  280. main()
Add Comment
Please, Sign In to add comment