tag:blogger.com,1999:blog-29251272535431134732024-03-13T08:11:42.493-03:00.:: Pepo ::.echo "c/o/s/a/s/#s/o/b/r/e/#/l/i/n/u/x/,#p/y/t/h/o/n/,#n/o/d/e/./j/s,#a/n/d/r/o/i/d/././.#a/n/d#/a/l/l#/t/h/a/t#j/a/z/z"|sed -e's/\///g;s/#/ /g' <br>cosas sobre linux, python, node.js, android... and all that jazzPepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-2925127253543113473.post-56437074249362858152012-06-28T01:08:00.000-03:002012-06-28T01:10:11.782-03:00Analizando mails desde logs en Postfix<link href="http://google-code-prettify.googlecode.com/svn/trunk/styles/sunburst.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript">
</script>
<br>
Este es un pequeño script en bash, para analizar los mails enviados por determinado usuario a partir del archivo de log del postfix, no es lo optimo pero funciona :D<br />
<br />
<br />
<pre class="prettyprint">
#!/bin/bash
echo "Buscando mail de: $1"
for i in $(grep sasl_username=$1 /var/log/maillog | awk '{print $6}'| cut -c -12); do grep $i /var/log/maillog| grep -E "from=|to="|awk '{if ($7 ~ "from"){ print "\n" $7 }else if ($7 ~ "to"){print $7}}';done
</pre>
<br />
<br />
<script>
prettyPrint();
</script>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0Buenos Aires, Autonomous City of Buenos Aires, Argentina-34.6037232 -58.3815931-34.7082817 -58.5395216 -34.499164699999994 -58.223664600000006tag:blogger.com,1999:blog-2925127253543113473.post-54305948527289653542012-04-09T14:28:00.001-03:002012-04-09T14:30:22.751-03:00La mejor explicación sobre Closures JavascriptExplicar como funcionan los <i>closures</i> en javascript no es una tarea de una sola vez, siempre surgen dudas y hay que volverlo a explicar. Por eso les dejo está porción del video de Alex Russell (@slightlylate on Twitter) del google IO 2011, en el que explica de forma simple y muy precisa como funciona está técnica y sobre todo por qué es tan importante manejarla.<br />
<br />
Espero que lo encuentren tan útil como yo...<br />
<br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/seX7jYI96GE&start=613&end=747"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/seX7jYI96GE&start=613&end=747" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object> <div style="text-align: right; margin-top: 3px; width: 425px; height: 344px;"><a href="http://splicd.com" style="color: rgb(85, 85, 85); font-size: 13px; text-decoration: none; font-family: Helvetica,sans-serif;">powered by <span style="color: rgb(200, 91, 0);">Splicd.com</span></a></div>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0Ciudad Autónoma de Buenos Aires, Argentina-34.6084175 -58.373161299999992-34.6977235 -58.471314799999995 -34.5191115 -58.27500779999999tag:blogger.com,1999:blog-2925127253543113473.post-69168232112505782432012-03-21T17:55:00.000-03:002012-03-21T17:55:16.153-03:00[en] Twitter Notify Me - Desktop notifications for twitter<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpqMjgHeRB46D4lOip-L1hUAZV6Erb5gl191Q0CJDWEGDV94M86CHlRIlizIvaLbJ4j1QVQYFtGbBvlC1Y86dU_MKkLvj4G4f-2fNF1IDh4xx3cLyabVNp9IwZKII-ARTSUghQe-uRim6E/s1600/Screen_shot.png" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="200" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpqMjgHeRB46D4lOip-L1hUAZV6Erb5gl191Q0CJDWEGDV94M86CHlRIlizIvaLbJ4j1QVQYFtGbBvlC1Y86dU_MKkLvj4G4f-2fNF1IDh4xx3cLyabVNp9IwZKII-ARTSUghQe-uRim6E/s320/Screen_shot.png" /></a></div><p> Digging about another project that requires sending messages via D-Bus I decided to make this simple app, that shows a notification of my recent tweets (your) <i> timeline </i>, and with this I can be updated about what's going on twitter while you do your daily tasks ...<br />
</p><p> It was originally madeonly for Linux environments, because in my work I have ubuntu, but then with the help of @dual3nigma decided port to mac and window$ using growl.<br />
</p><p> The app requires the libnotify library for Linux environments and growl for Mac / Window$, was made with Node.js and the code is available at <a href="https://github.com/pepoviola/Twitter-notifyme" target="_Blank">Github</a> where you will find all the steps to install and use.<br />
</p>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-53364247648242231362012-03-21T17:44:00.001-03:002012-03-21T17:53:28.362-03:00Twitter Notify Me - Desktop notifications for twitter<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNUf03MXqmtgwUdescaY9ylXg0Si1rOs7TUZyYF1A5HlEBSlcU9Fu6IHySY9sEz0TKyOtc46LYLrvYPz-2ZshCkNniZNMKblu6GsED-0-oiVQPPViE_YSWAuFMOBdRpgybF87tPLVwjy_L/s1600/Screen_shot.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNUf03MXqmtgwUdescaY9ylXg0Si1rOs7TUZyYF1A5HlEBSlcU9Fu6IHySY9sEz0TKyOtc46LYLrvYPz-2ZshCkNniZNMKblu6GsED-0-oiVQPPViE_YSWAuFMOBdRpgybF87tPLVwjy_L/s320/Screen_shot.png" width="320" /></a></div><br />
<p>Indagando sobre otro proyecto que requiere envio de mensajes a través de D-Bus se me ocurrió hacer esta simple app, que me mustra en un cuadro de notificación los últimos tweets de mi (tu) <i>timeline</i>, y con esto poder estar actualizado de lo que pasa en twitter al mismo tiempo que haces tus tareas diarias...<br />
</p><p>En un principio fue realizada sólo para entornos linux, ya que en mi trabajo tengo ubuntu, pero luego con la ayuda de @dual3nigma decidí portalo a mac y window$ utilizando growl.<br />
</p><p>La app require de la librería libnotify en entornos linux y de growl para Mac / Window$, fue realizada con Node.js y el código está disponible en <a href="https://github.com/pepoviola/Twitter-notifyme" target="_Blank">Github</a> en donde encontrará todos los pasos para instalarla y usarla.<br />
</p>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-36476682367527173792012-03-15T17:43:00.001-03:002012-03-15T17:53:58.912-03:00#02 Manejo de rutas con Express framework<link href="http://google-code-prettify.googlecode.com/svn/trunk/styles/sunburst.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript"></script><br />
Este es el segundo post de la serie sobre node.js (socket.IO y mongoDB), si no lo hicieron lean el primero <a href="http://javierviola.blogspot.com/2012/03/en-01-express-framework-basic-config.html" target="_Blank"> post #1</a>.<br />
<br />
Este capitulo es sobre el manejo de rutas, como ya sabrán cuando creamos nuestro servidor (en nuestro caso usando express) debemos declarar las rutas que manejaremos, y si bien esto a primera vista parece fácil hay algunas cosas a tener en cuenta.<br />
<br />
</br><br />
Comencemos con algo simple, establecer la respuesta para la ruta "/"<br />
</br><br />
<blockquote class="tr_bq"><pre class="prettyprint">app.get('/',function(req,res){
res.write('handler : / \n');
res.end();
});
</pre></blockquote><br />
<br />
Con lo anterior establecemos como manejaremos un requerimiento de nuestro <i>index (ej: http://javierviola.blogspot.com) </i> y que para este post en particular responderemos simplemente con el texto <i>handler : /</i>.<br />
<br />
<br />
Antes de seguir una aclaración, para demostrar el uso de rutas utilice simplemente los métodos <i>res.write y res.end</i> con el fin de imprimir la función que respondió el requerimiento y los parámetros pasados.<br />
<br />
<br />
Habiendo dicho eso, sigamos...<br />
<br />
Probamos la ruta / <br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl localhost:3000
handler : /
lucaMac:02-Routes pepo$ curl localhost:3000/
handler : /
</pre></blockquote>Vemos que responde a los dos requerimientos, ya que express se encarga de esa última barra (/) por nosotros.<br />
<br />
Ahora imaginemos que nuestra aplicación maneja usuarios, por lo que definimos lo siguiente: <br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">app.get('/users/:id?',function(req,res){
res.write('handler: /users/:id? \n');
res.write('parametros: \n');
for(key in req.params){
res.write('\t'+key+' : '+req.params[key]);
}
res.write('\n');
res.end();
});
</pre></blockquote><br />
<br />
Esto nos permitiría responder tanto a un <i>GET</i> de /users como a /users/12 o /users/pedro, y esto es posible porque el primer parámetro de la funci&oacuet;n get express lo utiliza como una expresión regular, por lo cual esta definición puede servir para lista todos los usuarios, algun usuario o los usuarios que matcheen con el valor de :id.<br />
<br />
Y esto es posible porque :id define un <i>placeholder</i> lo cual nos permite acceder al valor a través del objeto <i>req.params</i>.<br />
<br />
Veamos las diferentes respuestas:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl localhost:3000/users
handler: /users/:id?
parametros:
id : undefined
lucaMac:02-Routes pepo$ curl localhost:3000/users/pedro
handler: /users/:id?
parametros:
id : pedro
lucaMac:02-Routes pepo$ curl localhost:3000/users/25
handler: /users/:id?
parametros:
id : 25
</pre></blockquote>También podemos definir varios <i>placeholders</i> simplemente cambiando el primer argumento:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">app.get('/users/:id/:action',function(req,res){
res.write('handler: /users/:id \n');
res.write('parametros: \n');
for(key in req.params){
res.write('\t'+key+' : '+req.params[key]+'\n');
}
res.end();
});
</pre></blockquote>Lo cual nos permite acceder a los parámetros id y action.<br />
<br />
Y si bien esto es muy útil, podemos hacer cosas más complejas gracias a las <i>regex</i> como por ejemplo:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">app.get('/users/:id([0-9]+)/:action(edit|delete|create)',function(req,res){
res.write('handler: /users/:id \n');
res.write('parametros: \n');
for(key in req.params){
res.write('\t'+key+' : '+req.params[key]+'\n');
}
res.end();
});
</pre></blockquote>Y como pueden observar, aquí no sólo accedemos a id y action, sino que restringimos el primero a que sea numérico y damos tres opciones para el segundo, gracias a las regex :) <br />
<br />
Veamos como funciona:<br />
<blockquote class="tr_bq"><pre class="prettyprint">curl localhost:3000/users/25/edit
handler: /users/:id
parametros:
id : 25
action : edit
lucaMac:02-Routes pepo$ curl localhost:3000/users/25/delete
handler: /users/:id
parametros:
id : 25
action : delete
lucaMac:02-Routes pepo$ curl localhost:3000/users/25/del
Cannot GET /users/25/del
lucaMac:02-Routes pepo$ curl localhost:3000/users/pedro/delete
Cannot GET /users/pedro/delete
</pre></blockquote>Como vemos funciona y si la regex no se cumple <i>404</i> no se puede encontrar....<br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl localhost:3000/users/pedro/delete -I
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Type: text/plain
Connection: keep-alive
</pre></blockquote><span style="font-size:12px;color:red">* Ya veremos al final una posibilidad de manejar esto de una forma más pro</span><br />
<br />
<br />
<br />
<br />
Bueno ya manejamos los <i>GETs</i> ahora queremos manejar los <i>POSTs</i> para ello definimos: <br />
<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">app.post('/users',function(req,res){
res.write('handler post: /users/ \n');
res.write('parametros en body: \n');
for(key in req.body){
res.write('\t'+key+' : '+req.body[key]+'\n');
}
res.end();
});
</pre></blockquote>Y en este caso nos valemos del middleware <i>bodyParser</i> que nos permite acceder a los valores pasados a través del objeto req.body.<br />
<br />
Una cosa interesante de express es que nos ofrece el middleware <i>methodOverride</i> que nos permite ser más semántico en nustras rutas, ya que no permite que un <i>POST</i> sea transformado en un <i>PUT</i> o </DELETE> y así ser manejado por app.put o app.delete respectivamente...<br />
<br />
Para ello veamos la siguiente definición:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">/* post */
app.post('/users',function(req,res){
res.write('handler post: /users/ \n');
res.write('parametros en body: \n');
for(key in req.body){
res.write('\t'+key+' : '+req.body[key]+'\n');
}
res.end();
});
/* We can use put to be more semantics, like a RESTful api.
For this be use the middleware methodOverride, this
middleware check for the input _method in the body
(this input could be hidden for don't show to the
end user), and if its present tranform the post in the
_method input value and don't pass this in req.body
*/
app.put('/users',function(req,res){
res.write('handler put: /users/ \n');
res.write('parametros en body: \n');
for(key in req.body){
res.write('\t'+key+' : '+req.body[key]+'\n');
}
res.end();
});
/* delete, as in put we can use methodOverride to be
more semantic
*/
app.delete('/users',function(req,res){
res.write('handler delete: /users/ \n');
res.write('parametros en body: \n');
for(key in req.body){
res.write('\t'+key+' : '+req.body[key]+'\n');
}
res.end();
});
</pre></blockquote>Como vemos definimos la misma ruta para los tres <i>verbos</i> http (POST,PUT,DELETE), y gracias al middleware methodOverride atender cada uno de ellos según el valor del input <i>_method</i> que se pase, y para explicarlo mejor un ejemplo:<br />
<br />
Un post común:</br> <br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl -X POST -d "id=32&action=delete" localhost:3000/users/
handler post: /users/
parametros en body:
id : 32
action : delete
</pre></blockquote>Un post, pero que será respondido como put:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl -X POST -d "id=32&action=delete&_method=put" localhost:3000/users/
handler put: /users/
parametros en body:
id : 32
action : delete
</pre></blockquote><span style="color:blue;">vean como se pasa el valor de _method para que el middleware sobreescriba el método</span><br />
<br />
Y por último el mismo post, pero respondido como delete<br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl -X POST -d "id=32&action=delete&_method=delete" localhost:3000/users/
handler delete: /users/
parametros en body:
id : 32
action : delete
</pre></blockquote>Y con esto queda explicado el middleware...<br />
<br />
Una cosa importante a tener en cuenta es que las rutas se procesan secuencialmente y en la ubicación que fueron declaradas, es por eso que es muy importante hacer una declaración ordenada de nuestras rutas para que cada requerimiento sea atendido por la ruta que queramos y no por otra<br />
<br />
<br />
Y haciendo uso de esto último, y utilizando un <i>wildcard</i> podemos manejar los errores <i>404</i> de una forma simple con esta ruta al final de todo:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">app.all('*',function(req,res){
res.write('handler all: *\n');
res.write('ERR, no regex match\n');
res.end();
});
</pre></blockquote>De esta forma atenderemos cualquier ruta (*) y en cualquier <i>verbo</i> http que no haya sido manejada anteriormente, con lo cual es muy útil para servir errores 404<br />
<br />
Veamos como funciona:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">lucaMac:02-Routes pepo$ curl -X POST -d "id=32&action=delete" localhost:3000/users/dasdsdas
handler all: *
ERR, no regex match
lucaMac:02-Routes pepo$ curl -X GET -d "id=32&action=delete" localhost:3000/usedasd
handler all: *
ERR, no regex match
</pre></blockquote><br />
Espero que haya sido claro en como es el uso de rutas con express y cualquier cosa no duden en contactarme<br />
Les dejo el código utilizado <a href="https://github.com/pepoviola/Blog-Posts/tree/master/02-Routes" target="_blank"> Código en Github </a><br />
<br />
Hasta la próxima (con la explicación de como funcionan los middlewares :) )<br />
<br />
<br />
<script>
prettyPrint();
</script>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com1tag:blogger.com,1999:blog-2925127253543113473.post-90859986423406896602012-03-09T00:32:00.001-03:002012-03-15T15:44:46.989-03:00[en] #01 Express framework basic config<link href="http://google-code-prettify.googlecode.com/svn/trunk/styles/sunburst.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript">
</script><br />
This series of posts, are related to the previous post <a href="http://javierviola.blogspot.com/2012/02/nodejs-socketio-mongodb-real-time-apps.html" target="_blank"> node.js apps with real time </a> which explains how to install the necessary components to develop an application with node.js + socket.IO + MongoDB.<br />
But along the way I thought best to start with some basics, and from them be adding complexity until an application (I have not yet defined, hearing ideas...) which makes use of socket.IO for real-time interactions.<br />
<br />
Well, let's start with a very basic introduction to <a href="http://expressjs.com/" target="_blank"> Express frameworks</a>.<br />
This framework is widely used and perfectly combines with socket.IO, is very simple to use and brings many things "out of the box" ready to use.<br />
<br />
The first thing we do is create the environment where we will develop this demo, we created the directory for this application and within the structure we create the following subdirectories:<br />
<blockquote class="tr_bq"><pre class="prettyprint">pepo@frank3:~$ mkdir 01-basic_express && cd 01-basic_express
pepo@frank3:~$ mkdir views
pepo@frank3:~$ mkdir node_modules
pepo@frank3:~$ mkdir -p public/img
pepo@frank3:~$ mkdir -p public/css
pepo@frank3:~$ mkdir -p public/js
</pre></blockquote>I will explain each directory use:<br />
<blockquote><span style="color: blue;">views</span> : The directory where our templates lives<br />
<span style="background-color: white; color: blue;">node_modules</span> : Where were installed modules it will use<br />
<span style="color: blue;">public</span> : Content css, js, imagenes,etc.</blockquote><br />
once created the directories, open our favorite editor to start developing our app.<br />
The content of this simple example is:<br />
<blockquote class="tr_bq"><pre class="prettyprint">/**
* Module dependencies.
*/
var express = require('express');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view options', {
layout: false
});
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
// Routes
app.get('/',function(req,res){
res.render("index",{
title: "01 - basic express ",
banner: "Hello from template!"
});
});
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
</pre></blockquote><br />
Now we are going to analyze these lines:<br />
<blockquote><pre class="prettyprint">var express = require('express');
var app = module.exports = express.createServer();
</pre></blockquote>In these two lines load the module you need and call the function <span style="color: blue;"> createServer </span> we return an object with the web server will use to listen to requests and answer them.<br />
<br />
Then we go to its configuration, which are the following lines<br />
<blockquote><pre class="prettyprint">// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view options', {
layout: false
});
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
</pre></blockquote>They first set the directory <span style="color: blue;"> / views </span> as a repository of templates, for this we use a variable defined globally node.js runtime is __dirname whose value is a string with the absolute path of the directory of your app.<br />
Then we set to "ejs" as our engine for rendering templates, so remember to install the module via npm (npm install ejs).<br />
The final set is to establish that we will not use a layout file for this example, if we wanted we could have a database file for all of our templates or for use only for some pages.<br />
Then we declare the Middlewares we will use the first <span style="color: blue;"> express.bodyParser () </span> is used for parsing of the post (either json or not) and you return the result parses the variable accessible via <span style="color: blue;"> req.body </span>, the following is <span style="color: blue;"> express.methodOverride () </span> that is important to be declared after <span style="color: blue;"> express.bodyParser () </span> because it performs a check on the variable <span style="color: blue;"> req.body </span>, this middleware is useful to override the methods of our forms, just an input field with the hidden attribute, like this:<br />
<blockquote><pre class="prettyprint"><form action="/" method="post">
<input name="_method" type="hidden" value="put" />
<input name="user[name]" type="text" />
<input type="submit" value="Submit" />
&nbsp;&nbsp;&nbsp; </form>
</pre></blockquote>That will allow us to access the post as follows:<br />
<blockquote><pre class="prettyprint">app.put('/', function(){
console.log(req.body.user);
});
</pre></blockquote>Then we declare the use of <span style="color: blue;"> app.router </span> which is simply the middleware that contains all the paths defined, and performs route lookup based on the URL of the current request and the HTTP method.<br />
And finally declare the directory from where we provide our static content <span style="color: blue;"> express.static (__dirname + '/ public') </span>, this allows us to access our resources (in the directory <span style="color: blue;"> public </span>) directly referencing it as <span style="color: blue;"> <link href="/css/style.css" rel="stylesheet" type="text/css"></link> </span>, note that there is no need to reference the directory <span style="color: blue;"> public </span> but directly we refer to directories in there<br />
<br />
Well, with this we have our first app using node & Express, the code in this first post is on Github <a href="https://github.com/pepoviola/Blog-Posts" target="_blank"> Posts </a><br />
<br />
<script>
prettyPrint();
</script><br />
Until next time!Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com2tag:blogger.com,1999:blog-2925127253543113473.post-83985114657765740112012-03-08T11:06:00.002-03:002012-03-12T14:51:00.562-03:00[en] GitHub hacked... so we have to audit SSH keys<blockquote><br />
lucaMac:nodeapps pepo$ git clone git@github.com:pepoviola/Socket.IO_rooms.git<br />
Cloning into Socket.IO_rooms...<br />
ERROR: Hi pepoviola, it's GitHub. We're doing an SSH key audit.<br />
Please visit https://github.com/settings/ssh/audit/1767330<br />
to approve this key so we know it's safe.<br />
Fingerprint: 7c:(...):54<br />
fatal: The remote end hung up unexpectedly<br />
<br />
</blockquote>Yes, I had read the news that they had exploited a vulnerability that allowed update rails attributes inserting a new SSH key for more detail can read these links [0].<br />
<br />
Therefore began an audit GitHub SSH key, for it asks that we enter the link listed above ("Please visit https://github.com/settings/ssh/audit/1767330") to approve or reject our key now ... If you have multiple keys as I uploaded to github, since different machines rub shoulders and this means that you must enter each machine and check if the ssh fingerprint is correct or not. Which brings us to what inspired me to write this post, i dont know if everyone knows how to read your fingerprint to validate the github presented to us, if do not know it I leave here a simple explanation.<br />
<br />
The first thing to know is where is our public key, which usually is in the path <i> ~/.ssh/ </i> (/home/[user]/.ssh) with the name <i> id_rsa.pub, </i> when you have found this file must run the following command<br />
<blockquote>ssh-keygen -lf ~/.ssh/id_rsa.pub<br />
2048 7c: (...): 54 /Users/pepo/.ssh/id_rsa.pub (RSA) </blockquote>Which we will return three fields, the first is the size, the second is our fingerprint and is ultimately the public key file.<br />
<br />
<br />
I hope it was useful and approved yours ssh key on github : D<br />
<br />
Links<br />
[0]<br />
<a href="https://github.com/rails/rails/commit/b83965785db1eec019edf1fc272b1aa393e6dc57" target="_blank">homakov commit</a> (very funny comments)<br />
<a href="https://gist.github.com/1978249" target="_blank"> how to</a> Gist explaining how the vulnerability was exploited<br />
<a href="http://thehackernews.com/2012/03/github-hacked-with-ruby-on-rails-public.html" target="_blank"> thehackernews</a>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-12606949474842836262012-03-08T10:35:00.001-03:002012-03-08T10:44:28.626-03:00GitHub hacked... asique vamos a auditar claves SSH<blockquote><br />
lucaMac:nodeapps pepo$ git clone git@github.com:pepoviola/Socket.IO_rooms.git<br />
Cloning into Socket.IO_rooms...<br />
ERROR: Hi pepoviola, it's GitHub. We're doing an SSH key audit.<br />
Please visit https://github.com/settings/ssh/audit/1767330<br />
to approve this key so we know it's safe.<br />
Fingerprint: 7c:(...):54<br />
fatal: The remote end hung up unexpectedly<br />
<br />
</blockquote>Así es, había leido de la noticia de que habían explotado una vulnerabilidad de rails que permitía <i>updetear</i> los atributos insertando una nueva key de SSH, para más detalle puede leer estos links [0].<br />
<br />
Por lo tanto Github comenzó una auditoria de claves SSH, para ello nos pide que ingresemos al link que figura arriba (" Please visit https://github.com/settings/ssh/audit/1767330 "), para aprobar o <i>rejectar </i>nuestras claves, ahora... Si tu tienen como yo varias claves subidas a github, ya que <i>codeas</i> e diferentes maquinas esto representa que debes ingresar a cada maquina y chequear si el fingerprint de ssh es correcto o no. Lo cual nos trae a lo que me inspiró a escribir este post, que es que no sé si todo el mundo sabe como leer su fingerprint para validarlo con los que nos presenta github, si no lo saben les dejo aquí una simple explicación.<br />
<br />
Lo primero que debemos saber es donde se encuentra nuestra llave pública, que por lo general se encuentra en el path <i>~/.ssh/</i> (/home/[user]/.ssh) con el nombre <i>id_rsa.pub, </i>una vez localizado este archivo debemos ejecutar el siguiente comando<br />
<blockquote>ssh-keygen -lf ~/.ssh/id_rsa.pub <br />
2048 7c:(...):54 /Users/pepo/.ssh/id_rsa.pub (RSA)</blockquote>El cual nos devolverá tres campos, el primero es el tamaño, el segundo es nuestro fingerprint y por último es archivo de la clave pública.<br />
<br />
Buenos, espero que les haya servido y a aprobar claves ssh en github :D<br />
<br />
<br />
<br />
<br />
<br />
Links<br />
[0]<br />
<a href="https://github.com/rails/rails/commit/b83965785db1eec019edf1fc272b1aa393e6dc57" target="_blank">homakov commit</a> (Muy divertidos los comentarios)<br />
<a href="https://gist.github.com/1978249" target="_blank"> how to</a> Gist que explica como se explotó la vulnerabilidad<br />
<a href="http://thehackernews.com/2012/03/github-hacked-with-ruby-on-rails-public.html" target="_blank">noticia en thehackernews</a>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-47525753539793402512012-03-06T11:08:00.000-03:002012-03-06T11:08:19.844-03:00#01 Uso básico de Express framework<link href="http://google-code-prettify.googlecode.com/svn/trunk/styles/sunburst.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript"></script><br />
Esta serie de post, tienen relación con el post anterior <a href="http://javierviola.blogspot.com/2012/02/nodejs-socketio-mongodb-real-time-apps.html" target="_blank">real time apps con node.js</a> el cual explica como realizar la instalación de los componentes necesarios para desarrollar una aplicación con node.js + mongoDB + socket.IO.<br />
Pero en el camino me pareció mejor comenzar con algunas cosas básicas, y a partir de ellas ir sumando complejidad hasta lograr una aplicación (que todavía no tengo definida cual sera, se escuchan ideas) que haga uso de socket.IO para las interacciones en tiempo real.<br />
<br />
Bueno, vamos a comenzar con una introducción muy básica a frameworks <a href="http://expressjs.com/" target="_blank">Express</a>.<br />
Este framework es muy utilizado y se combina a la perfección con socket.IO, es muy simple de utilizar y trae muchas cosas "out of the box" lista para utlizar.<br />
<br />
Lo primero que vamos a hacer es crear el entorno donde desarrollaremos este demo, para ello creamos el directorio de la aplicación y dentro de el creamos la siguiente estructura de subdirectorios:<br />
<br />
<blockquote class="tr_bq"><pre class="prettyprint">pepo@frank3:~$ mkdir 01-basic_express && cd 01-basic_express
pepo@frank3:~$ mkdir views
pepo@frank3:~$ mkdir node_modules
pepo@frank3:~$ mkdir -p public/img
pepo@frank3:~$ mkdir -p public/css
pepo@frank3:~$ mkdir -p public/js
</pre></blockquote><br />
Paso a explicar para que utilizares cada directorio:<br />
<br />
<blockquote><span style="color: blue;">views</span> : Es el directorio donde alojaremos nuestros templates<br />
<span style="background-color: white; color: blue;">node_modules</span> : Donde se instalaran los módules que utilizaremos<br />
<span style="color: blue;">public</span> : Directorio de contenido, aquí alojaremos nuestros css, js, imagenes, etc.</blockquote><br />
Una vez creados los directorios, abrimos nuestro editor preferido para comenzar a desarrollar nuestra app.<br />
El contenido de este simple ejemplo es:<br />
<blockquote class="tr_bq"><pre class="prettyprint">/**
* Module dependencies.
*/
var express = require('express');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view options', {
layout: false
});
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
// Routes
app.get('/',function(req,res){
res.render("index",{
title: "01 - basic express ",
banner: "Hello from template!"
});
});
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
</pre></blockquote><br />
Ahora vamos a ir analizando estas líneas:<br />
<br />
<blockquote><pre class="prettyprint">var express = require('express');
var app = module.exports = express.createServer();
</pre></blockquote>En estas dos líneas cargamos el módulo que necesitamos y llamamos a la función <span style="color: blue;">createServer</span> que nos retorna un objeto con el servidor web que utilizaremos para escuchar las peticiones y responderlas.<br />
<br />
Luego pasamos a la configuración del mismo, que son las siguientes líneas<br />
<blockquote><pre class="prettyprint">// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view options', {
layout: false
});
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
</pre></blockquote>En ellas primero establecemos el directorio <span style="color: blue;">/views</span> como repositorio de templates, para ello usamos una variable definida globalmente en tiempo de ejecució de node.js que es __dirname cuyo valor es un string con el path absoluto del directorio de nuestra app.<br />
Luego establecemos a "ejs" como nuestro motor para renderizar los templates, para ello recordemos intalar el módulo vía npm (npm install ejs).<br />
El último set es para establecer que no utilizaremos un archivo de layout para este ejemplo, si quiesieramos podríamos tener un archivo de base para todos nuestros templates o también para utilizar sólo para algunas páginas.<br />
<br />
Luego declaramos los Middlewares que vamos a utilizar, el primero <span style="color: blue;"> express.bodyParser()</span> es utilizado para el parseo de los post (sean json o no) y nos devuelve el resultado del parsea accesible vía la variable <span style="color: blue;">req.body </span> , el siguiente es <span style="color: blue;">express.methodOverride()</span> que es importante que esté declarado después de <span style="color: blue;"> express.bodyParser()</span> ya que realiza una verificación sobre la variable <span style="color: blue;">req.body </span>, este middleware es muy útil para sobreescribir los métodos de nuestros formularios, simplemente con un campo input con el atributo hidden, algo así:<br />
<blockquote><pre class="prettyprint"><form action="/" method="post">
<input name="_method" type="hidden" value="put" />
<input name="user[name]" type="text" />
<input type="submit" value="Submit" />
&nbsp;&nbsp;&nbsp; </form>
</pre></blockquote>Que nos permitirá acceder al post de la siguiente forma:<br />
<blockquote><pre class="prettyprint">app.put('/', function(){
console.log(req.body.user);
});
</pre></blockquote><br />
Luego declaramos el uso de <span style="color: blue;">app.router</span> que es simplemente el middleware que contiene todas las rutas definidas, y realiza consulta de rutas basándose en la URL de la solicitud actual y el método HTTP.<br />
Y por último declaramos el directorio desde donde proveemos nuestro contenido estático <span style="color: blue;">express.static(__dirname + '/public')</span>, esto nos permite acceder a nustros recursos (dentro del directorio <span style="color: blue;">public</span>) directamente referenciandolo como <span style="color: blue;"><link href="/css/style.css" rel="stylesheet" type="text/css"></link> </span>, noten que no hace falta referenciar el directorio <span style="color: blue;">public</span> sino que directamente hacemos referencia a los directorios dentro del mismo.<br />
<br />
Bueno y con esto tenemos nuestra primera app utilizando node & Express, el código de este primer post se encuentra en Github <a href="https://github.com/pepoviola/Blog-Posts" target="_blank">Posts</a><br />
<br />
Hasta la próxima! <br />
<br />
<script>
prettyPrint();
</script>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-45887862120218899522012-03-04T18:43:00.004-03:002012-03-05T17:55:38.269-03:00[ en ] Working with node.js and MySQL<!--<link href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" rel="stylesheet" type="text/css"></link>--><br />
<link href="http://google-code-prettify.googlecode.com/svn/trunk/styles/sunburst.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript">
</script><br />
This is a small article about how to use node.js as web server to display the results of a query to a MySQL database engine.<br />
The first thing to do is to check is that we have installed the mysql module to run it the following:<br />
<br />
<pre class="prettyprint">lucaMac:BLOG_POSTs pepo$ node
> var Client = require('mysql').Client
Error: Cannot find module 'mysql'
at Function._resolveFilename (module.js:332:11)
at Function._load (module.js:279:25)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at repl:1:14
at REPLServer.eval (repl.js:80:21)
at repl.js:190:20
at REPLServer.eval (repl.js:87:5)
at Interface.<anonymous> (repl.js:182:12)
at Interface.emit (events.js:67:17)
>
</anonymous></pre>If fails, proceed to install the module via npm:<br />
<br />
npm install mysql<br />
<br />
<br />
<br />
The first thing we do is create the object for the query:<br />
<br />
<blockquote><pre class="prettyprint">var Client = require('mysql').Client,
client = new Client();
client.user = 'user';
client.password = 'password';
client.host='127.0.0.1';
client.port='3306';
client.database='database_name'
client.connect();
</pre></blockquote><br />
then create the web server<br />
<br />
<br />
<blockquote><pre class="prettyprint">var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
</pre></blockquote><br />
And within this we perform the query, and associate to its callback function<br />
<br />
<blockquote><pre class="prettyprint">client.query(
"select * from table where campo1 > 1 limit 10;",
function select(err, results, fields) {
if (err) {
console.log("Error: " + err.message);
throw err;
}
</pre></blockquote>print data to the console and the web response<br />
<br />
<br />
<blockquote><pre class="prettyprint">console.log("Number of rows: "+results.length);
console.log(results);
for (var i in results){
var result = results[i];
res.write(result.campo1+"\n");
}
res.end();
});
</pre></blockquote>We finished the code, setting up a port for listening <br />
<br />
<blockquote><pre class="prettyprint">}).listen(1337, "0.0.0.0");
console.log('Server running ');
</pre></blockquote><br />
<br />
The finished script is like this:<br />
<br />
<blockquote><pre class="prettyprint">var Client = require('mysql').Client,
client = new Client();
client.user = 'user';
client.password = 'password';
client.host='127.0.0.1';
client.port='3306';
client.database='DB'
client.connect();
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
client.query(
"select * from table where campo1 > 1 limit 10;",
function select(err, results, fields) {
if (err) {
console.log("Error: " + err.message);
throw err;
}
console.log("Number of rows: "+results.length);
console.log(results);
res.write(results);
for (var i in results){
var result = results[i];
res.write(result.campo1+"\n");
}
res.end();
});
}).listen(1337, "0.0.0.0");
console.log('Server running ');
</pre></blockquote>If you want to download this is the link to the <a href="http://bit.ly/xaBAK1" target="_blank"> gist </a><br />
<br />
<script>
prettyPrint();
</script>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com2tag:blogger.com,1999:blog-2925127253543113473.post-21882956830855338332012-03-01T10:32:00.001-03:002012-03-01T10:33:01.469-03:00[en] node.js + socket.IO + mongoDB = real time apps Part 1<link href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript">
</script><br />
<br />
Part 1: Setting the environment ....<br />
<br />
A few days ago I finished a simple application <a href="http://tweetland.com.ar/" target="_blank">tweetland.com.ar</a> I made in order to learn more about <a href="http://nodejs.org/" target="_blank">Node.js</a> and <a href="http://www.mongodb.org/" target="_blank"> MongoDB </a> ... on the road I also came across <a href="http://socket.io/" target="_blank"> Socket.IO </a> which is a great library for real time applications.<br />
The first is to prepare the environment. To do this first download node.js (from <a href="http://nodejs.org/#download" target="_blank"> node.js </a>), after downloading the installation follows the traditional steps:<br />
<blockquote class="tr_bq"><pre class="prettyprint">./configure
make
make install *</blockquote>* <span style="font-size: x-small;">the last step as root</span>
</pre>Once installed, continue with the installation of modules. For this node has <a href="http://npmjs.org/" target="_blank"> npm </a> (which is Node Package Manager) that allows us to install the modules with a single command install npm <module>. Instructions for installing npm are in your home page, also I leave <br />
<blockquote class="tr_bq"><code>curl http://npmjs.org/install.sh | sh</code></blockquote>At this time we have installed both node.js as its package manager npm. Usually what I usually do is create a directory in my case I call nodeapps as workspace.<br />
Entering the same:<br />
<blockquote class="tr_bq"><pre class="prettyprint">cd "path to nodeapps"
</pre></blockquote>and within it begin to install the modules you require. This is important because when you install the modules npm node_modules create the directory (if not there before), and install the modules in that directory.<br />
This is important because when we do within our code something like:<br />
<blockquote class="tr_bq"><pre class="prettyprint">var sys = require('sys');
</pre></blockquote>node will automatically search the directory sys module within node_modules in the current directory and not finding it will continue with the search recursively upwards, which is always important to remember where you installed the modules that we use.<br />
<br />
Before going further make the installation of some modules used, these are express, socket.io, mongoose.<br />
<br />
And this is precisely the last module we will use to interact with our database MongoDB, which is an object-oriented database (JSON), high performance and scalable. (in another post I will explain a little more how it works because it is a relatively new and very interesting).<br />
To install you have to download the appropriate version from <a href="http://www.mongodb.org/downloads" MongoDB target="_blank"> download </a>, and once discharged, proceed to decompress<br />
<blockquote class="tr_bq"><br />
pepo@sokol:~/DESARROLLO/POSTS/node_socket_mongo$ wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.2.tgz<br />
<br />
2012-02-28 11:42:19 (1.06 MB/s) - `mongodb-linux-i686-2.0.2.tgz' saved [38157227/38157227]<br />
<br />
pepo@sokol:~/DESARROLLO/POSTS/node_socket_mongo$ tar -xzf mongodb-linux-i686-2.0.2.tgz </blockquote>Once unpacked and could start the service mongod and start, but I'd rather create the directory structure I will use my base, create two directories for data and logs, the first store the files of the database and the second of logs. I also create the configuration file with which I will start the service, in my case is as follows:<br />
<blockquote class="tr_bq"><pre class="prettyprint">cat mongod.config
dbpath = /home/pepo/nodeapps/data/
logpath =/home/pepo/nodeapps/logs/mongodb.log
bind_ip = 127.0.0.1
noauth = true
verbose = true
</pre></blockquote> Bind_ip option is set to only listen on localhost requests (since by default it does on all interfaces) and indicate that we will not configure the authentication and verbose.<br />
<br />
To start the service simply run:<br />
<blockquote class="tr_bq"><pre class="prettyprint">bin/mongod --config mongod.config *
</pre></blockquote>* <span style="font-size: x-small;">Inside the unzipped directory MongoDB</span><br />
<br />
<span style="font-size: x-small;"><span style="font-size: small;">we see something like this:</span></span><br />
<blockquote class="tr_bq"><pre class="prettyprint"><span style="font-size: x-small;"><span style="font-size: small;"> # mongodb-linux-i686-2.0.2/bin/mongod --config mongod.config
all output going to: ./logs/mongodb.log</span></span>
</pre></blockquote>Finally to test the service entered as follows (always from the binary directory MongoDB):<br />
<blockquote class="tr_bq"><pre class="prettyprint">pepo@sokol:bin$ ./mongo
MongoDB shell version: 2.0.2
connecting to: test
> show dbs
local (empty)
</pre></blockquote>Well, with this we have our environment set up and configured to start programming applications in node.js with MongoDB, but that will be for the next post....<br />
<blockquote class="tr_bq"><span style="font-size: x-small;"><span style="font-size: small;"> </span> </span> </blockquote><br />
<script>
prettyPrint();
</script>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com1tag:blogger.com,1999:blog-2925127253543113473.post-56096959016481295062012-02-28T12:15:00.000-03:002012-02-28T12:15:36.115-03:00node.js + socket.IO + mongoDB = real time apps (parte 1)<link href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" rel="stylesheet" type="text/css"></link><br />
<script src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js" type="text/javascript">
</script><br />
<br />
Parte 1: Preparando el ámbiente.... <br />
<br />
Hace unos días terminé una simple aplicación <a href="http://tweetland.com.ar/" target="_blank">tweetland.com.ar</a> que realicé con el objetivo de aprender (existe otro?) más sobre <a href="http://nodejs.org/" target="_blank">Node.js</a> y <a href="http://www.mongodb.org/" target="_blank">mongoDB</a>... en el camino también me topé con <a href="http://socket.io/" target="_blank">Socket.IO</a> que es una gran librería para realizar aplicaciones en tiempo real.<br />
<br />
Lo primero es preparar el ambiente, para ello primero descargamos node.js (desde su home page <a href="http://nodejs.org/#download" target="_blank">node.js</a>), una vez descargado la instalación sigue los pasos tradicionales:<br />
<blockquote class="tr_bq"><pre class="prettyprint">./configure
make
make install *</blockquote>* <span style="font-size: x-small;">este último como root </span>
</pre><br />
Una vez instalado, seguimos con la instalación de módulos. Para ello node cuenta con <a href="http://npmjs.org/" target="_blank">npm</a> (que es Node Package Manager) que nos permite instalar los módulos con un simple comando npm install <module>. Las instrucciones para instalar npm están en su home page, igualmente se las dejo:</module><br />
<blockquote class="tr_bq"><code>curl http://npmjs.org/install.sh | sh</code></blockquote>En este momento ya tenemos instalado tanto node.js como su manejador de paquetes npm. Por lo general lo que suelo hacer es crear un directorio, en mi caso lo llamo nodeapps, como workspace.<br />
Ingreso al mismo:<br />
<blockquote class="tr_bq"><pre class="prettyprint">cd "path to nodeapps"
</pre></blockquote>y dentro de él comienzo a instalar los modulos que requiero. Esto es importante porque al instalar los modulos npm creará el directorio node_modules (siempre y cuando no exista antes), e instalará los modulos en dicho directorio.<br />
Y esto es importante porque cuando dentro de nuestro código hagamos algo como:<br />
<blockquote class="tr_bq"><pre class="prettyprint">var sys = require('sys');
</pre></blockquote>node automáticamente buscará el módulo sys dentro de directorio node_modules en el directorio actual y de no encontrarlo seguira con la busqueda recursiva hacia arriba, por lo cual siempre es importante tener en mente donde se instalán los módulos que vamos a utilizar.<br />
<br />
Antes de seguir adelante realicen la instalación de algunos módulos que utilizaran, estos son express, socket.io, mongoose .<br />
<br />
Y este último módulo es justamente el que utilizaremos para interactuar con nuestra base de datos mongoDB, que es una base orientada a objetos (JSON), de alta performance y escalable. (en otro post explicaré un poco más como funciona ya que es una tecnología relativamente nueva y muy interesante).<br />
Para realizar la instalación tenemos que descargar la versión que corresponda desde <a href="http://www.mongodb.org/downloads" target="_blank">mongoDB download</a> , y una vez descargada la descomprimimos<br />
<blockquote class="tr_bq"><br />
pepo@sokol:~/DESARROLLO/POSTS/node_socket_mongo$ wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.2.tgz<br />
<br />
2012-02-28 11:42:19 (1.06 MB/s) - `mongodb-linux-i686-2.0.2.tgz' saved [38157227/38157227]<br />
<br />
pepo@sokol:~/DESARROLLO/POSTS/node_socket_mongo$ tar -xzf mongodb-linux-i686-2.0.2.tgz </blockquote>Una vez descomprimido ya podríamos arrancar el servicio mongod y comenzar, pero antes prefiero crear la estructura de directorios que utilizaré con mi base, para eso creo dos directorios data y logs, el primero guardará los archivos de la base de datos y el segundo los archivos de logs. También creo el archivo de configuración con el que voy a levantar el servicio, en mi caso tiene la siguiente forma:<br />
<blockquote class="tr_bq"><pre class="prettyprint">cat mongod.config
dbpath = /home/pepo/nodeapps/data/
logpath =/home/pepo/nodeapps/logs/mongodb.log
bind_ip = 127.0.0.1
noauth = true
verbose = true
</pre></blockquote> La opción bind_ip está configurada para que sólo escuche las peticiones sobre el localhost (ya que por defecto lo hace sobre todas las interfaces) e indicamos que no tendremos autenticación y configuramos el verbose.<br />
<br />
Para levantar el servicio simplemente ejecutamos:<br />
<blockquote class="tr_bq"><pre class="prettyprint">bin/mongod --config mongod.config *
</pre></blockquote>* <span style="font-size: x-small;">Dentro de directorio descomprimido de mongoDB</span><br />
<br />
<span style="font-size: x-small;"><span style="font-size: small;">Y veremos algo como:</span></span><br />
<blockquote class="tr_bq"><pre class="prettyprint"><span style="font-size: x-small;"><span style="font-size: small;"> # mongodb-linux-i686-2.0.2/bin/mongod --config mongod.config
all output going to: ./logs/mongodb.log</span></span>
</pre></blockquote><br />
Por último para probar el servicio ingresamos de la siguiente forma (siempre desde el directorio de binarios de mongoDB):<br />
<blockquote class="tr_bq"><pre class="prettyprint">pepo@sokol:bin$ ./mongo
MongoDB shell version: 2.0.2
connecting to: test
> show dbs
local (empty)
</pre></blockquote>Bueno, y con esto ya tenemos nnuestro entorno instalado y configurado para comenzar a programar aplicaciones en con node.js con mongoDB, pero eso quedará para la próxima....<br />
<br />
<blockquote class="tr_bq"><span style="font-size: x-small;"><span style="font-size: small;"> </span> </span> </blockquote><br />
<script>
prettyPrint();
</script>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com1tag:blogger.com,1999:blog-2925127253543113473.post-68117567562068464242012-02-12T21:00:00.001-03:002012-02-29T12:44:58.788-03:005 buenas herramientas para probar sitios móvilesEn este tiempo de diversas resoluciones de pantallas es cada vez más importante poder contar con buenas herramientas para probar facilmente como se un sitio en diferentes dispositivos, en este link les dejo 5 muy buenas herramientas que facilitan esa tarea.<br />
<br />
http://bit.ly/xA20TTPepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0Ciudad Autónoma de Buenos Aires, Argentina-34.6084175 -58.373161299999992-34.697109000000005 -58.47078479999999 -34.519726 -58.275537799999995tag:blogger.com,1999:blog-2925127253543113473.post-55004464314547398462011-09-28T12:16:00.000-03:002011-09-28T12:16:59.474-03:00DJANGO_SETTINGS_MODULE... The simplest way to configure!Looking for simple and efficient way to configure my environment to develop different django apps, and set the environment variable DJANGO_SETTINGS_MODULE on the fly, I found this function to bash us greatly simplifies our work.<br />
You just have to edit and add user bash_profile<br />
<blockquote>function setdsm() {<br />
# add the current directory and the parent directory to PYTHONPATH<br />
# sets DJANGO_SETTINGS_MODULE<br />
export PYTHONPATH=$PYTHONPATH:$PWD/..<br />
export PYTHONPATH=$PYTHONPATH:$PWD<br />
if [ -z "$1" ]; then <br />
x=${PWD/\/[^\/]*\/}<br />
export DJANGO_SETTINGS_MODULE=$x.settings<br />
else <br />
export DJANGO_SETTINGS_MODULE=$1<br />
fi<br />
<br />
echo "DJANGO_SETTINGS_MODULE set to $DJANGO_SETTINGS_MODULE"<br />
}<br />
</blockquote>And then from our project directory run:<br />
<blockquote>user$ setdsm</blockquote><br />
I hope this functios will be as as useful for you as is for me.<br />
<br />
<a href="http://www.juiceanalytics.com/writing/django_settings_module/"> Link to source</a>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0Ciudad Autónoma de Buenos Aires, Capital Federal, Argentina-34.6084175 -58.373161299999992-34.6977235 -58.471314799999995 -34.5191115 -58.27500779999999tag:blogger.com,1999:blog-2925127253543113473.post-77061985372862068202011-06-06T16:15:00.000-03:002011-06-06T16:15:35.902-03:00Dump object attributtes pythonUna forma simple de hacer debuging es dumpear los atributos de los obejtos que manejemos, que en el caso de python la forma más simple es:<br />
<br />
<blockquote>print object.__dict__<br />
</blockquote><br />
El cual nos imprimirá el diccionario de atributos del objeto en cuestión.-Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-8066169448531881862011-06-05T18:13:00.000-03:002011-06-05T18:13:08.476-03:00Cast an ArrayList to an Array of strings (android)Me topé con la necesidad de catear un arraylist a un array de strings desarrollando una app para android, por suerte luego de una simple búsqueda encontre la fomar más simple de realizarlo :D<br />
<br />
<blockquote>String [] myStringsArray = myArrayList.toArray(new String[myArrayList.size()]);<br />
</blockquote><br />
Lección aprendidad para un domingo :DPepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-11489414489396408402011-05-31T11:52:00.000-03:002011-10-06T11:11:23.074-03:00nodejs mysql database<p>Este es un pequeño articulo como utilizar node.js como web server para mostrar los resultados de una consulta a un motor de base de datos MySQL.<br />
</p><br />
<p>Lo primero que debemos ver es tener el módulo necesario "mysql", estoy utilizando la versión 0.5.0-pre.<br />
<br />
#node -v<br />
v0.5.0-pre<br />
</p><p><br />
Lo primero que hacemos es crear el objeto para la consulta:<br />
<br />
<blockquote>var Client = require('mysql').Client,<br />
client = new Client();<br />
client.user = 'user';<br />
client.password = 'password';<br />
client.host='127.0.0.1';<br />
client.port='3306';<br />
client.database='base_de_datos'<br />
client.connect();<br />
</blockquote></p><br />
<p>Luego creamos el servidor: <br />
<br />
<blockquote>var http = require('http');<br />
http.createServer(function (req, res) {<br />
res.writeHead(200, {'Content-Type': 'text/plain'});<br />
</blockquote><br />
Y dentro de este realizamos la consulta, y la asociamos a su función de callback<br />
<br />
<blockquote>client.query(<br />
"select * from table where campo1 > 1 limit 10;", <br />
function select(err, results, fields) {<br />
if (err) {<br />
console.log("Error: " + err.message);<br />
throw err;<br />
}<br />
</blockquote><p>Sacamos los datos por la consola y por la pantalla<br />
<br />
<blockquote>console.log("Number of rows: "+results.length);<br />
console.log(results);<br />
<br />
<br />
for (var i in results){<br />
<br />
var result = results[i];<br />
res.write(result.campo1+"\n");<br />
}<br />
<br />
res.end();<br />
});<br />
</blockquote></p><p>Terminamos el código bindeando un puerto para escucha<br />
<blockquote>}).listen(1337, "0.0.0.0");<br />
console.log('Server running ');<br />
</blockquote></p><br />
<br />
El script completo es:<br />
<br />
<blockquote><br />
var Client = require('mysql').Client,<br />
client = new Client();<br />
client.user = 'user';<br />
client.password = 'password';<br />
client.host='127.0.0.1';<br />
client.port='3306';<br />
client.database='DB'<br />
client.connect();<br />
<br />
<br />
var http = require('http');<br />
http.createServer(function (req, res) {<br />
res.writeHead(200, {'Content-Type': 'text/plain'});<br />
<br />
<br />
client.query(<br />
"select * from table where campo1 > 1 limit 10;", <br />
function select(err, results, fields) {<br />
if (err) {<br />
console.log("Error: " + err.message);<br />
throw err;<br />
}<br />
console.log("Number of rows: "+results.length);<br />
console.log(results);<br />
res.write(results);<br />
<br />
for (var i in results){<br />
<br />
var result = results[i];<br />
res.write(result.campo1+"\n");<br />
}<br />
res.end();<br />
});<br />
<br />
}).listen(1337, "0.0.0.0");<br />
console.log('Server running ');<br />
<br />
</blockquote>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com1tag:blogger.com,1999:blog-2925127253543113473.post-5733258555231612122011-05-03T13:13:00.000-03:002011-05-03T13:13:55.025-03:00Simple (one line) web server pythonthe simplest way to serve up page or file sharing is go to the directory and run:<br />
$ python -c "import SimpleHTTPServer;SimpleHTTPServer.test()"<br />
<br />
Then go to http://<yourip>:8000 and see your files :DPepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com1tag:blogger.com,1999:blog-2925127253543113473.post-83371975436970854192011-04-01T13:07:00.000-03:002011-04-01T14:38:13.092-03:00Instalar virtualBox-4<div style="float:left"><a href="http://www.virtualbox.org/graphics/vbox_logo2_gradient.png" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="180" width="140" src="http://www.virtualbox.org/graphics/vbox_logo2_gradient.png" /></a></div><div >En la web de virtualbox se encuentra un completo tutorial de como actualizar a la última versión del producto, la web es: <a href="http://bit.ly/E76X6">VirtualBox 4</a>.<br />
Para los usuarios de distribuciones basadas en Debian simplemente deben agregar el repositorio a la lista de repos disponibles y lo pueden instalar con el manejador de paquetes de su preferencia.<br />
<br />
</div>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-5144557691692039102011-01-27T19:57:00.000-03:002011-01-27T19:57:16.484-03:00Eliminar ^MCuantas veces nos encotramos que al abrir un archivo con el vim vemos los molestos delimitadores de carry return (^M), una forma simple de eliminarlos es con el comando de reemplazo:<br />
<br />
<blockquote><b><i>%s/\r//g</i></b><br />
</blockquote><br />
y ya podemos seguir editando nuestro archivo :DPepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-13917400034810163522010-12-30T15:17:00.000-03:002010-12-30T15:17:43.715-03:00IndentationError: unexpected indentEste post está relacionado con python, muchas veces al editar un script desde consola con el vim luego al querer correrlo nos arroja este error... Error de identación, pero al acceder al archivo no encontramos a simple vista que bloque está mal identado o por qué da ese error...<br />
Por eso para ver las marcas del script simplemente lo podemos visualizar con el comando<br />
<br />
<br />
#cat -vET archivo.py<archivo></archivo><br />
<br />
En donde veremos los tabs como ^I y el delimitador de final de línea como $.<br />
<br />
por ejemplo:<br />
<br />
<br />
def db(tabla,tipo,puerto=None,desde=None,hasta=None):$<br />
^I"""$<br />
^I"""$<br />
$<br />
^Iif tipo == 'Bandwidth_mb':$<br />
^I^Itipo = 'Total_Bandwidth_mb,Read_Bandwidth_mb,Write_Bandwidth_mb'$<br />
^Ielif tipo == 'Throughput_io':$<br />
^I^Itipo = 'Total_Throughput_io ,Read_Throughput_io ,Write_Throughput_io'$<br />
^Ielif tipo == 'Queue':$<br />
^I^Itipo = 'Queue_Full_Count'$<br />
$<br />
<div><br />
</div>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com3tag:blogger.com,1999:blog-2925127253543113473.post-33069728163006396162009-12-18T16:12:00.000-03:002009-12-18T16:12:24.412-03:00Matando conexiones tcp ( tcpkill )Este post esta dedicado a matar conexiones tcp, muchas veces tenemos alguna conexión tcp que queremos matar, pero no queremos matar el proceso. Por ejemplo una consola de vnc manejada por qemu. Para estos casos en que solo queremos matar la conexión tcp podemos utilizar el comando tcpkill (que lo provee el paquete dsniff), el uso del mismo es el siguiente:<br />
<br />
pepo@frank:~$ tcpkill --help<br />
tcpkill: invalid option -- -<br />
Version: 2.4<br />
Usage: tcpkill [-i interface] [-1..9] expression<br />
<br />
Donde:<br />
-i interface # es la interface de red<br />
[-1.. 9 ] #el grado de <i>fuerza bruta</i> con el que se <i>mata</i> la conexión, el default es 3<br />
expression # filtro a utilizar, al estilo tcpdump (host, port, etc)<br />
<br />
Ejemplo:<br />
<br />
Vemos la conexión a matar<br />
<br />
pepo@frank:~$ netstat -nalp|grep vnc<br />
(No todos los procesos pueden ser identificados, no hay información de propiedad del proceso<br />
no se mostrarán, necesita ser superusuario para verlos todos.)<br />
tcp 0 0 172.xx.xx.xx:40184 172.xx.xx.xx:5922 ESTABLECIDO 4426/vncviewer <br />
unix 3 [ ] FLUJO CONECTADO 540821 4426/vncviewer <br />
<br />
Matamos<br />
<br />
pepo@frank:~$ sudo tcpkill -i eth0 host 172.20.70.19 and port 5922<br />
[sudo] password for pepo: <br />
tcpkill: listening on eth0 [host 172.20.70.19 and port 5922]<br />
172.20.70.19:5922 > 172.16.99.39:40184: R 2779891000:2779891000(0) win 0<br />
172.20.70.19:5922 > 172.16.99.39:40184: R 2779891181:2779891181(0) win 0<br />
172.20.70.19:5922 > 172.16.99.39:40184: R 2779891543:2779891543(0) win 0<br />
172.16.99.39:40184 > 172.20.70.19:5922: R 3942621646:3942621646(0) win 0<br />
172.16.99.39:40184 > 172.20.70.19:5922: R 3942623978:3942623978(0) win 0<br />
172.16.99.39:40184 > 172.20.70.19:5922: R 3942628642:3942628642(0) win 0<br />
<br />
Y listo....<br />
<br />
pepo@frank:~$ netstat -nalp|grep vnc<br />
(No todos los procesos pueden ser identificados, no hay información de propiedad del proceso<br />
no se mostrarán, necesita ser superusuario para verlos todos.)Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0tag:blogger.com,1999:blog-2925127253543113473.post-32757569146423069762009-11-27T18:05:00.000-03:002009-11-27T18:05:03.198-03:00passwd desde stdinEsto es para los que alguna vez tuvieron que crear usuarios y por cada uno de ellos ejecutar el comando passwd.<br />
Lo primero a saber es que el binario de las distribuciones de Red Hat (rhel/fedora) no es igual que el de debian, por lo que en Debian deberemos hacerlo de otra forma.<br />
<br />
Paso a detallar:<br />
<br />
rhel/fedora )<br />
El binario de estas distribuciones soporta el flag --stdin que le indica que teme como input la entrada estandar (stdin), por lo cual podriamos ejecutar<br />
<br />
#echo "password" | passwd --stdin <usuario></usuario><br />
<br />
debian )<br />
Como les comenté antes, el binario de debian no soporta este flag, por lo que para emularlo deberiamos correr el siguiente comando:<br />
<br />
#(sleep 1;echo "password";sleep 1;echo "password") | passwd <usuario></usuario>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com1tag:blogger.com,1999:blog-2925127253543113473.post-71776990274346348952009-10-09T11:27:00.000-03:002009-10-09T11:27:58.949-03:00Viernes de Basquet.. dos pasionesDos pasiones se unen con esta foto, una notebook corriendo Linux (Ubuntu) y una de mis zapatillas de basquet....<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8IqopbJ04AGhbGGKsEvadCGY5xHtA93YpB9qKBs8-clSaeWFOS863B9kfPtRAUJedPWwhYx97pLKxFurufBrPPWUWVeHy2UNupE-K4BQGWIZ3qiVf9a-eknbTOEQ76rUZirxXAg6fBSK5/s1600-h/zapa.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8IqopbJ04AGhbGGKsEvadCGY5xHtA93YpB9qKBs8-clSaeWFOS863B9kfPtRAUJedPWwhYx97pLKxFurufBrPPWUWVeHy2UNupE-K4BQGWIZ3qiVf9a-eknbTOEQ76rUZirxXAg6fBSK5/s320/zapa.jpg" /></a><br />
</div>Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com3tag:blogger.com,1999:blog-2925127253543113473.post-62643304801780442822009-10-08T13:20:00.000-03:002009-10-08T13:21:56.977-03:00Jugando con LVs y xfs<i>Esto no va ser un manual ni sobre LVs ni xfs, simplemente un mini-howto basado en un caso real</i><br />
Una pequeña introducción, algunas veces sucede que no tenemos la posibilidad de sentarnos frente al servidor que deseamos instalar y el mismo tampoco cuenta con una consola de administración remota al estilo Drac (de Dell) o ilom (de Sun). Por lo que no nos queda otra opción que otra persona realice la instalación del sistema base y habilite ssh para que podamos acceder remotamente.<br />
Este es el caso, usando Debian 5 con una instalación base con Lvs (es una de las opciones que nos ofrece al instalar).<br />
Bueno, sin más preámbulo, este es el escenario con el que nos encontramos al acceder por primera vez al equipo:<br />
<br />
<b><u>Miro FS montado:</u></b><br />
<br />
debian5:~# df<br />
<br />
S.ficheros Bloques de 1K Usado Dispon Uso% Montado en<br />
/dev/mapper/debian5-root<br />
329233 81766 230469 27% /<br />
tmpfs 972976 0 972976 0% /lib/init/rw<br />
udev 10240 668 9572 7% /dev<br />
tmpfs 972976 0 972976 0% /dev/shm<br />
/dev/sda1 233335 16379 204508 8% /boot<br />
/dev/mapper/debian5-home<br />
296395632 195628 281143928 1% /home<br />
/dev/mapper/debian5-tmp<br />
376807 10289 347062 3% /tmp<br />
/dev/mapper/debian5-usr<br />
4805760 397960 4163680 9% /usr<br />
/dev/mapper/debian5-var<br />
2882592 272504 2463656 10% /var<br />
<br />
Como vemos tiene el /boot montado sobre la partición sda1 y luego utiliza lvs creados sobre el VG debian5.<br />
<br />
<b><u>Miro los LVs creados:</u></b><br />
<br />
debian5:~# lvs<br />
LV VG Attr LSize Origin Snap% Move Log Copy% Convert<br />
home debian5 -wi-ao 287,17G <br />
root debian5 -wi-ao 332,00M <br />
swap_1 debian5 -wi-ao 2,53G <br />
tmp debian5 -wi-ao 380,00M <br />
usr debian5 -wi-ao 4,66G <br />
var debian5 -wi-ao 2,79G <br />
<br />
<b><u>Miro los VGs creados:</u></b><br />
<br />
debian5:~# vgs<br />
VG #PV #LV #SN Attr VSize VFree<br />
debian5 1 6 0 wz--n- 297,85G 0 <br />
<br />
<br />
<b><u>Miro los discos:</u></b><br />
<br />
debian5:~# fdisk -l<br />
<br />
Disco /dev/sda: 320.0 GB, 320072933376 bytes<br />
255 heads, 63 sectors/track, 38913 cylinders<br />
Units = cilindros of 16065 * 512 = 8225280 bytes<br />
Disk identifier: 0x000c9f92<br />
<br />
Disposit. Inicio Comienzo Fin Bloques Id Sistema<br />
/dev/sda1 * 1 31 248976 83 Linux<br />
/dev/sda2 32 38913 312319665 8e Linux LVM<br />
<br />
Disco /dev/sdb: 320.0 GB, 320072933376 bytes<br />
255 heads, 63 sectors/track, 38913 cylinders<br />
Units = cilindros of 16065 * 512 = 8225280 bytes<br />
Disk identifier: 0x000e0177<br />
<br />
<br />
<i>Hasta aca toda la información que recolectamos, nuestro objetivo es crear un lv (que llamaremos events) con el máximo de tamaño posible, para ello eliminaremos el lv "home" (que luego volveremos a crear con menos espacio) y utilizaremos el disco sdb para extender el vg debian5 y poder crear el lv "events" que deseamos y darle fs xfs.</i><br />
<br />
<u>Manos a la obra:</u><br />
<br />
<u><b>Primero instalo las herramientas que necesitaré: (xfsprogs)</b></u><br />
<br />
debian5:~# apt-get install xfsprogs<br />
<br />
<u><b>Desmonto el /home </b></u><br />
<br />
debian5:~# umount /home/<br />
<br />
<u><b>Elimino el lv y lo vuelvo a crear (si, ya se que podria reducir el tamaño del actual)</u></b><br />
<br />
debian5:~# lvremove /dev/debian5/home<br />
Do you really want to remove active logical volume "home"? [y/n]: y<br />
Logical volume "home" successfully removed<br />
<br />
<br />
debian5:~# lvcreate -n home -L 10G debian5<br />
/dev/cdrom: open failed: Sistema de ficheros de sólo lectura<br />
Logical volume "home" created<br />
<br />
<u><b>Le damos FS ext3 al LV </u></b><br />
<br />
debian5:~# mkfs.ext3 /dev/debian5/home <br />
<br />
Verificamos con mount -a (la entrada del home ya estaba en el fstab originalmente)<br />
<br />
debian5:~# mount -a<br />
<br />
<u><b>Particionamos el disco sdb, formato 8e (Linux LVM) </u></b><br />
<br />
Esto lo hicimos de forma interactiva, en un post anterior mío encontraran la forma de hacerlo con un script.<br />
<br />
debian5:~# fdisk /dev/sdb <br />
<br />
El número de cilindros para este disco está establecido en 38913.<br />
No hay nada malo en ello, pero es mayor que 1024, y en algunos casos<br />
podría causar problemas con:<br />
1) software que funciona en el inicio (p.ej. versiones antiguas de LILO)<br />
2) software de arranque o particionamiento de otros sistemas operativos<br />
(p.ej. FDISK de DOS, FDISK de OS/2)<br />
<br />
Orden (m para obtener ayuda): n<br />
<br />
Orden (m para obtener ayuda): n<br />
Acción de la orden<br />
e Partición extendida<br />
p Partición primaria (1-4)<br />
<br />
p<br />
<br />
Número de partición (1-4): 1<br />
Primer cilindro (1-38913, valor predeterminado 1): <enter><br />
Se está utilizando el valor predeterminado 1 <enter><br />
Último cilindro o +tamaño o +tamañoM o +tamañoK (1-38913, valor predeterminado 38913): <enter><br />
Se está utilizando el valor predeterminado 38913 <enter><br />
<br />
Orden (m para obtener ayuda): t<br />
Se ha seleccionado la partición 1<br />
Código hexadecimal (escriba L para ver los códigos): 8e<br />
Se ha cambiado el tipo de sistema de la partición 1 por 8e (Linux LVM)<br />
<br />
Orden (m para obtener ayuda): p<br />
<br />
Disco /dev/sdb: 320.0 GB, 320072933376 bytes<br />
255 heads, 63 sectors/track, 38913 cylinders<br />
Units = cilindros of 16065 * 512 = 8225280 bytes<br />
Disk identifier: 0x000e0177<br />
<br />
Disposit. Inicio Comienzo Fin Bloques Id Sistema<br />
/dev/sdb1 1 38913 312568641 8e Linux LVM<br />
<br />
Orden (m para obtener ayuda): w<br />
¡Se ha modificado la tabla de particiones!<br />
<br />
Llamando a ioctl() para volver a leer la tabla de particiones.<br />
Se están sincronizando los discos.<br />
<br />
<br />
<u><b>Creamos el PV (PHISICAL VOLUME) y extendemos el VG</b></u><br />
<br />
debian5:~# pvcreate /dev/sdb1 <br />
Physical volume "/dev/sdb1" successfully created<br />
<br />
debian5:~# vgextend debian5 /dev/sdb1 <br />
Attempt to close device '/dev/cdrom' which is not open.<br />
Volume group "debian5" successfully extended<br />
<br />
Miramos el espacio que ahora tenemos disponible en el VG debian5<br />
<br />
debian5:~# vgs<br />
VG #PV #LV #SN Attr VSize VFree <br />
debian5 2 6 0 wz--n- 595,93G 575,26G<br />
<br />
<br />
<u><b>Creamos el LV events y le damos formato xfs</b></u><br />
<br />
debian5:~# lvcreate -n events -L 575G debian5<br />
Logical volume "events" created<br />
<br />
debian5:~# mkfs.xfs /dev/debian5/events <br />
Warning - device mapper device, but no dmsetup(8) found<br />
Warning - device mapper device, but no dmsetup(8) found<br />
meta-data=/dev/debian5/events isize=256 agcount=4, agsize=37683200 blks<br />
= sectsz=512 attr=2<br />
data = bsize=4096 blocks=150732800, imaxpct=25<br />
= sunit=0 swidth=0 blks<br />
naming =version 2 bsize=4096 <br />
log =internal log bsize=4096 blocks=32768, version=2<br />
= sectsz=512 sunit=0 blks, lazy-count=0<br />
realtime =none extsz=4096 blocks=0, rtextents=0<br />
<br />
<br />
<u><b>Creamos el punto de montaje para este lv y agregamos la entrada al fstab</b></u><br />
<br />
debian5:~# mkdir -p /events<br />
debian5:~# vim /etc/fstab <br />
<br />
<b> Importante: Tener siempre en cuenta cuando se modifica el archivo fstab como es la jerarquia de los directorios y como los montará.<br />
Por ejemplo: este es el archivo fstab actual<br />
<br />
# /etc/fstab: static file system information.<br />
#<br />
# <file system> <mount point> <type> <options> <dump> <pass><br />
proc /proc proc defaults 0 0<br />
/dev/mapper/debian5-root / ext3 errors=remount-ro 0 1<br />
/dev/sda1 /boot ext2 defaults 0 2<br />
/dev/mapper/debian5-home /home ext3 defaults 0 2<br />
/dev/mapper/debian5-events /events xfs defaults 0 2<br />
/dev/mapper/debian5-tmp /tmp ext3 defaults 0 2<br />
/dev/mapper/debian5-usr /usr ext3 defaults 0 2<br />
/dev/mapper/debian5-var /var ext3 defaults 0 2<br />
/dev/mapper/debian5-swap_1 none swap sw 0 0<br />
/dev/hda /media/cdrom0 udf,iso9660 user,noauto 0 0<br />
<br />
Si el punto de montaje para el LV "events" sería /var/events en vez de /events, este archivo produciría un error al querer montar el LV events, ya que intentaría montar un lv en /var/events cuando aún no montó /var. Por eso es que siempre deben tener en cuenta el orden en que va montando.</b><br />
<br />
<br />
<u><b>Por último </b></u><br />
Probamos nuevamente con mount -a y luego vemos los FS montados con el comando df<br />
<br />
debian5:~# mount -a<br />
debian5:~# df<br />
S.ficheros Bloques de 1K Usado Dispon Uso% Montado en<br />
/dev/mapper/debian5-root<br />
329233 82640 229595 27% /<br />
tmpfs 972976 0 972976 0% /lib/init/rw<br />
udev 10240 676 9564 7% /dev<br />
tmpfs 972976 0 972976 0% /dev/shm<br />
/dev/sda1 233335 16379 204508 8% /boot<br />
/dev/mapper/debian5-tmp<br />
376807 10289 347062 3% /tmp<br />
/dev/mapper/debian5-usr<br />
4805760 400164 4161476 9% /usr<br />
/dev/mapper/debian5-var<br />
2882592 274256 2461904 11% /var<br />
/dev/mapper/debian5-home<br />
10321208 154232 9642688 2% /home<br />
/dev/mapper/debian5-events<br />
602800128 4256 602795872 1% /events<br />
<br />
<br />
pepo.Pepohttp://www.blogger.com/profile/03423847613221168243noreply@blogger.com0