Tag-Archive for » agile «

Wednesday, June 23rd, 2010 | Author:

eth0If you read this blog you may know I daily use puppet at $WORK. Puppet is made to maintain configuration on machines, but not for one shot actions. For a couple of month I used to work with fabric for this but It had a few drawbacks, mainly because you need to maintain the list of hosts you want to act on and that it hates dead hosts, even if ghantoos dropped a link showing how to get rid of this. So I replaced it with mcollective : not exactly the same (it uses an agent instead of SSH) but it dynamicaly knows which hosts are up, allows to filter on facts (from facter, the puppet companion).

You could think that needing an agent is a drawback but it allows much complex actions, fine grained logic. Moreover it does not require much work to be installed if you already have puppet running. If you have a high number of machines you gain scalability with real parallel actions : it does not take longer to run on 5 machines than on 100.

One more point is the active development : R.I. Pienaar released 2 versions recently, improving access control, adding DDL to create interfaces easily. You can give your unprivileged staff some power through a web interface in less than 100 lines of code.

A tool for sysadmins that appreciate the devops spirit and want to do more in less time !

I’ll be publishing my agent and related tools on my github account.

Category: BOFH Life, SysAdmin, Tech  | Tags: , , ,  | Comments off
Monday, July 06th, 2009 | Author:

Il y a des trucs, ça relève du bon sens mais on y pense pas toujours. Dans le monde des sysadmins, il y en a qui militent pour ce qu’on appelle “l’agilité”. C’est en fait appliquer certaines techniques à la base mises en place pour le développement au monde de l’administration système. Personnellement, je trouve que ce sont essentiellement des conseils de bon sens, l’expérience qui parle en somme.

Une de ces “bonnes pratiques” est que le code est la documentation, ce qui évite d’avoir à la réécrire – parce que c’est chiant avouons le – voire même d’oublier de l’écrire, ce qui arrive souvent.

Comme je suis en pleine frénésie puppet-ienne, j’écris des classes à tout va mais pas la doc qui va avec.. et ça PAS BIEN. Je me suis donc lancé dans un petit projet pour documenter mes classes puppet vite fait bien comme une loutre.

Il suffit d’ajouter au dessus de chaque classe (ou en dessous ou peu importe, le code est crade et ne fait pas la différence) des commentaires formattés comme suit :

# @name : debian
# @desc : classe de base pour debian
# @info : ne pas affecter, sera incluse automatiquement

Pour que le script sorte les données dans un tableau façon dokuwiki en 3 colonnes.

Le script va ensuite poster les infos dans le dokuwiki via XML-RPC dans la page indiquée par le script. Tout ce que contient la page sera écrasé, ce n’est pas de l'”append”.

Personnellement je conjugue ce script avec le plugin “include” de dokuwiki. J’ai donc la syntaxe suivante dans une des pages de mon wiki :

{{page>:auto_puppetclasses}}

Le XML-RPC est désactivé par défaut dans dokuwiki, pour l’activer ajoutez dans conf/local.php

$conf['xmlrpc'] = 1;

Et enfin, le script en ruby avec des bouts de XML-RPC dedans (dispo dans le package libruby sous debian). Warning, code sale.

#!/usr/bin/env ruby
#
# Automagicaly adds puppet classes in the dokuwiki corporate documentation
# For use with the "include" plugin
# By nico <nico@gcu.info>
 
require 'xmlrpc/client'
 
xmlrpc_url = "http://XXXXX/wiki/lib/exe/xmlrpc.php"
basedirs = [ "/home/nico/sysadmin/puppet/manifests/classes", "/home/nico/sysadmin/puppet/manifests/os"]
destination_page = "auto_puppetclasses"
 
server = XMLRPC::Client.new2(xmlrpc_url)
 
def doku_class(classfile, final_page)
	fp=File.open(classfile)
	fp.readlines().each { |line|
 
		line=line.gsub("n","")
 
		if line =~ /@name/
			final_page += "| " + line[10,line.length]
		end
 
		if line =~ /@desc/
			final_page += " | " + line[10,line.length] + " | "
		end
 
		if line =~ /@info/
			final_page += line[10,line.length] + " |n"
		end
	}
 
	return final_page
end
 
final_page=""
 
# output some dokuwiki thing
final_page += "===== Classes disponibles =====n"
final_page +=  "n"
final_page +=  "^ Nom de la classe ^ Description rapide ^ Infos supplémentaires ^n"
 
basedirs.each{ |basedir|
	Dir.new(basedir).entries.each { |entry|
		if File.file? basedir+"/"+entry then
			final_page=doku_class(basedir+"/"+entry,final_page)
		end
	}
}
 
server.call2("wiki.putPage", destination_page, final_page, "", 0)