<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Fabio's Tech Blog</title>
	
	<link>http://www.codewithstyle.eu</link>
	<description>Idee e appunti per il mondo IT</description>
	<lastBuildDate>Sun, 24 Jul 2011 22:09:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/FabiosTechBlog" /><feedburner:info uri="fabiostechblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Import an existing Redmine installation in Capistrano</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/Vw4d6LDJgjg/</link>
		<comments>http://www.codewithstyle.eu/2011/07/25/import-an-existing-redmine-installation-in-capistrano/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 22:07:55 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[redmine]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=413</guid>
		<description><![CDATA[In my previous article I explained how to install and upgrade Redmine using Capistrano, in this post I want to explain how to import your existing installation using the same method. Once again this is an experimental procedure, so make a backup before doing anything. In order to import an existing installation of Redmine you&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous article I explained <a title="install Redmine using Capistrano" href="http://www.codewithstyle.eu/2011/06/09/installing-redmine-using-capistrano/">how to install and upgrade Redmine using Capistrano</a>, in this post I want to explain how to import your existing installation using the same method. Once again this is an <strong>experimental</strong> procedure, so make a backup before doing anything.</p>
<p><span id="more-413"></span></p>
<p>In order to import an existing installation of Redmine you&#8217;ll need both local (your development machine) and remote steps (on your production server). First of all you need to checkout <a href="https://github.com/fabn/redmine">my Redmine fork</a> on your local machine using this command:</p>
<pre class="brush: bash; title: ; notranslate">
git checkout git://github.com/fabn/redmine.git
</pre>
<p>After that you need to define at least your production configuration, this goes into <code>config/deploy/production.rb</code> file. This could be its content</p>
<pre class="brush: ruby; title: ; notranslate">

# roles definition
role :web, &quot;your.redmine.org&quot;
role :app, &quot;your.redmine.org&quot;
role :db, &quot;your.redmine.org&quot;, :primary =&gt; true

# used on redmine install to load default data when installing
#set :load_default_data, false # default: true

# Customize here your start, stop and restart tasks if you need
# To use them you MUST deploy using explicit environment i.e. cap production redmine:upgrade
#namespace :deploy do
#  task :stop do
#    logger.important &quot;Overridden&quot;
#  end
#end
</pre>
<p>After that, from the local machine run</p>
<pre class="brush: bash; title: ; notranslate">
cap deploy:setup
</pre>
<p>this will prepare the folder structure on the server (under <code>/var/rails/redmine</code> folder, if you want to edit that override the <code>:deploy_to</code> variable for capistrano in the same file)</p>
<p>After the setup ssh into the remote machine and run the following commands, adjust paths to fit your needs</p>
<pre class="brush: bash; title: ; notranslate">
export OLD_REDMINE=/where/you/have/it
export NEW_REDMINE=/what/you/ve/set/in/production.rb
# The file configuration.yml exists only in RM &gt;= 1.2
cp -a ${OLD_REDMINE}/config/{database,email,configuration}.yml ${NEW_REDMINE}/shared/config
rmdir ${NEW_REDMINE}/shared/files &amp;&amp; cp -a ${OLD_REDMINE}/files ${NEW_REDMINE}/shared/
</pre>
<p>Then you should copy your themes and plugins in your new structure, you can use the following commands, but then need to remove all the stuff provided in Redmine itself. This is true especially for plugins since your installed plugins are in the same folder of the distribution plugins. If you won&#8217;t Capistrano will fail on deploy with a <code>"ln: file exist"</code> error.</p>
<pre class="brush: bash; title: ; notranslate">
cp -a ${OLD_REDMINE}/public/themes/* ${NEW_REDMINE}/shared/themes
cp -a ${OLD_REDMINE}/vendor/plugins/* ${NEW_REDMINE}/shared/plugins
</pre>
<p>Alternatively you can pick only folders you&#8217;ve manually installed into themes and plugins folders and put it in the destination folders (under <code>shared/plugins</code> and <code>shared/themes</code>).</p>
<p>Then, from the local machine, deploy the current version with </p>
<pre class="brush: bash; title: ; notranslate">
GIT_TAG=&lt;your-current-version&gt; cap production redmine:upgrade
</pre>
<p>This will deploy the code for the given tag, symlink all the imported data and then it migrate the db. Since you&#8217;re not doing a real upgrade no migration should be ran.</p>
<h3>Final Notes</h3>
<p>To ensure you can run all the above command you can try them with a staging configuration before doing the actual import to ensure that you meet the requirements. To do that follow these steps</p>
<p>Create a <code>config/deploy/staging.rb</code> file locally, with the following content:</p>
<pre class="brush: ruby; title: ; notranslate">
# deploy to a different path
set :deploy_to, &quot;/another/redmine/path&quot;
# roles definition
role :web, &quot;your.redmine.org&quot;
role :app, &quot;your.redmine.org&quot;
role :db, &quot;your.redmine.org&quot;, :primary =&gt; true

# used on redmine install to load default data when installing
set :load_default_data, true
</pre>
<p>Edit local configuration example files (especially config/database.yml.example and put it a sqlite database to avoid mess with production database)</p>
<pre class="brush: bash; title: ; notranslate">
cap staging deploy:setup
GIT_TAG=&lt;your-current-version&gt; cap staging redmine:install
</pre>
<p>If everything runs fine login on the remote machine and start the staging installation with</p>
<pre class="brush: bash; title: ; notranslate">
cd &lt;your staging path&gt; &amp;&amp; rails server
</pre>
<p>point your browser to http://your-server:3000 to see if everything works.</p>
<p>Fix any issue in this staging environment before doing the above procedure, if staging configuration works then the above should work either.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/D_ZwQvIlE_fNlc-gQrUCubhiwxY/0/da"><img src="http://feedads.g.doubleclick.net/~a/D_ZwQvIlE_fNlc-gQrUCubhiwxY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/D_ZwQvIlE_fNlc-gQrUCubhiwxY/1/da"><img src="http://feedads.g.doubleclick.net/~a/D_ZwQvIlE_fNlc-gQrUCubhiwxY/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Vw4d6LDJgjg:4o3sdQ_-Gyk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Vw4d6LDJgjg:4o3sdQ_-Gyk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Vw4d6LDJgjg:4o3sdQ_-Gyk:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Vw4d6LDJgjg:4o3sdQ_-Gyk:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=Vw4d6LDJgjg:4o3sdQ_-Gyk:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Vw4d6LDJgjg:4o3sdQ_-Gyk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=Vw4d6LDJgjg:4o3sdQ_-Gyk:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/Vw4d6LDJgjg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2011/07/25/import-an-existing-redmine-installation-in-capistrano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2011/07/25/import-an-existing-redmine-installation-in-capistrano/</feedburner:origLink></item>
		<item>
		<title>Installing Redmine using Capistrano</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/PpzRAfogRI0/</link>
		<comments>http://www.codewithstyle.eu/2011/06/09/installing-redmine-using-capistrano/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 00:26:32 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[redmine]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=398</guid>
		<description><![CDATA[Redmine is a great project, but it has a pretty complex multisteps installation procedure and upgrade is a little pain. In order to semplify installation I tried to develop a Capistrano (+RVM) recipe to install and upgrade it. I made it available on github for who wants to try it. You should know a little [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.redmine.org/">Redmine</a> is a great project, but it has a pretty complex multisteps installation procedure and upgrade is a little pain. In order to semplify installation I tried to develop a Capistrano (+RVM) recipe to install and upgrade it. I made it <a href="https://github.com/fabn/redmine">available on github</a> for who wants to try it. You should know a little bit how capistrano works to follow this guide, you can find a lot of documentation on it <a href="https://github.com/capistrano/capistrano/wiki">here</a>.<span id="more-398"></span></p>
<h3>Prerequisites</h3>
<p>In order to install Redmine from a local machine you should have ssh access to the host where to install, <a href="https://rvm.beginrescueend.com/">rvm</a> installed on both machines, git installed on both machines and the following gems on your local machine:</p>
<ul>
<li>capistrano</li>
<li>capistrano-ext</li>
<li><a href="https://github.com/fabn/capistrano-tags">capistrano-tags</a></li>
</ul>
<p>Then you can clone my repository (which is a fork of the official redmine git mirror) on your local machine with</p>
<pre class="brush: bash; title: ; notranslate">
git clone git://github.com/fabn/redmine.git
</pre>
<h3>Installation</h3>
<p>Once you&#8217;ve cloned the repository you should define your deploy configuration by using one or more stage files in <code>config/deploy/</code> folder inside redmine root. This is a minimal example of such file (named production.rb, the name will be useful later).</p>
<pre class="brush: ruby; title: ; notranslate">
# roles definition, on single machine deployment all the roles are played by the same host
role :web, &quot;redmine.example.org&quot;
role :app, &quot;redmine.example.org&quot;
role :db, &quot;redmine.example.org&quot;, :primary =&gt; true

# used on redmine install to load default data when installing
#set :load_default_data, false # default: true

# Customize here your start, stop and restart tasks if you need
# To use them you MUST deploy using explicit environment i.e. cap production redmine:upgrade
#namespace :deploy do
#  task :stop do
#    logger.important &quot;Overridden&quot;
#  end
#end
</pre>
<p>After you&#8217;ve created this file (it&#8217;s not included in the repository) your should edit redmine settings provided in .example files in the <code>config</code> folder, especially the database.yml.example file, all those files will be copied during the setup phase. Don&#8217;t change their names, simply edit them.</p>
<p>I don&#8217;t think that someone uses sqlite in production, anyway if you want to deploy with that db engine you <strong>MUST </strong>put your db files in the <code>db/sqlite</code> folder, otherwise they will <strong>NOT</strong> kept across different releases.</p>
<p>Then the first step on the remote machine is to prepare the environment for the installation, this could be achieved with the command</p>
<pre class="brush: bash; title: ; notranslate">
cap production deploy:setup
</pre>
<p>This command will prepare the typical capistrano structure under <code>/var/rails/redmine</code> (ensure your ssh user has write permission on <code>/var/rails</code>, otherwise capistrano will fail) on your remote machine adding some directories inside the <code>shared</code> folder and it will copy the yml files you&#8217;ve edited in the <code>shared/config</code> folder.</p>
<p>Now you should login on the remote machine and ensure that you&#8217;ve all the redmine dependencies installed, I choose to use rvm gemset to avoid mess in gem environment and to keep multiple projects with different dependencies installed on the same machine I used gemsets. So on the remote machine you must create a dedicated gemset called &#8220;redmine&#8221; and install redmine gems inside that gemset. This can be done with</p>
<pre class="brush: bash; title: ; notranslate">
rvm use 1.8.7@redmine --create
gem install rails -v=2.3.11
gem install i18n -v=0.4.2
gem install mysql # (or gem install sqlite3)
</pre>
<p>This should meet all redmine requirements, just check that your rvm installation has gem <= 1.5.0, if not you must downgrade it or you'll have problems.</p>
<p>Last manual task (optional), on the remote machine install your RM themes under <code>shared/themes</code> and your RM plugins under <code>shared/plugins</code> and you're ready to go with the installation.</p>
<p>To perform the installation just type the following command</p>
<pre class="brush: bash; title: ; notranslate">
cap production redmine:install
</pre>
<p>You'll be prompted to choose the tag to deploy (tested with 1.1.2 and 1.2.0) or leave it blank to deploy from master branch, you'll see a lot a screens and at the end RM is installed. I overridden the default capistrano start, stop and restart task because they are pretty obsolete, you have two choices here to handle redmine start and stop: starting it manually in your server, or redefine those tasks in your production.rb file (sample provided). A last note, if you want to deploy any < 1.2.0 RM version you should change the installed gems in the gemset or replacing the gemset with a different one because with 1.2 RM has moved to rails 2.3.11.</p>
<h3>Upgrade</h3>
<p>Now the funny part, suppose you've just deployed the 1.2 release and the 1.2.1 come out (or you want to switch to the devel version). Instead of doing all the manual steps listed <a href="http://www.redmine.org/projects/redmine/wiki/RedmineUpgrade">here</a> on your machine type the following command an it will do all that work for you</p>
<pre class="brush: bash; title: ; notranslate">
cap production redmine:upgrade
</pre>
<p>This task will upgrade the codebase in a new release folder, will symlink all the shared folders (files, logs, themes and plugins), will run the migrations (both for RM and plugins) and it will update the symlink. In a couple of minutes you're done.</p>
<h3>Final Notes</h3>
<p>I tried this procedures a dozen of times in my environment before publishing it and eventually I ran the update task against my production installation to upgrade it from 1.1.2 to 1.2 and everything has worked as expected, but this is experimental code, so try it at your own risk and most important backup, backup, backup.</p>
<p>If someone is interested I can write on how to import an existing RM installation into this structure, let me know in the comments and I'll update the post.</p>
<p>I just published the <a href="http://www.codewithstyle.eu/2011/07/25/import-an-existing-redmine-installation-in-capistrano/">steps needed to import your existing installation</a>.</p>
<p><a href="https://github.com/fabn/redmine"><br />
<img alt="Fork me on GitHub" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" style="position: absolute; top: 0; right: 0; border: 0;"></a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/gEBm7XfgW_bjLT6g7OkmN4xPK_E/0/da"><img src="http://feedads.g.doubleclick.net/~a/gEBm7XfgW_bjLT6g7OkmN4xPK_E/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/gEBm7XfgW_bjLT6g7OkmN4xPK_E/1/da"><img src="http://feedads.g.doubleclick.net/~a/gEBm7XfgW_bjLT6g7OkmN4xPK_E/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=PpzRAfogRI0:VSkFIEwaHPs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=PpzRAfogRI0:VSkFIEwaHPs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=PpzRAfogRI0:VSkFIEwaHPs:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=PpzRAfogRI0:VSkFIEwaHPs:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=PpzRAfogRI0:VSkFIEwaHPs:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=PpzRAfogRI0:VSkFIEwaHPs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=PpzRAfogRI0:VSkFIEwaHPs:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/PpzRAfogRI0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2011/06/09/installing-redmine-using-capistrano/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2011/06/09/installing-redmine-using-capistrano/</feedburner:origLink></item>
		<item>
		<title>Deploying Zend Framework applications using Capistrano</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/gmJVs4A7kEs/</link>
		<comments>http://www.codewithstyle.eu/2011/05/03/deploying-zend-framework-applications-using-capistrano/#comments</comments>
		<pubDate>Tue, 03 May 2011 01:16:10 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[gem]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=374</guid>
		<description><![CDATA[Are you tired of deploying manually your zf projects to production servers, do you want to automate this tedious and error prone process, do you want to be able to revert changes if you make some mistakes? If the answer to these questions is yes, this is the post for you. Recently I started to [...]]]></description>
			<content:encoded><![CDATA[<p>Are you tired of deploying manually your zf projects to production servers, do you want to automate this tedious and error prone process, do you want to be able to revert changes if you make some mistakes? If the answer to these questions is yes, this is the post for you.</p>
<p>Recently I started to exploring Ruby on Rails and one of the aspects I like of it is the ability to deploy projects using <a href="https://github.com/capistrano/capistrano/wiki">Capistrano</a> an automated deployment tool. With Capistrano your deployment process (once configured the app) is simple as typing <code>cap deploy</code>, and if you make a mistake you can revert the things as before by just typing <code>cap deploy:rollback</code>, no more ssh, no more (s)ftp, nothing, just a command.<span id="more-374"></span></p>
<p>I tried to replicate this behavior also for Zend Framework projects and what I obtained is a brand new gem, named <a href="https://github.com/fabn/zend-framework-deploy">zend-framework-deploy</a>. With this gem you can deploy ZF projects in the same manner of Rails ones. I developed a gem, because Ruby (and rails) are more extensible than php and I want to reuse existing capistrano code.</p>
<h3>Installing the gem</h3>
<p>So to use this technique you&#8217;ll need to install ruby and RubyGems. If you never did that, don&#8217;t worry it&#8217;s pretty simple with the right tools, just use <a href="https://rvm.beginrescueend.com/">Ruby Version Manager</a> on any Unix platform. If you&#8217;re on Windows platform (aargh&#8230;) you can use <a href="http://rubyinstaller.org/">Ruby Installer</a>.</p>
<p>Once you have the gem command available in your shell type this command to install my gem</p>
<pre class="brush: bash; title: ; notranslate">
gem install zend-framework-deploy
</pre>
<p>and it will take care of anything, path setup, dependencies, etc.</p>
<h3>Prepare the project</h3>
<p>Now you can enable your project to be used with capistrano, to do that just use the bundled <code>zf-capify</code> executable provided</p>
<pre class="brush: bash; title: ; notranslate">
zf-capify /your/project/root
[add] writing '/your/project/root/application/configs/deploy.rb'
[add] writing '/your/project/root/Capfile'
[done] zf-capified!
</pre>
<p>The executable writes two files with the minimal settings to deploy your project, you can safely ignore the <code>Capfile</code> and just edit the <code>deploy.rb</code> file. It contains the capistrano variables to configure parameters for your deploy. This is the content of the generated file</p>
<pre class="brush: ruby; title: ; notranslate">
set :application, &quot;set your application name here&quot;
set :repository,  &quot;set your repository location here&quot;
set :deploy_to, &quot;set path where to deploy application&quot;
set :zf_path, &quot;set Zend Framework (remote) installation path here&quot;

set :scm, :subversion
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

role :web, &quot;your web-server here&quot;                          # Your HTTP server, Apache/etc
</pre>
<p>Just fill the strings with your parameters and you&#8217;re almost ready to make your first deploy, these are the meaning of various settings:</p>
<ul>
<li>application: the name of your app, try to avoid spaces in that</li>
<li>repository: url of your repository</li>
<li>deploy_to: base path on the remote server which will contain the application</li>
<li>zf_path: remote path of Zend Framework release</li>
<li>scm: source code management type (git, subversion, etc)</li>
<li>role web: fill this with the dns name of your server</li>
</ul>
<p>To test your configuration you should type this command in the root of your project</p>
<pre class="brush: bash; title: ; notranslate">
cap deploy:setup
</pre>
<p>It will try so ssh into your server and it will make the required directories for project deployment. If everything goes fine, next step is to make a deploy, you can do that by typing</p>
<pre class="brush: bash; title: ; notranslate">
cap deploy
</pre>
<p>This command will create a new folder under the releases directory in the deploy_to folder and it will checkout the content of your SCM head into. Then it will symlink the data folder in the project root and lastly it will symlink Zend Framework directories in the library folder. At this point you should have a working version of your zend framework application (if the exit code of the command is 0), to make it run point your webserver root to the <code>deploy_to/current/public</code> folder and you&#8217;re ok. (Please note that you still need to setup your database manually). Refer to the <a href="https://github.com/capistrano/capistrano/wiki">capistrano documentation</a> for the full setup workflow and the structure of the deployment paths.</p>
<h3>Following deployments</h3>
<p>Once the setup is done, releasing a new version of your app is trivial, just cd (locally) in the root of the project and type <code>cap deploy</code>. The released project is automatically updated at the latest version present in your SCM. And if something goes wrong you can safely revert it to the previous state with <code>cap deploy:rollback</code></p>
<p>I will explain the multistage configuration in a future article. Please post any problem in the comments and I&#8217;ll try to help you on solving that.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/D-KpylfdVYQIiKMJmYk7EXjmRTs/0/da"><img src="http://feedads.g.doubleclick.net/~a/D-KpylfdVYQIiKMJmYk7EXjmRTs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/D-KpylfdVYQIiKMJmYk7EXjmRTs/1/da"><img src="http://feedads.g.doubleclick.net/~a/D-KpylfdVYQIiKMJmYk7EXjmRTs/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=gmJVs4A7kEs:4uanQmjCjrg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=gmJVs4A7kEs:4uanQmjCjrg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=gmJVs4A7kEs:4uanQmjCjrg:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=gmJVs4A7kEs:4uanQmjCjrg:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=gmJVs4A7kEs:4uanQmjCjrg:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=gmJVs4A7kEs:4uanQmjCjrg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=gmJVs4A7kEs:4uanQmjCjrg:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/gmJVs4A7kEs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2011/05/03/deploying-zend-framework-applications-using-capistrano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2011/05/03/deploying-zend-framework-applications-using-capistrano/</feedburner:origLink></item>
		<item>
		<title>Zend Framework Exception Notifier</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/fflw0NcogmQ/</link>
		<comments>http://www.codewithstyle.eu/2011/01/26/zend-framework-exception-notifier/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 01:06:07 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zle]]></category>
		<category><![CDATA[application resource]]></category>
		<category><![CDATA[application.ini]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=351</guid>
		<description><![CDATA[Do you want to be notified when an exception is raised in your code? This code is for you. I wrote an application resource that will send you a nicely formatted email with all the data about the exception. In order to use it you have to install my library and insert the following lines [...]]]></description>
			<content:encoded><![CDATA[<p>Do you want to be notified when an exception is raised in your code? This code is for you. I wrote an application resource that will send you a nicely formatted email with all the data about the exception. In order to use it you have to install <a href="http://github.com/fabn/zle/">my library</a> and insert the following lines into your <code>application.ini</code> file</p>
<pre class="brush: plain; title: ; notranslate">
autoloadernamespaces[] = &quot;Zle_&quot;
pluginPaths.Zle_Application_Resource = &quot;Zle/Application/Resource&quot;
</pre>
<p>Then you&#8217;ll have to setup the application resource using the following directives</p>
<pre class="brush: plain; title: ; notranslate">
; notifier settings
resources.notifier.project = Project Name
resources.notifier.addresses[] = foo@example.com
resources.notifier.addresses[] = bar@example.com
</pre>
<p>This snippet of code attachs an email log writer to the log resource, so don&#8217;t forget to configure the log resource in <code>application.ini</code> file. The generated email will be sent using the default transport, so you&#8217;ll have to configure it otherwise the default transport (sendmail) would be used.</p>
<p>The default error controller will log any error with the <code>CRIT</code> priority, this will trigger the writer and send a message like this one to the given recipients:</p>
<p><a href="http://www.codewithstyle.eu/wp-content/uploads/2011/01/exception.png"><img src="http://www.codewithstyle.eu/wp-content/uploads/2011/01/exception-300x249.png" alt="exception notification" title="Exception notification" width="300" height="249" class="aligncenter size-medium wp-image-364" /></a></p>
<p>You would like to avoid to receive notifications for a page not found (otherwise all the request generated by script kiddies would flood your inbox), in order to do this you can edit the default error controller to keep track of that in this way:</p>
<pre class="brush: php; title: ; notranslate">
    public function errorAction()
    {
        $errors = $this-&gt;_getParam('error_handler');
        $logError = true;
        // skipped code
        switch ($errors-&gt;type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                $logError = false;
        // other case for the switch
        // Log exception, if logger available
        if ($logError &amp;&amp; $log = $this-&gt;getLog()) {
            $log-&gt;crit($this-&gt;view-&gt;message, $errors-&gt;exception);
        }
</pre>
<p>Last but not least, when you are in development or in testing mode you can avoid notifications by using this line in the right section of your <code>application.ini</code></p>
<pre class="brush: plain; title: ; notranslate">
; disable notifier for development
resources.notifier.disabled = true
</pre>

<p><a href="http://feedads.g.doubleclick.net/~a/Tu17jiirhHyRX2RaXC-a_BTOIns/0/da"><img src="http://feedads.g.doubleclick.net/~a/Tu17jiirhHyRX2RaXC-a_BTOIns/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Tu17jiirhHyRX2RaXC-a_BTOIns/1/da"><img src="http://feedads.g.doubleclick.net/~a/Tu17jiirhHyRX2RaXC-a_BTOIns/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=fflw0NcogmQ:w7eS0hrsTvw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=fflw0NcogmQ:w7eS0hrsTvw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=fflw0NcogmQ:w7eS0hrsTvw:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=fflw0NcogmQ:w7eS0hrsTvw:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=fflw0NcogmQ:w7eS0hrsTvw:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=fflw0NcogmQ:w7eS0hrsTvw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=fflw0NcogmQ:w7eS0hrsTvw:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/fflw0NcogmQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2011/01/26/zend-framework-exception-notifier/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2011/01/26/zend-framework-exception-notifier/</feedburner:origLink></item>
		<item>
		<title>Google Sync: sincronizzare iPhone e Mac over the air</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/6ka84vgFBdQ/</link>
		<comments>http://www.codewithstyle.eu/2010/11/12/google-sync-sincronizzare-iphone-e-mac-over-the-air/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 01:17:30 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Google sync]]></category>
		<category><![CDATA[gratis]]></category>
		<category><![CDATA[iCal]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[snow leopard]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=318</guid>
		<description><![CDATA[Una delle funzioni più interessante degli smartphone è sicuramente la possibilità di sincronizzare i propri dati (email, agenda, contatti) tra il proprio computer e il proprio telefono potendo usare uno o l&#8217;altro indistintamente. Nella pratica però quando si tratta di iPhone e Mac la necessità di passare per iTunes ogni volta che si apporta una [...]]]></description>
			<content:encoded><![CDATA[<p>Una delle funzioni più interessante degli smartphone è sicuramente la possibilità di sincronizzare i propri dati (email, agenda, contatti) tra il proprio computer e il proprio telefono potendo usare uno o l&#8217;altro indistintamente. Nella pratica però quando si tratta di iPhone e Mac la necessità di passare per iTunes ogni volta che si apporta una modifica al calendario (oppure ai contatti) è piuttosto noiosa.</p>
<p>Per ovviare a questo inconveniente è possibile utilizzare i servizi messi a disposizione gratuitamente da Google per far si che le modifiche apportate ai propri dati siano riflesse in tempo reale su uno o sull&#8217;altro dispositivo in maniera semplice e trasparente senza dover collegare il telefono al computer via USB.<span id="more-318"></span></p>
<p>Per fare tutto ciò e necessario utilizzare il protocollo Exchange, disponibile su iOS a partire dalla versione 3.0, e il servizio Google Sync. Come primo passo è necessario disattivare la sincronizzazione dei calendari tramite iTunes dopo aver effettuato un&#8217;ultima sincronizzazione per garantire che siano presenti gli stessi dati si entrambi i dispositivi, per cui colleghiamo l&#8217;iPhone al Mac e dopo che la sincronizzazione è completata spuntiamo la casella &#8220;Sincronizza calendari iCal&#8221; e clicchiamo su &#8220;Applica&#8221; in tal modo verranno rimossi tutti i calendari dall&#8217;iPhone (tranquilli, verranno riaggiunti negli step successivi).</p>
<p><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/iTunes-calendari.png"><img class="aligncenter size-full wp-image-323" title="iTunes calendari" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/iTunes-calendari.png" alt="" width="494" height="153" /></a></p>
<p>Ora colleghiamoci al nostro account di Google Calendar e creiamo gli stessi calendari che abbiamo in iCal tramite l&#8217;interfaccia di Google, inizialmente saranno vuoti (a meno che non usiate già Calendar).</p>
<p>Una volta fatto ciò è necessario accedere ai calendari creati tramite iCal, per fare questo andiamo sulle preferenze del programma ed aggiungiamo l&#8217;account di Google ai calendari attuali come nella schermata successiva, in tal modo verrà visualizzato in iCal il calendario principale.</p>
<p><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/aggiunta-account.png"><img class="aligncenter size-full wp-image-325" title="Aggiunta account ad iCal" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/aggiunta-account.png" alt="" width="599" height="516" /></a></p>
<p>Per visualizzare anche gli altri calendari aggiunti è sufficiente cliccare sulla scheda Delega nella pagina dell&#8217;account e spuntare i calendari a cui siamo interessati. Piccola nota, utilizzando questo approccio i calendari aggiuntivi appariranno nella categoria DELEGATI con una grafica non proprio accattivante, non ho trovato un modo per cambiare questa visualizzazione, se qualcuno conosce il modo mi farebbe piacere se lo scrivesse nei commenti.</p>
<p>A questo punto mancano due passi ancora per terminare, il trasferimento dei vecchi calendari da iCal a Google e l&#8217;impostazione dell&#8217;iPhone/iPod Touch/iPad. Per quanto riguarda il primo passo è disponibile una guida direttamente nell&#8217;<a href="http://www.google.com/support/calendar/bin/answer.py?answer=83126&amp;cbid=-8ptf5ufot0as&amp;src=cb&amp;lev=%20index">help di Google Calendar</a>. I passaggi indicati vanno ripetuti per ognuno dei calendari a cui siamo interessati, dopodiché i calendari originali, indicati nell&#8217;interfaccia di iCal nella categoria &#8220;SUL MIO MAC&#8221; andrebbero eliminati da iCal in modo da non visualizzare eventi doppi.</p>
<p>Passando alla parte finale della configurazione, la configurazione del dispositivo mobile, anche qui è presente <a href="http://www.google.com/support/mobile/bin/answer.py?answer=138740&amp;topic=14252">un&#8217;ottima guida</a> passo passo da parte di Google, in ogni caso la configurazione da fare è composta da pochi passi. È sufficiente andare sulle preferenze del telefono e nella voce &#8220;Mail, Contatti e Calendari&#8221; selezionare &#8220;Aggiungi account&#8221;; selezionare Exchange come tipo di account e inserire i dati del proprio account Gmail, lasciando la voce &#8220;Dominio&#8221; vuota. Nella schermata successiva inserire m.google.com alla voce &#8220;Server&#8221; e poi selezionare &#8220;Successivo&#8221; in alto a sinistra.</p>
<p style="text-align: center;"><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/impostazioni.png"><img class="alignnone size-full wp-image-329" title="impostazioni" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/impostazioni.png" alt="" width="192" height="288" /></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/aggiungi.png"><img class="alignnone size-full wp-image-330" title="aggiungi" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/aggiungi.png" alt="" width="192" height="288" /></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/exchange.png"><img class="alignnone size-full wp-image-331" title="exchange" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/exchange.png" alt="" width="192" height="288" /></a></p>
<p style="text-align: center;"><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/exchange.png"></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/dati.png"><img class="size-full wp-image-334 alignnone" title="dati" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/dati.png" alt="" width="192" height="288" /></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/server.png"><img class="alignnone size-full wp-image-337" title="server" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/server.png" alt="" width="192" height="288" /></a></p>
<p>Infine selezionare i servizi da sincronizzare tramite l&#8217;account, il mio suggerimento è per il momento di attivare solamente la sincronizzazione dei calendari, in futuro esplorerò anche la modalità ottimale di sincronizzare i contatti, mentre per la posta preferisco decisamente IMAP a meno che uno non preferisca la modalità push, ma usando questo approccio ci sono <a href="http://www.google.com/support/mobile/bin/answer.py?hl=it&amp;answer=139635">alcune limitazioni</a> che in IMAP non sono presenti, per cui preferisco non usarla.</p>
<p>A questo punto il più è fatto, ma al momento abbiamo solamente il calendario principale sincronizzato sul telefono, per farlo è necessario accedere alla pagina <a href="http://m.google.com/sync">http://m.google.com/sync</a> con il broswer dell&#8217;iPhone (in alternativa si può usare Safari sul Mac avendo l&#8217;accortezza di cambiare lo User Agent in &#8220;Safari Mobile 4.0.2&#8243; attraverso il menù Sviluppo), comparirà una schermata che dice che il browser in uso non è supportato, ma in realtà basta cliccare su &#8220;Modifica lingua&#8221; e selezionare English (US) nella pagina successiva per arrivare al punto desiderato, ovvero quello mostrato nella schermata successiva.</p>
<p style="text-align: center;"><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/sync-iniziale.png"><img class="alignnone size-medium wp-image-340" title="sync iniziale" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/sync-iniziale-300x280.png" alt="" width="300" height="280" /></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/login.png"><img class="alignnone size-medium wp-image-341" title="login" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/login-251x300.png" alt="" width="251" height="300" /></a></p>
<p>Facendo il login si avrà a disposizione la lista dei propri dispositivi su cui si è impostata la sincronizzazione di tipo Exchange, cliccando sul dispositivo al quale si è interessati è possibile selezionare i calendari da sincronizzare ed il gioco è fatto.</p>
<p style="text-align: center;"><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/login.png"></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/devices1.png"><img class="alignnone size-medium wp-image-346" title="devices" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/devices1-251x300.png" alt="" width="251" height="300" /></a><a href="http://www.codewithstyle.eu/wp-content/uploads/2010/11/calendars.png"><img class="alignnone size-medium wp-image-343" title="calendars" src="http://www.codewithstyle.eu/wp-content/uploads/2010/11/calendars-251x300.png" alt="" width="251" height="300" /></a></p>
<p>Una nota sulle modalità di recupero dei dati, di default l&#8217;iPhone la imposta su Push, ovvero le modifiche fatte attraverso interfaccia web o tramite iCal diventano immediatamente visibili (a discapito però della batteria) mentre su iCal di default l&#8217;aggiornamento avviene ogni 15 minuti, quindi le modifiche (fatte dal telefono) non saranno immediatamente visibili. Entrambe queste impostazioni possono essere cambiate a piacimento dagli appositi menù.</p>
<p>Infine una nota dolente, i colori dei calendari su iPhone/iPad sono casuali, non ho trovato nessun modo di cambiarli. L&#8217;unica indicazione che ho trovato in giro suggerisce di disattivare e riattivare la sincronizzazione in quanto i colori vengono riassegnati (sempre in modalità random) e di ripetere la procedura fintanto ché non si trova una combinazione di colori che aggrada. Non mi sembra il massimo come soluzione, per cui se qualcuno trova un modo differente per risolvere questo piccolo problema è pregato di segnalarlo nei commenti.</p>
<p>Buona sincronizzazione.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/Err17iJR9M4gWztg8wPGQMLL86U/0/da"><img src="http://feedads.g.doubleclick.net/~a/Err17iJR9M4gWztg8wPGQMLL86U/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Err17iJR9M4gWztg8wPGQMLL86U/1/da"><img src="http://feedads.g.doubleclick.net/~a/Err17iJR9M4gWztg8wPGQMLL86U/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=6ka84vgFBdQ:Y5kxJIoC4Ms:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=6ka84vgFBdQ:Y5kxJIoC4Ms:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=6ka84vgFBdQ:Y5kxJIoC4Ms:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=6ka84vgFBdQ:Y5kxJIoC4Ms:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=6ka84vgFBdQ:Y5kxJIoC4Ms:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=6ka84vgFBdQ:Y5kxJIoC4Ms:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=6ka84vgFBdQ:Y5kxJIoC4Ms:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/6ka84vgFBdQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2010/11/12/google-sync-sincronizzare-iphone-e-mac-over-the-air/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2010/11/12/google-sync-sincronizzare-iphone-e-mac-over-the-air/</feedburner:origLink></item>
		<item>
		<title>Visualizzare il contenuto degli archivi in QuickLook</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/-dQN0nwID28/</link>
		<comments>http://www.codewithstyle.eu/2010/10/22/visualizzare-il-contenuto-degli-archivi-in-quicklook/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 00:00:21 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[quicklook]]></category>
		<category><![CDATA[snow leopard]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=304</guid>
		<description><![CDATA[Una delle funzionalità migliori aggiunta a Mac OS X nella versione 10.5 è sicuramente stata l&#8217;introduzione di QuickLook, ovvero la possibilità di visualizzare in anteprima i file dal finder senza aprire il programma associato, ma solamente evidenziando un file e premendo la barra spaziatrice. Chiaramente non tutti i file sono supportati da QuickLook ma per [...]]]></description>
			<content:encoded><![CDATA[<p>Una delle funzionalità migliori aggiunta a Mac OS X nella versione 10.5 è sicuramente stata l&#8217;introduzione di QuickLook, ovvero la possibilità di visualizzare in anteprima i file dal finder senza aprire il programma associato, ma solamente evidenziando un file e premendo la barra spaziatrice. Chiaramente non tutti i file sono supportati da QuickLook ma per quelli non supportati (o anche per cambiare l&#8217;anteprima di quelli supportati) gli sviluppatori Apple hanno previsto la possibilità di usare un meccanismo di plugin.<br />
<span id="more-304"></span><br />
Per quanto riguarda gli archivi esiste l&#8217;utilissimo <a href="http://macitbetter.com/BetterZip-Quick-Look-Generator">BetterZip</a> che consente di visualizzare in QuickLook il contenuto di vari tipi di archivio (ZIP, TAR, GZip, BZip2, ISO, RAR più molti altri) senza doverne estrarre il contenuto e senza aprire nessun programma.</p>
<p>Per l&#8217;installazione del plugin è sufficiente scaricare <a href="http://macitbetter.com/BetterZipQL.zip">l&#8217;archivio contenente il generator</a> e copiare il file <code>BetterZipQL.qlgenerator</code> contenuto al suo interno in <code>/Library/QuickLook</code> se lo si vuole installare per tutti gli utenti del sistema oppure in <code>~/Library/QuickLook</code> se lo si vuole solamente per l&#8217;utente corrente.</p>
<p>Una volta installato per far si che sia attivo bisogna aspettare qualche minuto che QuickLook si accorga del nuovo generator oppure forzarne il caricamento con il comando <code>qlmanage -r</code>.</p>
<p>Il risultato che si avrà quando si preme la barra su di un archivio è <a href="http://www.codewithstyle.eu/wp-content/uploads/2010/10/betterzip.png">questo</a></p>
<p>Infine un sito che raccoglie una vasta lista di plugin aggiuntivi per QuickLook: <a href="http://www.quicklookplugins.com/">http://www.quicklookplugins.com/</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/3XMBZsUAd070TG1pQ3AAOLPTRDQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/3XMBZsUAd070TG1pQ3AAOLPTRDQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/3XMBZsUAd070TG1pQ3AAOLPTRDQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/3XMBZsUAd070TG1pQ3AAOLPTRDQ/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dQN0nwID28:YUFAr892-pU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dQN0nwID28:YUFAr892-pU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dQN0nwID28:YUFAr892-pU:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dQN0nwID28:YUFAr892-pU:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=-dQN0nwID28:YUFAr892-pU:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dQN0nwID28:YUFAr892-pU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=-dQN0nwID28:YUFAr892-pU:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/-dQN0nwID28" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2010/10/22/visualizzare-il-contenuto-degli-archivi-in-quicklook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2010/10/22/visualizzare-il-contenuto-degli-archivi-in-quicklook/</feedburner:origLink></item>
		<item>
		<title>Installare il comando tree su Mac OS X</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/SLpuIb3KTpQ/</link>
		<comments>http://www.codewithstyle.eu/2010/10/22/installare-il-comando-tree-su-mac-os-x/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 23:32:21 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[shell scripting]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=298</guid>
		<description><![CDATA[Il comando tree è un comando di terminale molto utile per chi lavora molto con questo strumento. Il suo output fornisce un elenco strutturato dei file e delle directory contenuti in un determinato path, molto utile mentre si naviga in un albero di directory usando il terminale. Purtroppo tale comando non è presente di default [...]]]></description>
			<content:encoded><![CDATA[<p>Il comando <code>tree</code> è un comando di terminale molto utile per chi lavora molto con questo strumento. Il suo output fornisce un elenco strutturato dei file e delle directory contenuti in un determinato path, molto utile mentre si naviga in un albero di directory usando il terminale.</p>
<p><span id="more-298"></span></p>
<p>Purtroppo tale comando non è presente di default in Mac OS X, per averlo a disposizione si può installare il gestore di pacchetti <a href="http://www.macports.org/">MacPorts</a>, ma chi non volesse installarlo può sempre avere a disposizione questo comando installando il binario tramite sorgenti. Per fare ciò sono sufficienti pochi comandi per scaricare i sorgenti</p>
<pre class="brush: bash; title: ; notranslate">
curl -O ftp://mama.indstate.edu/linux/tree/tree-1.5.3.tgz
tar xzvf tree-1.5.3.tgz
cd tree-1.5.3/
</pre>
<p>Fatto ciò è necessario cambiare il Makefile per compilare il programma per Mac commentando queste righe relative a Linux</p>
<pre class="brush: bash; title: ; notranslate">
# Linux defaults:
#CFLAGS=-ggdb -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
#CFLAGS=-O2 -Wall -fomit-frame-pointer -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
#LDFLAGS=-s
</pre>
<p>ed decommentando queste relative a Mac</p>
<pre class="brush: bash; title: ; notranslate">
# Uncomment for OS X:
CC=cc
CFLAGS=-O2 -Wall -fomit-frame-pointer -no-cpp-precomp
LDFLAGS=
XOBJS=strverscmp.o
</pre>
<p>Alla fine è sufficiente compilare ed installarlo nel path di sistema con i comandi</p>
<pre class="brush: bash; title: ; notranslate">
make
sudo make install
</pre>
<p>ed il comando sarà a disposizione anche su Mac.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/BYnuH4kYddSqSVd53pP20nvARB8/0/da"><img src="http://feedads.g.doubleclick.net/~a/BYnuH4kYddSqSVd53pP20nvARB8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/BYnuH4kYddSqSVd53pP20nvARB8/1/da"><img src="http://feedads.g.doubleclick.net/~a/BYnuH4kYddSqSVd53pP20nvARB8/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=SLpuIb3KTpQ:VkvUxs1fcrY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=SLpuIb3KTpQ:VkvUxs1fcrY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=SLpuIb3KTpQ:VkvUxs1fcrY:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=SLpuIb3KTpQ:VkvUxs1fcrY:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=SLpuIb3KTpQ:VkvUxs1fcrY:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=SLpuIb3KTpQ:VkvUxs1fcrY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=SLpuIb3KTpQ:VkvUxs1fcrY:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/SLpuIb3KTpQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2010/10/22/installare-il-comando-tree-su-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2010/10/22/installare-il-comando-tree-su-mac-os-x/</feedburner:origLink></item>
		<item>
		<title>Verificare i dati recuperati con ddrescue e md5sum</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/lMbcelEg5BA/</link>
		<comments>http://www.codewithstyle.eu/2010/03/18/verificare-i-dati-recuperati-con-ddrescue-e-md5sum/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 23:59:54 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[ddrescue]]></category>
		<category><![CDATA[filesystem]]></category>
		<category><![CDATA[md5]]></category>
		<category><![CDATA[md5sum]]></category>
		<category><![CDATA[recupero dati]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=293</guid>
		<description><![CDATA[In un precedente post ho spiegato come recuperare dati da un supporto danneggiato utilizzando il programma GNU ddrescue. Sfortunatamente se il recupero non è completo ci possono essere dei file danneggiati all&#8217;interno del materiale recuperato. In questo post utilizzeremo nuovamente il programma ddrescue per verificare quanto e quale del materiale sia stato effettivamente recuperato. Ho [...]]]></description>
			<content:encoded><![CDATA[<p>In un precedente post ho spiegato <a href="http://www.codewithstyle.eu/2009/12/05/recuperare-i-propri-files-da-un-disco-danneggiato/">come recuperare dati da un supporto danneggiato</a> utilizzando il programma <a href="http://www.gnu.org/software/ddrescue/ddrescue.html">GNU ddrescue</a>. Sfortunatamente se il recupero non è completo ci possono essere dei file danneggiati all&#8217;interno del materiale recuperato. In questo post utilizzeremo nuovamente il programma ddrescue per verificare quanto e quale del materiale sia stato effettivamente recuperato.<span id="more-293"></span></p>
<p>Ho appena perso un disco da 500 GB con al suo interno una partizione piena circa al 50%, il disco ha cominciato improvvisamente a manifestare chiari problemi sia in lettura sia in scrittura, per cui prima che si rompesse del tutto ho voluto eseguire una copia dei dati al suo interno. Chiaramente la copia dal filesystem risultava impossibile per via degli errori restituiti dal dispositivo, per cui ho preso un nuovo disco della stessa capacità ed ho avviato il fido ddrescue.</p>
<p>Dopo circa 1 giorno il contenuto del disco era stato copiato quasi del tutto poco meno dei 500GB totali (ddrescue copia tutti i settori del dispositivo, indipendentemente dal filesystem, per cui sono stati copiati anche i blocchi vuoti) , ma mancavano circa 70MB che restituivano errori in lettura. Ho avviato la seconda passata di ddrescue con le opzioni <code>-d</code> e <code>-r 2</code> per tentare il recupero di questi ulteriori 70 MB ed ho lasciato andare per circa 3 giorni. Quando mancavano solamente 11MB (ma purtroppo sparsi in 12000 settori differenti) anche ddrescue si è arreso e rimanevano questi dati non copiati. Una volta montato il filesystem recuperato il problema a questo punto era capire quali file erano integri e quali no, infatti leggendo il log prodotto da ddrescue si poteva leggere quanto segue</p>
<pre class="brush: plain; title: ; notranslate">
# Rescue Logfile. Created by GNU ddrescue version 1.11
# current_pos  current_status
0x14E248400     -
#      pos        size  status
0x00000000  0x0FD49800  +
0x0FD49800  0x00000400  -
0x0FD49C00  0x0000FA00  +
0x0FD59600  0x00000600  -
0x0FD59C00  0x000B4E00  +
0x0FE0EA00  0x00000200  -
0x0FE0EC00  0x0000F200  +
0x0FE1DE00  0x00000200  -
0x0FE1E000  0x00000200  +
0x0FE1E200  0x00000400  -
0x0FE1E600  0x000B4E00  +
0x0FED3400  0x00000400  -
0x0FED3800  0x0000F000  +
0x0FEE2800  0x00000600  -
0x0FEE2E00  0x000C4000  +
</pre>
<p>In questo log ad ogni &#8211; sulla terza colonna corrisponde una parte di disco non recuperata che inizia all&#8217;indirizzo nella prima colonna e la cui lunghezza in bytes è espressa nella seconda colonna. Praticamente nel disco mancavano blocchetti di pochi bytes (in media 400) in 11000 indirizzi diversi il che indica che è, da un punto di vista probabilistico, impossibile che tutti i file siano stati recuperati correttamente.</p>
<p>Per stabilire con certezza quali file siano corrotti ho utilizzato <a href="http://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html#Fill-Mode">la modalità fill di ddrescue</a>. La prima cosa da fare è quella di montare il filesystem recuperato (se si ha la possibilità meglio eseguire tutte le operazioni su un&#8217;ulteriore copia) in modalità readonly e calcolare i checksum dei file presenti nel dispositivo. Nel mio caso il disco recuperato era <code>sdc</code> per cui ho eseguito questi comandi allo scopo</p>
<pre class="brush: plain; title: ; notranslate">
# mount-o ro /dev/sdc1 /mnt/rescued
# find /mnt/rescued/ -type f -print0 | xargs -0 -n 1 md5sum &gt;&gt; rescued.md5.txt
</pre>
<p>In questo modo ho salvato tutti i checksum dei file presenti nella partizione <code>/dev/sdc1</code> nel file <code>rescued.md5.txt</code>. Questo comando a seconda della dimensione totale dei files può richiedere parecchio, nel mio caso circa 2 ore e mezza. A questo punto ho invocato nuovamente ddrescue in modalità fill in modo da riempire tutti i buchi presenti nell&#8217;hard disk con una stringa fissa, in modo da cambiare l&#8217;md5 dei file coinvolti. La funzione md5 ci garantisce che anche cambiando un solo bit in un file l&#8217;hash generato cambia radicalmente per cui il rischio che un file mantenesse lo stesso hash era praticamente zero (è molto più probabile vincere al superenalotto&#8230;). Per riempire i blocchi danneggiati ho eseguito i seguenti comandi</p>
<pre class="brush: plain; title: ; notranslate">
# umount /dev/sdc1
# echo -n &quot;BAD SECTOR &quot; &gt; tmpfile
# ddrescue --fill=- tmpfile /dev/sdc rescued.log
</pre>
<p>Questa operazione è molto veloce in quanto avviene su un disco funzionante, per cui in meno di un minuto ddrescue ha completato il suo lavoro. A questo punto non resta che rimontare il filesystem e verificare quali file sono cambiati su disco, per fare ciò sono sufficiente questi comandi.</p>
<pre class="brush: plain; title: ; notranslate">
# mount -o ro /dev/sdc1 /mnt/rescued
# md5sum -c rescued.md5.txt &gt; checklist.txt
</pre>
<p>Passate altre 2 ore e mezza circa la lista è pronta, basta leggere il file <code>checklist.txt</code> per capire quali file sono integri e quali no, infatti il contenuto del file è all&#8217;incirca questo</p>
<pre class="brush: plain; title: ; notranslate">
/mnt/rescued/IMG_0096.JPG: OK
/mnt/rescued/IMG_0247.jpg: OK
/mnt/rescued/IMG_0249.jpg: FAILED
/mnt/rescued/IMG_0253.jpg: OK
/mnt/rescued/IMG_0256.jpg: OK
/mnt/rescued/IMG_0482.JPG: OK
/mnt/rescued/IMG_0485.JPG: OK
/mnt/rescued/IMG_0486.JPG: OK
/mnt/rescued/IMG_0487.JPG: OK
/mnt/rescued/IMG_0489.JPG: OK
/mnt/rescued/IMG_0490.JPG: FAILED
/mnt/rescued/IMG_0491.JPG: FAILED
/mnt/rescued/IMG_0492.JPG: FAILED
/mnt/rescued/IMG_0493.JPG: FAILED
</pre>
<p>In alternativa si possono costruire le liste dei file integri e di quelli rovinati utilizzando grep in questo modo</p>
<pre class="brush: plain; title: ; notranslate">
# grep OK$ checklist.txt &gt; files.ok.txt
# grep FAILED$ checklist.txt &gt; files.bad.txt
</pre>

<p><a href="http://feedads.g.doubleclick.net/~a/G81oqs1tH-lK4MYXaz1VHnbD8tM/0/da"><img src="http://feedads.g.doubleclick.net/~a/G81oqs1tH-lK4MYXaz1VHnbD8tM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/G81oqs1tH-lK4MYXaz1VHnbD8tM/1/da"><img src="http://feedads.g.doubleclick.net/~a/G81oqs1tH-lK4MYXaz1VHnbD8tM/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=lMbcelEg5BA:CFr6s1386Mc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=lMbcelEg5BA:CFr6s1386Mc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=lMbcelEg5BA:CFr6s1386Mc:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=lMbcelEg5BA:CFr6s1386Mc:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=lMbcelEg5BA:CFr6s1386Mc:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=lMbcelEg5BA:CFr6s1386Mc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=lMbcelEg5BA:CFr6s1386Mc:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/lMbcelEg5BA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2010/03/18/verificare-i-dati-recuperati-con-ddrescue-e-md5sum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2010/03/18/verificare-i-dati-recuperati-con-ddrescue-e-md5sum/</feedburner:origLink></item>
		<item>
		<title>Creazione di un raid software livello 5 con Debian o Ubuntu</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/Awuw5pry6uc/</link>
		<comments>http://www.codewithstyle.eu/2010/02/17/creazione-di-un-raid-software-livello-5-con-debian-o-ubuntu/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 00:27:17 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[debian]]></category>
		<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[filesystem]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mdadm]]></category>
		<category><![CDATA[raid]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=282</guid>
		<description><![CDATA[Nella gestione dei dati una delle tecniche migliori da utilizzare è sicuramente il RAID, in particolare tra tutti i livelli disponibili per questa tecnologia, quello che offre il miglior rapporto tra prestazioni, uso disco e ridondanza è sicuramente il livello 5. Esistono 3 tipologie di RAID a livello implementativo RAID hardware: disponibile sui server di [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-289" style="margin: 5px;" title="RAID5" src="http://www.codewithstyle.eu/wp-content/uploads/2010/02/RAID5-300x245.png" alt="" width="210" height="172" />Nella gestione dei dati una delle tecniche migliori da utilizzare è sicuramente il <a href="http://it.wikipedia.org/wiki/RAID">RAID</a>, in particolare tra tutti i livelli disponibili per questa tecnologia, quello che offre il miglior rapporto tra prestazioni, uso disco e ridondanza è sicuramente il livello 5. Esistono 3 tipologie di RAID a livello implementativo</p>
<ul>
<li>RAID hardware: disponibile sui server di fascia alta, è quello che offre forse le migliori performance in quanto le operazioni vengono eseguite tutte dal controller in maniera completamente trasparente, ma ha sicuramente i costi più elevati. Inoltre utilizzando questa tipologia di raid i dati sono legati al controller utilizzato e non possono essere utilizzati ad esempio in un&#8217;altra macchina senza che si utilizzi lo stesso controlloer</li>
<li>FAKERAID: ovvero RAID hardware a basso costo. Questa è la tecnologia che viene usata sui controller di fascia bassa oppure implementata nelle motherboard dei computer desktop. Questa tecnologia viene chiamata fakeraid in quanto non è un RAID vero e proprio ma una parte dell&#8217;implementazione e della computazione viene lasciata alla CPU e l&#8217;interfacciamento con i dati avviene tramite un driver. Qui le performance sono decisamente più basse e rimane il problema del trasporto dei dati da un sistema all&#8217;altro. Inoltre non è detto che il driver di questi controller sia disponibile per tutti i sistemi operativi.</li>
<li>RAID software: quello di cui discuteremo qui. Il maggiore vantaggio di questa tecnologia è il controllo assoluto sui propri dati, si possono aggiungere e rimuovere dispositivi a piacere e soprattutto si possono trasferire da una macchina all&#8217;altra. Inoltre è possibile eseguire le operazioni di manutenzione a sistema attivo, cosa che non è possibile negli altri due casi in cui è richiesto un reboot.<span id="more-282"></span></li>
</ul>
<p>Per questo tutorial utilizzerò una macchina virtuale in modo da poter aggiungere dischi a piacimento e simulare la rottura di un disco rimuovendolo dalla macchina virtuale. Il sistema operativo di questa macchina virtuale è Ubuntu 9.10, ma i comandi ed i pacchetti utilizzati sono gli stessi che si utilizzerebbero su Debian. L&#8217;unico pacchetto che va installato per poter creare e manipolare array di dischi è il pacchetto mdadm che mette a disposizione l&#8217;omonimo comando.</p>
<p>Per creare un array di dischi a utilizzando il RAID5 sono necessari almeno 3 dischi/partizioni della stessa dimensione. Degli N dischi utilizzati uno di essi è utilizzato come codice di controllo in maniera circolare, per cui lo spazio effettivo a disposizione nell&#8217;array risultante sarà pari ad (n-1) * disksize. Il livello di fault tolerance offerto da questa soluzione è di un disco, ovvero il sistema rimane in funzione ed i dati rimangono integri se si danneggia fino ad un disco, in caso di rottura di più di un disco contemporaneamente i dati sono irrimediabilmente persi. Se si hanno più dischi a disposizione si può configurare uno di essi come spare disk, ovvero come disco di emergenza. Nel caso di rottura di un disco esso verrà rimpiazzato automaticamente dal disco di riserva ottenendo quindi una fault tolerance pari a 2 dischi.</p>
<p>Nella macchina virtuale di esempio verranno utilizzati 3 dischi da 3GB per la configurazione iniziale che porteranno quindi ad un array di dimensione 6GB.</p>
<h2>Creazione delle partizioni</h2>
<p>Una volta aggiunti i dischi alla macchina virtuale essi appaiono come dispositivi vuoti, quindi come prima cosa vanno partizionati per poter essere utilizzati come membri di array. Il tipo di partizione per il RAID è <code>fd</code>, per cui utilizzando fdisk la sequenza di comandi da utilizzare per ognuno dei 3 dischi è la seguente:</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/# fdisk /dev/sdb
Il dispositivo non contiene né una tabella delle partizioni DOS valida, né una disklabel Sun, SGI od OSF
Building a new DOS disklabel with disk identifier 0xd90f450c.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Attenzione: il flag 0x0000 non valido della tabella delle partizioni 4 verrà corretto con w(rite)

Comando (m per richiamare la guida): n
Azione comando
   e   estesa
   p   partizione primaria (1-4)
p
Numero della partizione (1-4): 1
Primo cilindro (1-391, predefinito 1):
Utilizzo del valore predefinito 1
Last cilindro, +cilindri or +size{K,M,G} (1-391, predefinito 391):
Utilizzo del valore predefinito 391

Comando (m per richiamare la guida): t
Partizione selezionata 1
Codice esadecimale (digitare L per elencare i codici): fd
Modificato il tipo di sistema della partizione 1 in fd (Autorilevamento raid di Linux)

Comando (m per richiamare la guida): w
La tabella delle partizioni è stata alterata!

Chiamata di ioctl() per rileggere la tabella delle partizioni.
Sincronizzazione dei dischi in corso.</pre>
<p>Il procedimento va ripetuto per tutti e tre i dischi in modo da prepararli per la costruzione dell&#8217;array. Una volta create le partizioni dopo aver creato le partizioni per tutti i dischi interessati si dovrebbe avere questo output digitando il comando <code>fdisk -l</code></p>
<pre class="brush: plain; title: ; notranslate">
Disco /dev/sdb: 3221 MB, 3221225472 byte
255 testine, 63 settori/tracce, 391 cilindri
Unità = cilindri di 16065 * 512 = 8225280 byte
Identificativo disco: 0x00000000

Dispositivo Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         391     3140676   fd  Autorilevamento raid di Linux

Disco /dev/sdc: 3221 MB, 3221225472 byte
255 testine, 63 settori/tracce, 391 cilindri
Unità = cilindri di 16065 * 512 = 8225280 byte
Identificativo disco: 0xd90f450c

Dispositivo Boot      Start         End      Blocks   Id  System
/dev/sdc1               1         391     3140676   fd  Autorilevamento raid di Linux

Disco /dev/sdd: 3221 MB, 3221225472 byte
255 testine, 63 settori/tracce, 391 cilindri
Unità = cilindri di 16065 * 512 = 8225280 byte
Identificativo disco: 0x171338f5

Dispositivo Boot      Start         End      Blocks   Id  System
/dev/sdd1               1         391     3140676   fd  Autorilevamento raid di Linux
</pre>
<h2>Creazione dell&#8217;array</h2>
<p>Come accennato in precedenza tutte le operazioni vengono eseguite con il comando mdadm. Per vedere le opzioni a disposizione vedere la relativa pagina di manuale, in ogni caso per creare il volume è sufficiente eseguire il comando</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/# mdadm --create --verbose /dev/md0 --level=5 --raid-devices=3 /dev/sdb1 /dev/sdc1 /dev/sdd1
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 64K
mdadm: size set to 3140608K
mdadm: array /dev/md0 started.</pre>
<p>In questo modo si è creato ed avviato il device /dev/md0 che può essere utilizzato come una normale partizione in modo del tutto trasparente. Per controllare che il device sia stato utilizzato correttamente basta eseguire</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sdd1[2] sdc1[1] sdb1[0]
      6281216 blocks level 5, 64k chunk, algorithm 2 [3/3] [UUU]

unused devices: &lt;none&gt;
</pre>
<p>Se l&#8217;array è stato creato correttamente siamo a posto, ma dobbiamo fare in modo che esso venga avviato all&#8217;avvio del sistema operativo. Per fare ciò dobbiamo editare (o creare) il file mdadm.conf che normalmente dovrebbe trovarsi in <code>/etc</code>, ma in Ubuntu si trova in <code>/etc/mdadm/mdadm.conf</code>. Per i dettagli relativi a tale file consultare la pagina di manuale relativa (ovvero mdadm.conf). In ogni caso l&#8217;opzione che va inserita per caricare all&#8217;avvio l&#8217;array appena creato è ARRAY. Per ottenere automaticamente il contenuto di tale opzione è sufficiente eseguire il comando</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/# mdadm --examine --scan
ARRAY /dev/md0 level=raid5 num-devices=3 UUID=c5a20602:9985ece9:11a1047a:ce03a3ef</pre>
<p>L&#8217;output generato da tale comando è la linea che dobbiamo inserire nel file di configurazione. Un&#8217;altra opzione utile da considerare in tale file è MAILADDR ovvero l&#8217;indirizzo di posta a cui il demone mdadm invierà le email per segnalare eventuali anomalie nel sistema. Su Ubuntu/Debian il programma mdadm viene avviato automaticamente all&#8217;avvio del sistema, su altre distribuzioni potrebbe essere necessario aggiungere uno script in init.d a tale scopo. Infine un&#8217;ultima opzione che consiglio di lasciare al valore di default è DEVICE. Questa opzione indica a mdadm in quali device deve ricercare partizioni di tipo <code>fd</code>. Il valore di default è partitions, ovvero tutte le partizioni elencate in <code>/proc/partitions</code>. Utilizzando questo valore invece che la lista esplicita delle partizioni di tipo RAID non si rischia di dimenticare nessuna partizione che potrebbe contenere una parte di array.</p>
<p>Finito di editare il file mdadm.conf riavviamo il sistema e controlliamo al riavvio attraverso il file <code>/proc/mdstat</code> che l&#8217;array sia stato inizializzato correttamente (ovvero che si abbia lo stesso output avuto in precedenza).</p>
<p>Se tutto è andato a buon fine si può cominciare ad utilizzare il device creando un filesystem su di esso. Ad esempio per creare un filesystem di tipo ext3 con il seguente comando</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/home/fabio# mkfs.ext3 /dev/md0
mke2fs 1.41.9 (22-Aug-2009)
Etichetta del filesystem=
Tipo SO: Linux
Dimensione blocco=4096 (log=2)
Dimensione frammento=4096 (log=2)
393216 inode, 1570304 blocchi
78515 blocchi (5.00%) riservati per l'utente root
Primo blocco dati=0
Maximum filesystem blocks=1610612736
48 gruppi di blocchi
32768 blocchi per gruppo, 32768 frammenti per gruppo
8192 inode per gruppo
Backup del superblocco salvati nei blocchi:
	32768, 98304, 163840, 229376, 294912, 819200, 884736

Scrittura delle tavole degli inode: fatto
Creating journal (32768 blocks): fatto
Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto

Questo filesystem verrà automaticamente controllato ogni 25 mount, o
180 giorni, a seconda di quale venga prima. Usare tune2fs -c o -i per cambiare.
</pre>
<h2>Fault tolerance in RAID5</h2>
<p>Vediamo ora cosa succede disconnettendo un disco dalla macchina virtuale, simulando così la rottura di un disco. Per verificare l&#8217;integrità dei dati nella partizione costruita sul RAID ho creato alcuni files dal contenuto casuale (con il comando <code>dd if=/dev/urandom of=testfile bs=1MB count=100</code>) e ne ho salvato l&#8217;md5 in un file di testo.</p>
<p>Spegnendo la macchina virtuale ed eliminando un disco al successivo riavvio l&#8217;array non verra&#8217; montato e, se configurata la variabile MAILADDR in mdadm.conf ci arriverà un messaggio di posta che ci avvisa che l&#8217;array è degradato. Sarà comunque possibile avviare l&#8217;array utilizzando il seguente comando ed i verificare che i dati sono integri e disponibili</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/mnt/raid# mdadm -As
mdadm: /dev/md0 has been started with 2 drives (out of 3).
root@fabio-laptop-ubuntu:/mnt/raid# mount /mnt/raid
root@fabio-laptop-ubuntu:/mnt/raid# md5sum -c md5
testfile: OK
testfile1: OK
testfile2: OK
testfile3: OK
</pre>
<p>Chiaramente questo è molto pericoloso in quanto se si dovesse rovinare un altro disco sarebbe tutto irrimediabilmente perso (ed inoltre le performance sono ridotte all&#8217;osso in quanto i dati del disco mancante sono calcolati a partire dagli altri 2). Per cui il passo successivo è quello di rimpiazzare al più presto il disco mancante e ricostruire l&#8217;array. Inserendo un nuovo disco per sostituire il precedente e partizionandolo come in precedenza (quindi sempre come <code>/dev/sdd1</code>), sarà sufficiente eseguire il seguente comando per ricostruire l&#8217;array e tornare operativi e coperti da eventuali ulteriori guasti:</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/mnt/raid# mdadm /dev/md0 --add /dev/sdd1
mdadm: added /dev/sdd1
</pre>
<p>A questo punto l&#8217;array verrà ricostruito automaticamente come si può verificare con il comando</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/mnt/raid# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid5 sdd1[3] sdb1[0] sdc1[1]
      6281216 blocks level 5, 64k chunk, algorithm 2 [3/2] [UU_]
      [&gt;....................]  recovery =  4.9% (154624/3140608) finish=2.2min speed=22089K/sec

unused devices: &lt;none&gt;
</pre>
<h2>Aggiunta di un nuovo disco all&#8217;array</h2>
<p>Nello stesso modo in cui si sostituisce un disco/partizione che ha fallito è possibile aggiungere un nuovo device all&#8217;array nel caso in cui fossimo a corto di spazio. Per cui una volta inserito il nuovo disco nella macchina si può aggiungere all&#8217;array con il comando</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/mnt/raid# mdadm /dev/md0 --add /dev/sde1
mdadm: added /dev/sde1
</pre>
<p>In questo modo si è aggiunto il disco all&#8217;array ma allo stato attuale delle cose il nuovo disco viene considerato come disco di spare, ovvero come disco di emergenza da usare in caso di fallimento di un altro disco. Per aggiungere questo dispositivo allo spazio effettivamente disponibile bisogna utilizzare un altro comando con il quale si ingrandisce l&#8217;array.</p>
<pre class="brush: plain; title: ; notranslate">
root@fabio-laptop-ubuntu:/mnt/raid# mdadm --grow /dev/md0 --raid-devices=4
mdadm: Need to backup 384K of critical section..
mdadm: ... critical section passed.
</pre>
<p>Anche qui si può controllare lo stato della ricostruzione dell&#8217;array con il comando</p>
<pre class="brush: plain; title: ; notranslate">root@fabio-laptop-ubuntu:/mnt/raid# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10]
md0 : active raid5 sde1[3] sdb1[0] sdd1[2] sdc1[1]
      6281216 blocks super 0.91 level 5, 64k chunk, algorithm 2 [4/4] [UUUU]
      [&gt;....................]  reshape =  2.5% (79680/3140608) finish=3.8min speed=13280K/sec

unused devices: &lt;none&gt;
</pre>
<p>Dopo che si è aggiunto il disco però è necessario un altro passo, ovvero l&#8217;estensione del filesystem, altrimenti non otterremmo nessun beneficio nell&#8217;aver aggiunto ulteriore spazio. Nel caso di ext3 questa operazione può essere eseguita al volo con il comando</p>
<pre class="brush: plain; title: ; notranslate">root@fabio-laptop-ubuntu:/mnt/raid# resize2fs /dev/md0
resize2fs 1.41.9 (22-Aug-2009)
Filesystem at /dev/md0 is mounted on /mnt/raid; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/md0 to 2355456 (4k) blocks.
The filesystem on /dev/md0 is now 2355456 blocks long.
</pre>

<p><a href="http://feedads.g.doubleclick.net/~a/1duUnO5dZE8w-DHB-4cpEswXVHw/0/da"><img src="http://feedads.g.doubleclick.net/~a/1duUnO5dZE8w-DHB-4cpEswXVHw/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/1duUnO5dZE8w-DHB-4cpEswXVHw/1/da"><img src="http://feedads.g.doubleclick.net/~a/1duUnO5dZE8w-DHB-4cpEswXVHw/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Awuw5pry6uc:QUNyMAWz6QU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Awuw5pry6uc:QUNyMAWz6QU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Awuw5pry6uc:QUNyMAWz6QU:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Awuw5pry6uc:QUNyMAWz6QU:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=Awuw5pry6uc:QUNyMAWz6QU:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=Awuw5pry6uc:QUNyMAWz6QU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=Awuw5pry6uc:QUNyMAWz6QU:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/Awuw5pry6uc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2010/02/17/creazione-di-un-raid-software-livello-5-con-debian-o-ubuntu/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2010/02/17/creazione-di-un-raid-software-livello-5-con-debian-o-ubuntu/</feedburner:origLink></item>
		<item>
		<title>Geotag delle foto con iPhone, Everytrail ed exiftool</title>
		<link>http://feedproxy.google.com/~r/FabiosTechBlog/~3/-dj6Ev-y-EM/</link>
		<comments>http://www.codewithstyle.eu/2010/02/16/geotag-delle-foto-con-iphone-everytrail-ed-exiftool/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 02:04:22 +0000</pubDate>
		<dc:creator>fabio</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[everytrail]]></category>
		<category><![CDATA[exiftool]]></category>
		<category><![CDATA[geotag]]></category>
		<category><![CDATA[gps]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[iphoto]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://www.codewithstyle.eu/?p=274</guid>
		<description><![CDATA[Una delle funzioni che ho apprezzato maggiormente di iPhoto 09 è l&#8217;aggiunta di &#8220;Places&#8221; (nella versione italiana &#8220;Luoghi&#8221;). Questa funzione si interfaccia con Google Maps per mostrare una mappa interattiva delle proprie fotografie e dei luoghi dove esse sono state scattate. Per far si che le foto vengano mostrate sulla mappa è necessario però che [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-medium wp-image-278" style="margin: 5px;" title="places" src="http://www.codewithstyle.eu/wp-content/uploads/2010/02/places-300x299.png" alt="" width="240" height="239" />Una delle funzioni che ho apprezzato maggiormente di iPhoto 09 è l&#8217;aggiunta di &#8220;Places&#8221; (nella versione italiana &#8220;Luoghi&#8221;). Questa funzione si interfaccia con Google Maps per mostrare una mappa interattiva delle proprie fotografie e dei luoghi dove esse sono state scattate.</p>
<p>Per far si che le foto vengano mostrate sulla mappa è necessario però che le immagini contengano i dati GPS negli appositi campi EXIF. Questo può essere ottenuto in vari modi, ad esempio iPhone, essendo dotato di un modulo GPS interno, inserisce automaticamente tali dati nelle proprie foto. Altre macchine fotografiche di fascia medio alta hanno integrato un sensore GPS oppure dispongono di un interfaccia hardware per collegare un ricevitore esterno, normalmente questo comporta una spesa aggiuntiva che con un iPhone ed un po di sforzo possiamo evitare.<span id="more-274"></span></p>
<p>Il metodo che descriverò ora funziona con qualsiasi macchina fotografica, anzi in realtà con qualsiasi immagine. È richiesto solamente un po di lavoro da eseguire tramite riga di comando per taggare correttamente le proprie foto. Basta utilizzare uno dei tanti software disponibili per iPhone per registrare i propri percorsi in formato <a href="http://en.wikipedia.org/wiki/GPS_eXchange_Format">GPX</a>. Io mi sono trovato bene con il software <a href="http://itunes.apple.com/it/app/everytrail/id342467041?mt=8">EveryTrail</a> che è un software gratuito, ma esistono moltissime alternative su AppStore.</p>
<p>Una volta scaricato il software e necessario creare un account (gratuito anch&#8217;esso) sul sito di EveryTrail per poter caricare i propri percorsi tramite iPhone. Una volta che si è creato l&#8217;account è possibile visualizzare i propri percorsi registrati con l&#8217;applicazione.</p>
<p>Per cui nel momento in cui si inizia a scattare ricordatevi di avviare l&#8217;applicazione e tenetela attiva sul telefono. In caso di arrivo di una chiamata l&#8217;applicazione va in pausa ed è sempre possibile riprendere in seguito il percorso iniziato in precedenza. Quando avete terminato di scattare eseguite l&#8217;upload del percorso, cliccate sul link che vi arriva per email e scaricate il file gpx con i dati GPS registrati.</p>
<h2>Sincronizzazione e geotag con exiftool</h2>
<p>Le operazioni da eseguire per effettuare il geotag possono essere eseguite utilizzando <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">exiftool</a>. Il programma, una volta installato, mette a disposizione da riga di comando l&#8217;eseguibile exiftool, la cui pagina di manuale si trova <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/exiftool_pod.html">qui</a>. Il programma è uno strumento molto potente da utilizzare a riga di comando. Negli esempi seguenti utilizzerò le opzioni che vanno a sovrascrivere i file originali che sono</p>
<pre class="brush: plain; title: ; notranslate">
  -P          (-preserve)          Preserve date/time of original file
  -overwrite_original_in_place     Overwrite original by copying tmp file
</pre>
<p>Nel caso in cui si esegua qualche esperimento è il caso di non utilizzare tali opzioni,  in quanto con esse i file originali vengono sostituiti e non c&#8217;è modo di recuperarli.</p>
<p>Indipendentemente da come si è ottenuto il file con i dati gps la cosa più importante da verificare è la sincronizzazione tra gli orari delle immagini e quelli indicati nel file con le coordinate gps. La cosa migliore da fare è di sincronizzare il proprio iPhone e la propria camera prima di cominciare, possibilmente con una precisione al secondo. Se questo non è possibile o ce ne siamo semplicemente dimenticati (come è successo a me) è possibile cambiare la data di scatto nei dati EXIF.</p>
<p>La prima cosa da fare è quella di calcolare l&#8217;offset tra il tempo di scatto ed il tempo esatto, nel mio caso l&#8217;orario della macchinetta era completamente sballato (di circa una settimana) per cui ho dovuto cambiare completamente data ed ora. Per eseguire questa procedura ho eseguito una fotografia al display del telefono in modo da avere sul file la data di scatto memorizzata dalla macchinetta e nell&#8217;immagine il tempo registrato dall&#8217;iPhone. Confrontando i dati ho ottenuto una differenza di tempo pari ad 8 giorni, 13 ore 44 minuti e 24 secondi, per cui facendo riferimento a <a href="http://search.cpan.org/dist/Image-ExifTool/lib/Image/ExifTool/Shift.pl">questa pagina di manuale riguardante lo shift di tempi e date</a> la sintassi da utilizzare con exiftool è</p>
<pre class="brush: bash; title: ; notranslate">exiftool -P -overwrite_original_in_place -DateTimeOriginal+='8 13:44:24' -createdate+='8 13:44:24' *.JPG
   22 image files updated
</pre>
<p>Ora che la data del file è corretta è possibile utilizzare il file gpx per assegnare la localizzazione ad ogni foto, il comando per fare ciò è il seguente</p>
<pre class="brush: bash; title: ; notranslate">
exiftool -geotag geodata.gpx -P -overwrite_original_in_place *.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1263.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1264.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1265.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1266.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1267.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1268.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1269.JPG
Warning: Time is too far before track in File:Geotime (ValueConvInv) - DSCF1270.JPG
Warning: Time is too far beyond track in File:Geotime (ValueConvInv) - DSCF1281.JPG
Warning: Time is too far beyond track in File:Geotime (ValueConvInv) - DSCF1282.JPG
Warning: Time is too far beyond track in File:Geotime (ValueConvInv) - DSCF1283.JPG
Warning: Time is too far beyond track in File:Geotime (ValueConvInv) - DSCF1284.JPG
   10 image files updated
   12 image files unchanged
</pre>
<p>Come si vede nel caso in cui  alcune immagini non rientrino nell&#8217;intervallo temporale dei dati gps, exiftool ce lo segnala con un warning e lascia i file in questione invariati. Alla fine di questo processo potete importare le foto in iPhoto ed esse compariranno sulla mappa in &#8220;Luoghi&#8221;.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/G-nje2EbRpInH5ApJbuyE47bhFo/0/da"><img src="http://feedads.g.doubleclick.net/~a/G-nje2EbRpInH5ApJbuyE47bhFo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/G-nje2EbRpInH5ApJbuyE47bhFo/1/da"><img src="http://feedads.g.doubleclick.net/~a/G-nje2EbRpInH5ApJbuyE47bhFo/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dj6Ev-y-EM:fMBji2yYsAc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dj6Ev-y-EM:fMBji2yYsAc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dj6Ev-y-EM:fMBji2yYsAc:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?d=I9og5sOYxJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dj6Ev-y-EM:fMBji2yYsAc:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=-dj6Ev-y-EM:fMBji2yYsAc:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/FabiosTechBlog?a=-dj6Ev-y-EM:fMBji2yYsAc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/FabiosTechBlog?i=-dj6Ev-y-EM:fMBji2yYsAc:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/FabiosTechBlog/~4/-dj6Ev-y-EM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.codewithstyle.eu/2010/02/16/geotag-delle-foto-con-iphone-everytrail-ed-exiftool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.codewithstyle.eu/2010/02/16/geotag-delle-foto-con-iphone-everytrail-ed-exiftool/</feedburner:origLink></item>
	</channel>
</rss>

