Metiendo Jenkins con calzador

Voy a tener la decencia de no compartir esta entrada en mi página de Facebook para que no sufran todos aquellos (más bien aquellas) que recientemente se han apuntado pensando que yo aquí sólo hablaba sobre temas de pareja y niños… porque como los veteranos sabéis aquí también hablo a veces de cosas relacionadas con la programación y esta entrada es un claro ejemplo de ello.

Así que estáis advertidos…  ¡parad de leer ya!

Tenemos un proyecto que está programado en un lenguaje de script, que ni se compila ni nada… por suerte usamos GIT para hacer el control de versiones y poco más. Hasta ahí todo bien, pero resulta que ahora para pasar el código de preproducción (PRE) a producción (PRO) nos exigen que utilicemos Jenkins (un software de integración continua open source escrito en Java).

=========== JENKINS EN MAC ==========

Total que llevo ya dos noches haciendo pruebas aquí en mi MacBook y he conseguido que pseudo-funcione algo que seguro que a vista de cualquier experto resultará una atrocidad… y aun así me dispongo a dejarlo aquí escrito para que no se me olvide.

Atentos que vienen curvas…

1 – Instalamos Jenkins, que es muy sencillo… tanto en Mac como Windows sólo tienes que bajarte el “native package” y ejecutarlo.

2 – Ya en Jenkins (localhost:8080 por defecto), nos vamos a “Manage Jenkins”  > “Manage Plugins” e instalamos: Git Plugin y también “Bitbucket OAuth” (el enlace para instalar este plugin que no es imprescindible).

3 – Volvemos a la Home de Jenkins y le damos a “New Item” > Freestyle project… y nos creamos un item con el nombre de nuestro repositorio.

4 – En “Source Code Management” eligimos Git (que gracias al plugin que instalamos ya aparece), en “Repository URL” ponemos las URL para SSH que tiene la siguiente estructura en bitbucket:

git@bitbucket.org:[USUARIO]/[REPOSITORIO].git

5 – En “Credentials” le daremos a “Add” y se nos abrirá una pantalla nueva para crear usuarios. Aquí podríamos dar de alta nuestro usuario de bitbucket.org con el usuario y la contraseña… pero eso nos daría problemas después así tenemos que dar de alta un Credencial del tipo “SSH Username with private key”, en “username” dejaremos “jenkins” y seleccionaremos la opción de “From the Jenkins master ~/.ssh”.

Guardamos y nos aseguramos que en el desplegable de Credenciales ha quedado seleccionado “jenkins”

6 – En el apartado “Buid Triggers” seleccionamos “Poll SCM” y rellenamos en Schedule “H/15 * * * *” que quiere decir que cada 15 minutos se va a conectar a Bitbucket a ver si hay algo nuevo.

Ahora viene la parte absurda y que creo que no tiene ningún sentido que la configure así… pero que de momento me sirve para salir del paso. El apartado Build:

7 – Como el código de este proyecto no se compila lo que vamos a hacer es directamente añadir dos ejecuciones de “shell” en la primera nos vamos con CD a la carpeta donde está ese repositorio en nuestro ordenador y en la segunda hacemos un “git pull origin master” de toda la vida.

Que son exactamente los comandos que antes ejecutábamos a mano y que ahora en cierta manera los metemos dentro de un flujo… y que al menos su resultado queda archivado en el log de Jenkins.

Guardamos… y evidentemente no funciona nada, porque la clave SSH a la que hemos hecho referencia lo normal es que no la hayamos creado todavía…

Así que aquí empieza otra explicación, casi tan amena como la anterior:

1 – El truco de este tema es entender que cuando Jenkins se ejecuta lo hace con su propio usuario “jenkins” y no con tu usuario. Asi que la clave SSH hay que crearla para ese otro usuario, para ello abrimos una ventana de terminal:

sudo su
su jenkins
ssh-keygen
Enter - Enter - Enter
cd /Users/Shared/Jenkins/.ssh
vim id_rsa.pub

2 – Si todo ha ido bien hemos creado un llave en su ubicación por defecto, sin “passphrase” que ahora tenemos que registrar en bitbucket.org. Para copiarla en el portapapeles normalmente utilizaríamos:

cat id_rsa.pub | pbcopy

Pero no me funcionaba, no sé si es porque estaba en el Terminal con el usuario “jenkins”… así que lo hice al viejo estilo de copiar y pegar desde VIM.

3 – En Bitbucket.org nos vamos a la configuración del usuario (no del repositorio) y en el apartado de SSH registramos la llave en mi caso con el nombre “MacBook Jenkins”

4 – Para probar que todo va bien ejecutamos:

hg clone ssh://git@altssh.bitbucket.org:443/[user]/[rep].git testkey

Esta prueba termina con un “abort: not suitable response from remote hg!” pero eso es normal.

5 – En nuestro repositorio dentro de la carpeta “.git” (que está oculta) tenemos que editar el fichero “config” y asegurarnos que en el apartado [remote “origin”] en URL aparece la dirección del repositorio para SSH, es decir:

git@bitbucket.org:[USUARIO]/[REPOSITORIO].git

6 – No contentos con eso todavía queda un escollo por resolver. Si en la ventana de terminal en la que estábamos trabajando como si fuéramos el usuario jenkins vamos a teclear “exit” para salirnos de “bash” y vamos a ir donde están nuestros repositorios y probar a hacer un pull.

cd User/[mi usuario]/Documents/webs/[nombre repositorio]
git pull origin master

Al principio parecerá que todo va bien, nos dice que va a añadir bitbucket.org a la lista de “know hosts”… y después nos salta un error que dice “error: cannot open .git/FETCH_HEAD: Permisión denied

Esto se debe a que estamos intentando operar dentro de una carpeta que no pertenece al usuario “jenkins” asi que lo que tenemos que hacer es dar al usuario “jenkins” permisos de escritura y lectura en toda la carpeta del repositorio.

7 –  Buscamos la carpeta del repositorio desde Finder, botón derecho del ratón sobre ella y vamos a “Get info”, desplegamos el último apartado “Sharing & Permissions” y añadimos el usuario “jenkins” a la lista y en Privilege selecionamos “Read & Write”. Ahora tenemos que darle al icono de la tuerca (desbloqueamos primero con el candado) y elegimos la opción “Apply to enclosed items”

8 – Si todo ha ido bien ahora nos debería dejar hacer pull del repositorio con el usuario “jenkins”… y si te deja en el terminal te debería dejar con el propio Jenkins.

NOTA – Si hasta ese momento solíamos hacer pull en bitbucket.org a través de HTTPS con usuario y contraseña… dado que hemos cambiado el /.git/config para que utilice SSH ese método ya no va a funciona. Tendremos que crear otra clave SSH (esta vez con contraseña) para nuestro usuario habitual y registrarla también en bitbucket.org.

Conclusiones

Jenkins cuando se conecta a bitbucket.org para traerse los cambios mantiene una copia tu repositorio en Workspace:

/Users/Shared/Jenkins/Home/Jobs/[nombre del repositorio]/workspace/

Si ahí está tu código fuente y dado que en este caso no es necesario compilarlo, entiendo que lo suyo es que de alguna manera desde ahí pasase a donde yo necesito que esté:

/User/[mi usuario]/Documents/webs/[nombre repositorio]/

Pero eso todavía no sé como se hace, tal vez hay algún plugin para proyectos sencillos como el de este ejemplo. Así que de momento hago algo que yo creo que es absurdo: “Construir” ejecutando pull en mi carpeta desde shell, es decir, lo que ya hacía antes de usar Jenkins con un script. Pero bueno, por algo se empieza… trasteando es como se aprende.

Si hay algún maestro de Jenkins que me quiera iluminar es bienvenido.

Actualización. Jenkins deja de arrancar a los dos días de instalarlo – Siempre que escribo un tutorial de este tipo se que antes o después lo voy a necesitar, lo que no sabía es que iba a ser tan pronto. Resulta que al día siguiente de escribir esta entrada abro el MacBook y Jenkins no enciende. Después de hacer de todo, incluso desinstalarlo y volverlo a repetir todo, el error al parecer se debe a que Jenkins crea unos ficheros log con permisos incorrectos, lo que impide al propio Jenkins escribir sobre ellos y hace que no pueda iniciarse. El primer fichero log si que está bien hecho, son los siguientes que se crean cada dos días los que fallan. El problema se soluciona así desde Terminal:

1 – chown jenkins /var/log/jenkins/jenkins.log   Con esto arreglamos el fichero log ya creado… nada más hagamos esto veremos como repentinamente se carga de datos y  Jenkins volverá a funcionar.

2 – Para que dentro de dos días no se vuelve a estropear tenemos que editar el fichero /etc/newsyslog.d/jenkins.conf y añadir “jenkins:jenkins” antes del 644, para que quede tal que asi:

jenkins_conf___private_etc_newsyslog_d__-_VIM

[ Actualización 28 de abril de 2015 ]

=========== JENKINS EN WINDOWS ==========

Una vez conseguido que funcionara Jenkins en mi ordenador MacBook que es el que tengo en casa y con el que me puedo quedar trabajando hasta altas horas de la noche, necesitaba conseguir que todo funcionara en Windows, y dentro de lo posible aprovechar para completar esa última pieza del puzle con la que todo este tinglado puede tener algún sentido.

Asi que voy a ir detallando los escollos en el proceso:

Crear una llave SSH en Windows y conectarnos a Bitbucket.org

1 – Aprovechando que vi un artículo sobre este programa me instalé la versión gratuita de MobaXterm y con ella me cree mi llave .ssh. Algo que se hace con este comando:

ssh-keygen -t rsa -C “your_email@example.com”

La crearemos sin  passphrase y en la ubicación por defecto que será:

C:Users[USUARIO]DocumentsMobaXtermhome.ssh

2 – Luego copiaremos de esa carpeta el contenido de id_rsa.pub y lo daremos de alta en Bitbucket.org de la misma manera que hicimos en el Mac.

3 – También tendremos que crear un credencial dentro de Jenkins y copiar el contenido de la Private Key (id_rsa):

Captura_de_pantalla_042815_113219_AM

4 – Después de instalarnos el plugin de Git, nos crearemos una “Nueva Tarea en Jenkins” que se conectará a nuestro repositorio en bitbucket.org a través de SSH con los que “Repository URL” tendremos que poner:

git@bitbucket.org:[USUARIO]/[REPOSITORIO].git

Y en “Credentials” elegirimos el que hemos creado anteriormente.

5 – Para que funcionen los credenciales es necesario que se de de alta bitbucket.org como “known_hosts”:

Captura_de_pantalla_042815_114526_AM

Si instalas GIT en Mobaxterm con el comando:

apt-get install git

Puedes ir a uno de tus repositorios y hacer un pull, y se añadirá automáticamente:

Captura_de_pantalla_042815_115005_AM

Esto es mejor hacerlo por fuera, antes de configurar Jenkins, asi nos aseguramos que todo funciona correctamente haciéndolo desde el exterior.

Configurando el Disparador de ejecuciones

Aquí es igual que en MacBook pondremos de momento “Ejecutar periódicamente” y seleccionaremos cada 15 minutos “H/15 * * * *”

Configurando un ejecutar (BUILD) chapucero

Como os comenté en mi MacBook hice algo poco ortodoxo que fue básicamente construir mi proyecto a través de un PULL de nuevo a bitbucket en la ubicación de destino. Algo tal que asi:

Captura_de_pantalla_042815_114030_AMEsto no tiene mucho sentido porque realmente para hacer algo así no es que necesites Jenkins, ¿para qué va a tener nuestro repositorio guardado en Workspace si no es para construir a partir de él? En cualquier caso, por poder, es posible configurar algo similar en Windows, como se ve en la imagen pero tienes que tener en cuenta lo siguiente:

1 – Para que se ejecuten estos comandos del tirón tienes que tener configurado GIT para que funcione con SSH y sin passphrase (en teoría cuando creas los Credenciales en Jenkins puede en “Avanzadas” guardar tu passphrase, pero yo no he conseguido que de esa manera funcione).

2 – Aun así puede que cuando intente construir de esta manera se quede colgado por falta de permisos en la carpeta. Al fin y al cabo para conectar con SSH tiene que tener acceso a la clave privada guardada en nuestro ordenador y como Jenkins correo con su propio usuario lo normal es que no tenga acceso a ella. Una solución para este tema es ir a “Servicios” en Windows, buscar el Servicio de Jenkins > Propiedades > Iniciar sesión y configurar ahí nuestra cuenta:

Captura_de_pantalla_042815_115919_AM

Tendremos que parar el servicio y volverlo a arrancar para que todo funcione… y a partir de ese momento Jenkins cuando se ejecute lo hará como si fueramos nosotros, asi que podrá hacer pull y tirar de nuestra llave SSH.

Configurar un BUILD en condiciones con Microsoft Web Deploy V3

Investigando descubrí que las solución a todos nuetros problemas es un ejecutable que se llama MSDEPLOY.EXE que como su propio nombre indica sirve para desplegar webs en IIS.

1 – Lo normal es que no lo tengas instalado, pero eso es sencillo de solucionar sólo tienes que abrir IIS y pulsar en “Obtener nuevos componentes de plataforma web” y luego buscar “deploy” para que te salgan todos los componentes con ese nombre. Yo me instalé “Web Deployment Tool 3.5 sin compatibilidad con SQL (…)” que es el más ligero:

Captura_de_pantalla_042815_121048_PM

2 – Opcional – una vez que lo tenemos instalado por comodidad podemos dar de alta su ruta de instación como una variable de entorno en PATH para poderlo ejecutar desde cualquier parte. La ruta de instalación es esta:

C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe

3 – Ahora vamos con la magia, el comando que queremos ejecutar para construir nuestra web sería algo parecido a esto:

"C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe"
-AllowUntrusted
-verb:sync
-source:contentPath="C:Program Files (x86)Jenkinsjobs[REPO]workspace"
-dest:contentPath="D:wwwroot[REPO]"
-skip:objectName=dirPath,absolutePath=".git"

Qué básicamente establece como origen (souce) nuestro workspace de Jenkins, define un destino (dest) que es el emplazamiento del sitio web que tenemos configurado en IIS y hace una sincronización (verb: sync).

Como detalle de calidad excluimos de la sincronización la carpeta “.git” que no debería estar disponible desde Internet. Podemos ejecutar esto desde Simbolos de Sistema (CMD como administrador):

Captura_de_pantalla_042815_121902_PM

4 – Y cuando veamos que todo nos funciona meterlo en Jenkins:

Captura_de_pantalla_042815_122512_PMAsí que ahora ya tenemos un “BUILD” en condiciones que puede tener algo más de sentido, ante un cambio en la consola (Console Output) de Jenkins quedará registrado todo:

C:Program Files (x86)Jenkinsjobsmacrolanworkspace>"C:Program FilesIISMicrosoft Web Deploy V3msdeploy.exe" -AllowUntrusted -verb:sync -source:contentPath="C:Program Files (x86)Jenkinsjobsmacrolanworkspace" -dest:contentPath="D:wwwrootmacrolan_prueba" -skip:objectName=dirPath,absolutePath=".git"
Info: Se omiti¢ el objeto dirPath (C:Program Files (x86)Jenkinsjobsmacrolanworkspace.git) debido a la directiva de omisi¢n 'CommandLineSkipDirective 1'.
Info: Actualizando el archivo (D:wwwrootmacrolan_pruebaREADME.md).
N£mero total de cambios: 1 (0 agregados, 0 eliminados, 1 actualizados, 0 par metros cambiados, 22 bytes copiados)
C:Program Files (x86)Jenkinsjobsmacrolanworkspace>exit 0
Finished: SUCCESS

Aun así, aunque esto ya tiene algún sentido, todavía no hemos rasgado ni un 1% de lo que Jenkins puede hacer por nosotros, asi que cuando nos deje de doler la cabeza seguiremos investigando…

Un comentario en “Metiendo Jenkins con calzador”

Comentarios cerrados.