I use Redmine to track my personal projects, and every time that I have to update I have to re-read the full upgrading page which is long and full of exceptions. So I decided to write my own reduced cookbook to solve that. FYI I’m using Ubuntu 16.04, Apache2, MySQL and Passenger for running Redmine.
Being root user run:
backup MySQL database
download new redmine package and unpack in /var/www
change ‘redmine’ soft link to new folder
copy old files and directories overwriting the new ones:<br><pre><code>config/database.yml<br>config/configuration.yml<br>files/<br>plugins/</code></pre><br>
locating work directory on new redmine folder, run:<br><pre>bundle install --without development test<br>bundle exec rake generate_secret_token<br>bundle exec rake db:migrate RAILS_ENV=production<br>bundle exec rake redmine:plugins:migrate RAILS_ENV=production<br>bundle exec rake tmp:cache:clear tmp:sessions:clear RAILS_ENV=production</pre><br>
Ansible is a very powerful tool. Using playbooks, something like a cookbook, is very easy to automate maintenance tasks of systems. I used Puppet and other tools like that but IMHO Ansible is the best one.
In some cases you need to manage dynamic systems and take into advantage of Ansible like a Python library is a very good complement for your scripts. This is my last requirement and because of that I decided to share some simple Python snippets that help you to understand how to use Ansible as a Python library.
Firstly an example about how to call an Ansible module with just one host in the inventory (test_modules.py):
#!/usr/bin/python import ansible.runnerimport ansible.playbookimport ansible.inventoryfrom ansible import callbacksfrom ansible import utilsimport json# the fastest way to set up the inventory# hosts listhosts = ["10.11.12.66"]# set up the inventory, if no group is defined then 'all' group is used by defaultexample_inventory = ansible.inventory.Inventory(hosts)pm = ansible.runner.Runner( module_name = 'command', module_args = 'uname -a', timeout = 5, inventory = example_inventory, subset = 'all' # name of the hosts group )out = pm.run()print json.dumps(out, sort_keys=True, indent=4, separators=(',', ': '))
As a second example, we’re going to use a simple Ansible Playbook with that code (test.yml):
- hosts: sample_group_name tasks: - name: just an uname command: uname -a
The Python code which uses that playbook is (test_playbook.py):
#!/usr/bin/python import ansible.runnerimport ansible.playbookimport ansible.inventoryfrom ansible import callbacksfrom ansible import utilsimport json### setting up the inventory## first of all, set up a host (or more)example_host = ansible.inventory.host.Host( name = '10.11.12.66', port = 22 )# with its variables to modify the playbookexample_host.set_variable( 'var', 'foo')## secondly set up the group where the host(s) has to be addedexample_group = ansible.inventory.group.Group( name = 'sample_group_name' )example_group.add_host(example_host)## the last step is set up the invetory itselfexample_inventory = ansible.inventory.Inventory()example_inventory.add_group(example_group)example_inventory.subset('sample_group_name')# setting callbacksstats = callbacks.AggregateStats()playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)# creating the playbook instance to run, based on "test.yml" filepb = ansible.playbook.PlayBook( playbook = "test.yml", stats = stats, callbacks = playbook_cb, runner_callbacks = runner_cb, inventory = example_inventory, check=True )# running the playbookpr = pb.run() # print the summary of results for each hostprint json.dumps(pr, sort_keys=True, indent=4, separators=(',', ': '))
Als que usem Gentoo l’ordre del títol ens sona moltíssim, i encara més l’efecte típic que segueix a aquesta ordre quan tenim un munt de paquets per actualitzar i deixem l’ordinador tota la nit compilant, o no? perquè no… doncs perquè sovint en algún punt del procés ha sorgit un problema i s’ha parat la compilació. Un munt de temps perdut perquè el sistema esperava que corregíssim un problemilla que havia sorgit per poder continuar i els tropocientos paquets que hi havia per instal·lar s’han quedat a mitges.
Al Gentoo Weekly News d’aquesta setmana a l’apartat de Tips and Tricks ha sortit un script que de ben segur si el comenceu a usar no podreu viure sense ell. Realment útil, perquè s’encarrega just de solucionar el problema que he comentat. O sigui, que en cas de que fent una actualització un paquet doni un error ell seguirà compilant i al final deixarà dintre d’un fitxer un informe dels problemes que hagin sorgit durant l’upgrade del sistema.
Això crea una llista dels paquets que s’instal·laràn (equival a emerge -uD –newuse world). Si voleu també podeu generar una llista amb tots els paquets del sistema amb l’ordre update-world –empty, seria equivalent a emerge -e world). La llista de paquets a instal·lar la podeu trobar a ~/.update-world/emergelist, així que un cop generada la llista de paquets podeu modificar-la i després ja podeu llençar l’actualització:
# update-world --install
En cas de que falli un paquet durant el procés d’instal·lació/actualització de paquets (penseu que equival a emerge -uD world) a ~/.update-world/failedlist trobareu una llista amb els paquets que hagin fallat. A més també es crearà un enllaç a ~/.update-world/[date]/log/ cap al log amb l’error que ha donat aquest paquet.
Com podeu veure tot un gran enginy que simplificarà la feina d’administrar els sistemes Gentoo que tenim.
Notes per un lamer com jo per saber fer un upgrade de la versió d’ubuntu dapper a la edgy que és l’última. Però és que necessito la nota perquè mai recordo com es fa:
A larxiu /etc/apt/source.list canviar les entrades de dapper per edgy
apt-get update com a root
apt-get dist-upgrade també com a root
També aprofito per referenciar un FAQ d’ubuntu que té molt bona pinta i que té resoltes coses tan interessants com obrir PDF dins del firefox en linux. Cosa que jo estava convençut que no es podia fer, digueu-me incult.