mirror of
https://github.com/almet/notmyidea.git
synced 2025-04-28 19:42:37 +02:00
306 lines
No EOL
17 KiB
HTML
306 lines
No EOL
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>Working directly on your server? How to backup and sync your dev environment with unison</title>
|
|
<meta charset="utf-8" />
|
|
<link rel="stylesheet" href="./theme/css/main.css" type="text/css" />
|
|
<link href="./feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Alexis' log ATOM Feed" />
|
|
|
|
|
|
<!--[if IE]>
|
|
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
|
|
|
<!--[if lte IE 7]>
|
|
<link rel="stylesheet" type="text/css" media="all" href="./css/ie.css"/>
|
|
<script src="./js/IE8.js" type="text/javascript"></script><![endif]-->
|
|
|
|
<!--[if lt IE 7]>
|
|
<link rel="stylesheet" type="text/css" media="all" href="./css/ie6.css"/><![endif]-->
|
|
|
|
</head>
|
|
|
|
<body id="index" class="home">
|
|
|
|
<a href="http://github.com/ametaireau/">
|
|
|
|
<img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub" />
|
|
|
|
</a>
|
|
|
|
<header id="banner" class="body">
|
|
<h1><a href=".">Alexis' log </a></h1>
|
|
<nav><ul>
|
|
|
|
|
|
|
|
<li><a href="./pages/projects.html">projects</a></li>
|
|
|
|
|
|
|
|
<li ><a href="./category/asso.html">asso</a></li>
|
|
|
|
<li ><a href="./category/dev.html">dev</a></li>
|
|
|
|
<li ><a href="./category/python.html">python</a></li>
|
|
|
|
<li class="active"><a href="./category/system.html">system</a></li>
|
|
|
|
<li ><a href="./category/thoughts.html">thoughts</a></li>
|
|
|
|
</ul></nav>
|
|
</header><!-- /#banner -->
|
|
|
|
<section id="content" class="body">
|
|
<article>
|
|
<header> <h1 class="entry-title"><a href=""
|
|
rel="bookmark" title="Permalink to Working directly on your server? How to backup and sync your dev environment with unison">Working directly on your server? How to backup and sync your dev environment with unison</a></h1> </header>
|
|
<div class="entry-content">
|
|
<footer class="post-info">
|
|
<abbr class="published" title="2011-03-16T00:00:00">
|
|
Wed 16 March 2011
|
|
</abbr>
|
|
|
|
|
|
<address class="vcard author">
|
|
By <a class="url fn" href="./author/Alexis Métaireau.html">Alexis Métaireau</a>
|
|
</address>
|
|
|
|
<p>In <a href="./category/system.html">system</a>. </p>
|
|
<p>tags: <a href="./tag/freebsd.html">freebsd</a><a href="./tag/unison.html">unison</a></p>
|
|
|
|
|
|
</footer><!-- /.post-info -->
|
|
<p>I have a server running freebsd since some time now, and was wondering about
|
|
the possibility to directly have a development environment ready to use when
|
|
I get a internet connexion, even if I'm not on my computer.</p>
|
|
<p>Since I use vim to code, and spend most of my time in a console while
|
|
developing, it's possible to work via ssh, from everywhere.</p>
|
|
<p>The only problem is the synchronisation of the source code, config files etc.
|
|
from my machine to the server.</p>
|
|
<p>Unison provides an interesting way to synchronise two folders, even over
|
|
a network. So let's do it !</p>
|
|
<div class="section" id="creating-the-jail">
|
|
<h2>Creating the jail</h2>
|
|
<p>In case you don't use FreeBSD, you can skip this section.</p>
|
|
<div class="highlight"><pre><span class="c"># I have a flavour jail named default</span>
|
|
<span class="nv">$ </span>ezjail-admin -f default workspace.notmyidea.org 172.19.1.6
|
|
<span class="nv">$ </span>ezjail-admin start workspace.notmyidea.org
|
|
</pre></div>
|
|
<p>In my case, because the "default" flavour contains already a lot of interesting
|
|
things, my jail come already setup with ssh, bash and vim for instance, but
|
|
maybe you'll need it in your case.</p>
|
|
<p>I want to be redirected to the ssh of the jail when I connect to the host with
|
|
the 20006 port. Add lines in <cite>/etc/pf.conf</cite>:</p>
|
|
<pre class="literal-block">
|
|
workspace_jail="172.19.1.6"
|
|
rdr on $ext_if proto tcp from any to $ext_ip port 20006 -> $workspace_jail port 22
|
|
</pre>
|
|
<p>Reload packet filter rules</p>
|
|
<div class="highlight"><pre><span class="nv">$ </span>/etc/rc.d/pf reload
|
|
</pre></div>
|
|
</div>
|
|
<div class="section" id="working-with-unison">
|
|
<h2>Working with unison</h2>
|
|
<p>Now that we've set up the jail. Set up unison on the server and on your client.
|
|
Unison is available on the freebsd ports so just install it</p>
|
|
<div class="highlight"><pre><span class="nv">$ </span>ssh notmyidea.org -p 20006
|
|
<span class="nv">$ </span>make -C /usr/ports/net/unison-nox11 config-recursive
|
|
<span class="nv">$ </span>make -C /usr/ports/net/unison-nox11 package-recursive
|
|
</pre></div>
|
|
<p>Install as well unison on your local machine. Double check to install the same
|
|
version on the client and on the server. Ubuntu contains the 2.27.57 as well as
|
|
the 2.32.52.</p>
|
|
<p>Check that unison is installed and reachable via ssh from your machine</p>
|
|
<div class="highlight"><pre><span class="nv">$ </span>ssh notmyidea.org -p 20006 unison -version
|
|
unison version 2.27.157
|
|
<span class="nv">$ </span>unison -version
|
|
unison version 2.27.57
|
|
</pre></div>
|
|
</div>
|
|
<div class="section" id="let-sync-our-folders">
|
|
<h2>Let sync our folders</h2>
|
|
<p>The first thing I want to sync is my vim configuration. Well, it's already <a class="reference external" href="http://github.com/ametaireau/dotfiles/">in
|
|
a git repository</a> but let's try to use
|
|
unison for it right now.</p>
|
|
<p>I have two machines then: <cite>workspace</cite>, the jail, and <cite>ecureuil</cite> my laptop.</p>
|
|
<div class="highlight"><pre>unison .vim ssh://notmyidea.org:20006/.vim
|
|
unison .vimrc ssh://notmyidea.org:20006/.vimrc
|
|
</pre></div>
|
|
<p>It is also possible to put all the informations in a config file, and then to
|
|
only run <cite>unison</cite>. (fire up <cite>vim ~/.unison/default.prf</cite>.</p>
|
|
<p>Here is my config:</p>
|
|
<pre class="literal-block">
|
|
root = /home/alexis
|
|
root = ssh://notmyidea.org:20006
|
|
|
|
path = .vimrc
|
|
path = dotfiles
|
|
path = dev
|
|
|
|
follow = Name *
|
|
</pre>
|
|
<p>My vimrc is in fact a symbolic link on my laptop, but I don't want to specify
|
|
each of the links to unison. That's why the <cite>follow = Name *</cite> is for.</p>
|
|
<p>The folders you want to synchronize are maybe a bit large. If so, considering
|
|
others options such as rsync for the first import may be a good idea (I enjoyed
|
|
my university huge upload bandwith to upload 2GB in 20mn ;)</p>
|
|
</div>
|
|
<div class="section" id="run-the-script-frequently">
|
|
<h2>Run the script frequently</h2>
|
|
<p>Once that done, you just need to run the unison command line some times when
|
|
you want to sync your two machines. I've wrote a tiny script to get some
|
|
feedback from the sync:</p>
|
|
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span>
|
|
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
|
|
|
<span class="n">DEFAULT_LOGFILE</span> <span class="o">=</span> <span class="s">"~/unison.log"</span>
|
|
<span class="n">PROGRAM_NAME</span> <span class="o">=</span> <span class="s">"Unison syncer"</span>
|
|
|
|
<span class="k">def</span> <span class="nf">sync</span><span class="p">(</span><span class="n">logfile</span><span class="o">=</span><span class="n">DEFAULT_LOGFILE</span><span class="p">,</span> <span class="n">program_name</span><span class="o">=</span><span class="n">PROGRAM_NAME</span><span class="p">):</span>
|
|
<span class="c"># init</span>
|
|
<span class="n">display_message</span> <span class="o">=</span> <span class="bp">True</span>
|
|
<span class="n">error</span> <span class="o">=</span> <span class="bp">False</span>
|
|
|
|
<span class="n">before</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
|
|
<span class="c"># call unison to make the sync</span>
|
|
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s">'unison -batch > {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">logfile</span><span class="p">))</span>
|
|
|
|
<span class="c"># get the duration of the operation</span>
|
|
<span class="n">td</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">before</span>
|
|
<span class="n">delta</span> <span class="o">=</span> <span class="p">(</span><span class="n">td</span><span class="o">.</span><span class="n">microseconds</span> <span class="o">+</span> <span class="p">(</span><span class="n">td</span><span class="o">.</span><span class="n">seconds</span> <span class="o">+</span> <span class="n">td</span><span class="o">.</span><span class="n">days</span> <span class="o">*</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">)</span> <span class="o">*</span> <span class="mi">10</span><span class="o">**</span><span class="mi">6</span><span class="p">)</span> <span class="o">/</span> <span class="mi">10</span><span class="o">**</span><span class="mi">6</span>
|
|
|
|
<span class="c"># check what was the last entry in the log</span>
|
|
<span class="n">log</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="n">logfile</span><span class="p">))</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="s">'No updates to propagate'</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
|
|
<span class="n">display_message</span> <span class="o">=</span> <span class="bp">False</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="n">l</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">lines</span> <span class="k">if</span> <span class="s">"Synchronization"</span> <span class="ow">in</span> <span class="n">l</span><span class="p">]</span>
|
|
|
|
<span class="n">message</span> <span class="o">=</span> <span class="n">output</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="n">message</span> <span class="o">+=</span> <span class="s">" It took {0}s."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">delta</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">display_message</span><span class="p">:</span>
|
|
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s">'notify-send -i {2} "{0}" "{1}"'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">program_name</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span>
|
|
<span class="s">'error'</span> <span class="k">if</span> <span class="n">error</span> <span class="k">else</span> <span class="s">'info'</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
|
|
<span class="n">sync</span><span class="p">()</span>
|
|
</pre></div>
|
|
<p>This is probably perfectible, but that does the job.</p>
|
|
<p>Last step is to tell you machine to run that frequently. That's what <cite>crontab</cite>
|
|
is made for, so let's <cite>crontab -e</cite>:</p>
|
|
<pre class="literal-block">
|
|
$ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py
|
|
</pre>
|
|
<p>The <cite>~/.Xdbus</cite> allows cron to communicate with your X11 session. Here is its
|
|
content.</p>
|
|
<div class="highlight"><pre><span class="c">#!/bin/bash</span>
|
|
|
|
<span class="c"># Get the pid of nautilus</span>
|
|
<span class="nv">nautilus_pid</span><span class="o">=</span><span class="k">$(</span>pgrep -u <span class="nv">$LOGNAME</span> -n nautilus<span class="k">)</span>
|
|
|
|
<span class="c"># If nautilus isn't running, just exit silently</span>
|
|
<span class="k">if</span> <span class="o">[</span> -z <span class="s2">"$nautilus_pid"</span> <span class="o">]</span>; <span class="k">then</span>
|
|
<span class="nb">exit </span>0
|
|
<span class="k">fi</span>
|
|
|
|
<span class="c"># Grab the DBUS_SESSION_BUS_ADDRESS variable from nautilus's environment</span>
|
|
<span class="nb">eval</span> <span class="k">$(</span>tr <span class="s1">'\0'</span> <span class="s1">'\n'</span> < /proc/<span class="nv">$nautilus_pid</span>/environ | grep <span class="s1">'^DBUS_SESSION_BUS_ADDRESS='</span><span class="k">)</span>
|
|
|
|
<span class="c"># Check that we actually found it</span>
|
|
<span class="k">if</span> <span class="o">[</span> -z <span class="s2">"$DBUS_SESSION_BUS_ADDRESS"</span> <span class="o">]</span>; <span class="k">then</span>
|
|
<span class="nb">echo</span> <span class="s2">"Failed to find bus address"</span> >&2
|
|
<span class="nb">exit </span>1
|
|
<span class="k">fi</span>
|
|
|
|
<span class="c"># export it so that child processes will inherit it</span>
|
|
<span class="nb">export </span>DBUS_SESSION_BUS_ADDRESS
|
|
</pre></div>
|
|
<p>And it comes from <a class="reference external" href="http://ubuntuforums.org/showthread.php?p=10148738#post10148738">here</a>.</p>
|
|
<p>A sync takes about 20s + the upload time on my machine, which stay acceptable for
|
|
all of my developments.</p>
|
|
</div>
|
|
|
|
</div><!-- /.entry-content -->
|
|
|
|
<div class="comments">
|
|
<h2>Comments !</h2>
|
|
<div id="disqus_thread"></div>
|
|
<script type="text/javascript">
|
|
var disqus_identifier = "working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html";
|
|
(function() {
|
|
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
|
dsq.src = 'http://blog-notmyidea.disqus.com/embed.js';
|
|
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
|
})();
|
|
</script>
|
|
</div>
|
|
|
|
|
|
</article>
|
|
</section>
|
|
|
|
<section id="extras" class="body">
|
|
|
|
<div class="blogroll">
|
|
<h2>blogroll</h2>
|
|
<ul>
|
|
|
|
<li><a href="http://biologeek.org">Biologeek</a></li>
|
|
|
|
<li><a href="http://filyb.info/">Filyb</a></li>
|
|
|
|
<li><a href="http://www.libert-fr.com">Libert-fr</a></li>
|
|
|
|
<li><a href="http://prendreuncafe.com/blog/">N1k0</a></li>
|
|
|
|
<li><a href="http://ziade.org/blog">Tarek Ziadé</a></li>
|
|
|
|
<li><a href="http://zubin71.wordpress.com/">Zubin Mithra</a></li>
|
|
|
|
</ul>
|
|
</div><!-- /.blogroll -->
|
|
|
|
|
|
<div class="social">
|
|
<h2>social</h2>
|
|
<ul>
|
|
<li><a href="./feeds/all.atom.xml" rel="alternate">atom feed</a></li>
|
|
|
|
|
|
|
|
<li><a href="http://twitter.com/ametaireau">twitter</a></li>
|
|
|
|
<li><a href="http://lastfm.com/user/akounet">lastfm</a></li>
|
|
|
|
<li><a href="http://github.com/ametaireau">github</a></li>
|
|
|
|
</ul>
|
|
</div><!-- /.social -->
|
|
|
|
</section><!-- /#extras -->
|
|
|
|
<footer id="contentinfo" class="body">
|
|
<address id="about" class="vcard body">
|
|
Proudly powered by <a href="http://alexis.notmyidea.org/pelican/">pelican</a>, which takes great advantages of <a href="http://python.org">python</a>.
|
|
</address><!-- /#about -->
|
|
|
|
<p>The theme is by <a href="http://coding.smashingmagazine.com/2009/08/04/designing-a-html-5-layout-from-scratch/">Smashing Magazine</a>, thanks!</p>
|
|
</footer><!-- /#contentinfo -->
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
var disqus_shortname = 'blog-notmyidea';
|
|
(function () {
|
|
var s = document.createElement('script'); s.async = true;
|
|
s.type = 'text/javascript';
|
|
s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
|
|
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
|
|
}());
|
|
</script>
|
|
|
|
</body>
|
|
</html> |