Z wiekiem systemu narastała kupka z własnymi modyfikacjami w /etc, więc dodałem repo z hg. Pozostało to zautomatyzować...
yum-plugin-hg
Kierując się poradnikiem Writing Yum Plugins naskrobałem takie coś:$ cat /etc/yum/pluginconf.d/hg.conf
[main] enabled=1 # lista folderów pod kontrolą hg (domyślnie tylko /etc) # path=/etc:/var/log # opcjonalnie można podać alternatywną ścieżkę do: hg, meld # hg=/usr/local/bin/hg # trik wyłączy commit repo # hg=/bin/echo$ cat /usr/lib/yum-plugins/hg.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import os,sys,filecmp
from subprocess import Popen, PIPE, check_call, CalledProcessError
from yum.plugins import TYPE_CORE, TYPE_INTERACTIVE
if os.environ.has_key('DISPLAY'):
import pygtk
import gtk
requires_api_version = '2.6'
plugin_type = (TYPE_CORE, TYPE_INTERACTIVE)
def err(comment):
sys.stderr.write(comment)
def sh(cmd):
""" http://docs.python.org/library/subprocess.html """
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
err(stderr)
out(stdout)
def mercurial(path):
# Test: czy jest repo, jak nie to robimy nowe
try:
check_call([hg,"st"],stdout=PIPE,stderr=PIPE)
except CalledProcessError:
out('creating a new hg repository in '+path+' directory')
sh(hg+" init")
out('hg addremove ...')
sh(hg+" addremove")
out('hg status ...')
sh(hg+" st")
out('hg commit ... it may take a while')
sh(hg+" ci -m 'commit by yum plugin'")
# access only for root
os.chmod('.hg',700)
os.chown('.hg',0,0)
def question(name):
dialog = gtk.Dialog("Are you sure?", None, 0,
(gtk.STOCK_NO, gtk.RESPONSE_NO,
gtk.STOCK_YES, gtk.RESPONSE_YES))
label = gtk.Label("\nDelete file "+name+"?\n")
label.show()
dialog.get_content_area().add(label)
dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
response = dialog.run()
dialog.destroy()
while gtk.events_pending():
gtk.main_iteration(False)
if response == gtk.RESPONSE_YES:
return True
else:
return False
def find_confs(conf='.rpmsave'):
for root, dirs, files in os.walk("/etc"):
for f in files:
if f.endswith(conf):
backup=root+'/'+f
current=backup.split(conf)[0]
merg_confs(current,backup)
def merg_confs(current,backup):
if os.path.isfile(current) and os.path.isfile(backup):
if filecmp.cmp(current,backup): # ~diff
out("files: '"+current+"' & '"+backup+"' are identical")
out("removing: '"+backup+"'")
os.remove(backup)
elif os.environ.has_key('DISPLAY'):
out("comparing files: '"+current+"' & '"+backup+"' with meld")
sh(meld+" "+current+" "+backup)
if question(backup):
out("removing: '"+backup+"'")
os.remove(backup)
else:
err("no X ;( use 'diff' to compare files: '"
+current+"' & '"+backup+"'")
elif not os.path.exists(current):
err("no such file or directory: '"+current+"'")
out("renaming: '"+backup+"' --> '"+current+"'")
os.rename(backup,current)
def main(path):
if os.getuid() != 0:
return False
cwd=os.getcwd()
for dir in path.split(':'):
try:
os.chdir(dir)
except:
show("no such directory: '"+dir+"'")
else:
out('hg: '+dir)
if dir == '/etc':
find_confs(conf='.rpmsave')
find_confs(conf='.rpmnew')
mercurial(dir)
finally:
os.chdir(cwd) # back to main directory
def close_hook(conduit):
global out, meld, hg
path = conduit.confString('main', 'path', default='/etc')
meld = conduit.confString('main', 'meld', default='/usr/bin/meld')
hg = conduit.confString('main', 'hg' , default='/usr/bin/hg')
def out(comment):
if comment:
conduit.info(2,comment)
main(path)
def simulation(): # close_hook(conduit)
global out, meld, hg
path='/etc:/var/log'
meld='/usr/bin/meld'
hg='/usr/bin/hg'
def out(comment):
sys.stdout.write(comment) # print if not Null
main(path)
if __name__ == '__main__':
simulation()
Warto dodać, że podczas testowania pluginu można uruchomić yum'a z opcją -d 10 co ozn. wypisywanie wszystkich komunikatów.
Do pobrania:
Prosto z borzole.repo, albo paczka rpmAktualizacja:
- 2010.10.22-23:50
Poprawka błędu, który uniemożliwiał zainicjowanie repo. Dorzuciłem też przykładowy plik /etc/.hgignore - 2010.10.21-23:57
Zrobiłem refaktoryzację tej partyzantki i pozbyłem się większości sztucznych konstrukcji. Zarówno 'meld' jak i 'hg' pozostają wywołane przez moduł 'subprocess' pomimo, że można napisać to w czystym pythonie. Niestety z natywnym 'hg' nie mogłem sobie poradzić, a 'meld' wymagał innego kodu dla Fedora 13 i 14.
Brak komentarzy:
Prześlij komentarz