flurischt.chhttps://flurischt.ch/2017-11-05T00:00:00+01:00Software EngineerEncrypted Duplicity Backup to European Amazon S3 Bucket2017-11-05T00:00:00+01:002017-11-05T00:00:00+01:00flurintag:flurischt.ch,2017-11-05:/encrypted-duplicity-backup-to-european-amazon-s3-bucket.html<p>This post documents how to configure AWS S3 and duplicity to do encrypted backups to the cloud.</p><h1>Introduction</h1>
<p><a href="http://duplicity.nongnu.org/">duplicity</a> supports backups to <a href="https://aws.amazon.com/s3/">AWS S3</a>. There are a lot of howtos out there but most assume that you want to backup to the (default) US region. It gets more complicated for other regions and your mostly left on your own with strange errors from boto, the library that talks to AWS. Below I document how to use duplicity to do GPG encrypted backups to S3 in the <strong>EU (Ireland)</strong> (eu-west-1) region.</p>
<h1>Setting up S3 and IAM</h1>
<p>We'll create an S3-bucket and an IAM user with full access to that bucket. Make sure to use <strong>EU (Ireland)</strong> region so that the backup-script below works.</p>
<ol>
<li>Go to the <a href="https://s3.console.aws.amazon.com">S3 console</a> and create a new bucket in region <strong>EU (Ireland)</strong>. Do <strong>NOT</strong> use dots in the bucket-name (<a href="https://github.com/boto/boto/issues/2836">#2836</a>). Let's say we use <code>MY-S3-BUCKET-NAME</code>.</li>
<li>Next go to <a href="https://console.aws.amazon.com/iam/home">Identity and Access Management</a> (IAM), create a new user with <strong>programmatic access</strong> and write down the <code>access key</code> and <code>secret access key</code>.</li>
<li>Still in IAM create a new policy with the content below and attach it to the user. Make sure to replace <code><MY-S3-BUCKET-NAME></code> with the actual bucket name. </li>
</ol>
<div class="highlight"><pre><span></span><code><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="nt">"Version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2012-10-17"</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="nt">"Statement"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="nt">"Effect"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Allow"</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="nt">"Action"</span><span class="p">:</span><span class="w"> </span><span class="s2">"s3:*"</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="nt">"Resource"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"></span>
<span class="w"> </span><span class="s2">"arn:aws:s3:::<MY-S3-BUCKET-NAME>"</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="s2">"arn:aws:s3:::<MY-S3-BUCKET-NAME>/*"</span><span class="w"></span>
<span class="w"> </span><span class="p">]</span><span class="w"></span>
<span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w"> </span><span class="p">]</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<h1>Server Setup</h1>
<p>Assuming Ubuntu we'll install the latest duplicity version from the ppa:</p>
<div class="highlight"><pre><span></span><code>root@server:~# add-apt-repository ppa:duplicity-team/ppa
root@server:~# apt clean <span class="o">&&</span> apt update <span class="o">&&</span> apt install -y duplicity python-boto
</code></pre></div>
<p>Next we'll need a gpg key to encrypt the backup stored in the cloud:</p>
<div class="highlight"><pre><span></span><code>user@server:~# sudo -i <span class="c1"># we'll run the backup as root. so make the gpg key using user root too</span>
root@server:~# gpg --gen-key <span class="c1"># use kind "RSA and RSA (default)", name "duplicity" and set a passphrase</span>
root@server:~# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub 4096R/<The-GPG-Key-ID> <span class="m">2017</span>-12-05
uid duplicity <span class="o">(</span>...<span class="o">)</span> <....>
sub 4096R/....... <span class="m">2017</span>-12-05
<span class="c1"># export the gpg keys and keep them at a secure location:</span>
root@server:~# gpg -a --export duplicity
root@server:~# gpg -a --export-secret-key duplicity
</code></pre></div>
<p><strong>AGAIN:</strong> Save the gpg key at a secure location and not only on the server. If the server goes down you will not be able to restore your backups without that key!</p>
<h1>Backup Script</h1>
<p>On the server we'll create two files: <code>/root/.duplicity_secrets</code> with the S3 access keys and <code>/root/backup_to_s3.sh</code> which will be the backup script.</p>
<h2>/root/.duplicity_secrets</h2>
<p>This file will hold the S3 access keys and the passphrase to the gpg key:</p>
<div class="highlight"><pre><span></span><code><span class="nb">export</span> <span class="nv">PASSPHRASE</span><span class="o">=</span><span class="s2">"<THE-PASSPHRASE-TO-YOUR-GPG-KEY>"</span>
<span class="nb">export</span> <span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span><span class="s2">"<YOUR-IAM-USERS-ACCESS-KEY>"</span>
<span class="nb">export</span> <span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span><span class="s2">"<YOUR-IAM-USERS-SECRET-ACCESS-KEY>"</span>
</code></pre></div>
<h2>/root/backup_to_s3.sh</h2>
<p>The backup script will source the .duplicity_secrets file and then backup to S3. Below is an example how to backup <code>/etc</code> into a subdirectory <code>server-name/etc</code> in the S3-bucket. Make sure to configure <code><The-GPG-Key-ID></code> and <code><MY-S3-BUCKET-NAME></code> in the following script: </p>
<div class="highlight"><pre><span></span><code><span class="nb">source</span> /root/.duplicity_secrets
<span class="c1"># duplicity args</span>
<span class="c1"># </span>
<span class="nv">s3_bucket</span><span class="o">=</span><span class="s2">"s3://s3.eu-west-1.amazonaws.com/<MY-S3-BUCKET-NAME>/</span><span class="si">${</span><span class="nv">HOSTNAME</span><span class="si">}</span><span class="s2">"</span>
<span class="nv">encrypt_key</span><span class="o">=</span><span class="s2">"<The-GPG-Key-ID>"</span>
<span class="nv">aws_args</span><span class="o">=</span><span class="s2">"--s3-european-buckets --s3-use-new-style"</span>
<span class="c1"># experimental setting that may speed up the backup: --asynchronous-upload</span>
<span class="c1"># backup /etc to <MY-S3-BUCKET-NAME>/hostname/etc</span>
/usr/bin/duplicity <span class="nv">$aws_args</span> --encrypt-key <span class="nv">$encrypt_key</span> -v <span class="m">4</span> <span class="se">\</span>
incr --full-if-older-than 14D <span class="se">\</span>
/etc <span class="si">${</span><span class="nv">s3_bucket</span><span class="si">}</span>/etc
<span class="nb">unset</span> PASSPHRASE
<span class="nb">unset</span> AWS_ACCESS_KEY_ID
<span class="nb">unset</span> AWS_SECRET_ACCESS_KEY
</code></pre></div>
<h1>Some Duplicity commands</h1>
<p>Checkout: <a href="https://help.ubuntu.com/community/DuplicityBackupHowto">https://help.ubuntu.com/community/DuplicityBackupHowto</a></p>
<p>Some examples:</p>
<div class="highlight"><pre><span></span><code>root@server:~# <span class="nb">source</span> /root/.duplicity_secrets
root@server:~# <span class="nb">export</span> <span class="nv">S3_BUCKET</span><span class="o">=</span><span class="s2">"s3://s3.eu-west-1.amazonaws.com/<MY-S3-BUCKET-NAME>/<SET-YOUR-SERVER-HOSTNAME-HERE>"</span>
<span class="c1"># list files in the backup</span>
root@server:~# duplicity list-current-files <span class="nv">$S3_BUCKET</span>/etc
<span class="c1"># restore /etc/fstab to /tmp/restored_fstab</span>
root@server:~# duplicity --file-to-restore fstab <span class="nv">$S3_BUCKET</span>/etc /tmp/restored_fstab
</code></pre></div>
<h1>Troubleshooting</h1>
<p>We're connecting duplicity directly to s3.eu-west-1.amazonaws.com. This is <strong>EU (Ireland)</strong> region and will therefore only work if you setup the bucket in the correct region. If you're using another region you may have to change the URL and/or play with <code>$aws_args</code> in the backup script. If you're getting ACCESS DENIED errors make sure to check the IAM policy and that it is attached to the user.</p>
<h1>Credits</h1>
<p>A lot of this post is based on Igor Cicimov's <a href="https://icicimov.github.io/blog/devops/Duplicity-encrypted-backups-to-Amazon-S3/">Duplicity encrypted backups to Amazon S3</a> post. I followed the steps described there but ran into S3 upload problems with the URL-schema used there. That's why I'm using eu-west-1 and directly connect to that endpoint.</p>Sharir and Pnueli's TWO APPROACHES TO INTERPROCEDURAL DATA FLOW ANALYSIS2017-08-18T00:00:00+02:002017-08-18T00:00:00+02:00flurintag:flurischt.ch,2017-08-18:/sharir-and-pnuelis-two-approaches-to-interprocedural-data-flow-analysis.html<p>This paper is really hard to come by and all scans are either incomplete or include the empty backpages. Here's a cleaned up version: <a href="https://flurischt.ch/upload/static-analysis/sharir-pnueli_two-approaches.pdf">Download</a></p>Spellcheck in Latex Files2017-08-10T00:00:00+02:002017-08-10T00:00:00+02:00flurintag:flurischt.ch,2017-08-10:/spellcheck-in-latex-files.html<p>I use the following snippet to spellcheck latex files:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
hunspell -d en_GB -t <span class="nv">$1</span>
</code></pre></div>
<p>Put it into a spellcheck.sh file. Then <code>./spellcheck.sh myfile.tex</code>.</p>Manually starting ssh-agent to use it in a (remote) terminal session2017-06-22T00:00:00+02:002017-06-22T00:00:00+02:00flurintag:flurischt.ch,2017-06-22:/manually-starting-ssh-agent-to-use-it-in-a-remote-terminal-session.html<p>ssh-agent can be used to unlock an ssh private key and therefore prevent having to enter the password multiple times. Usually your desktop environment does this for you. But if you're for example sshing into your workstation and then use ssh (e.g. for git or hg) your desktop environment …</p><p>ssh-agent can be used to unlock an ssh private key and therefore prevent having to enter the password multiple times. Usually your desktop environment does this for you. But if you're for example sshing into your workstation and then use ssh (e.g. for git or hg) your desktop environment won't help you. Here's how to start ssh-agent and unlock your private key:</p>
<div class="highlight"><pre><span></span><code>> eval `ssh-agent -s`
> ssh-add
</code></pre></div>
<p>Now you can use the unlocked key to make ssh connections. And after your work is done here's how to kill ssh-agent and unlock the key again:</p>
<div class="highlight"><pre><span></span><code>> ssh-agent -k
</code></pre></div>Python networkx (graph library) example2017-06-06T00:00:00+02:002017-06-06T00:00:00+02:00flurintag:flurischt.ch,2017-06-06:/python-networkx-graph-library-example.html<p>This is just for me to look it up again later:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python3</span>
<span class="sd">"""</span>
<span class="sd">A small example that uses networkx and pyplot to create a DiGraph, </span>
<span class="sd">draw it and compute floyd-warshall on it.</span>
<span class="sd">"""</span>
<span class="kn">import</span> <span class="nn">networkx</span> <span class="k">as</span> <span class="nn">nx</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="c1">#https://www.debian.org/vote/2013/vote_001 …</span></code></pre></div><p>This is just for me to look it up again later:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python3</span>
<span class="sd">"""</span>
<span class="sd">A small example that uses networkx and pyplot to create a DiGraph, </span>
<span class="sd">draw it and compute floyd-warshall on it.</span>
<span class="sd">"""</span>
<span class="kn">import</span> <span class="nn">networkx</span> <span class="k">as</span> <span class="nn">nx</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="c1">#https://www.debian.org/vote/2013/vote_001</span>
<span class="c1"># The beats matrix:</span>
<span class="c1">#</span>
<span class="c1"># 1 2 3 4</span>
<span class="c1">#Option 1 88 62 319</span>
<span class="c1">#Option 2 252 141 355</span>
<span class="c1">#Option 3 279 210 353</span>
<span class="c1">#Option 4 51 24 30 </span>
<span class="n">BEATS_MATRIX</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">88</span><span class="p">,</span> <span class="mi">62</span><span class="p">,</span> <span class="mi">319</span><span class="p">],</span>
<span class="p">[</span><span class="mi">252</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">141</span><span class="p">,</span> <span class="mi">355</span><span class="p">],</span>
<span class="p">[</span><span class="mi">279</span><span class="p">,</span> <span class="mi">210</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">353</span><span class="p">],</span>
<span class="p">[</span><span class="mi">51</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
<span class="p">]</span>
<span class="n">NUM_OPTIONS</span> <span class="o">=</span> <span class="mi">4</span>
<span class="c1"># create a graph with candidates that beat each other</span>
<span class="n">G</span><span class="o">=</span><span class="n">nx</span><span class="o">.</span><span class="n">DiGraph</span><span class="p">()</span>
<span class="c1"># create nodes for all options</span>
<span class="k">for</span> <span class="n">option</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">NUM_OPTIONS</span><span class="p">):</span>
<span class="n">G</span><span class="o">.</span><span class="n">add_node</span><span class="p">(</span><span class="n">option</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># connect winner to loser options</span>
<span class="k">for</span> <span class="n">o1</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">NUM_OPTIONS</span><span class="p">):</span>
<span class="k">for</span> <span class="n">o2</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">o1</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">NUM_OPTIONS</span><span class="p">):</span>
<span class="k">if</span> <span class="n">BEATS_MATRIX</span><span class="p">[</span><span class="n">o1</span><span class="p">][</span><span class="n">o2</span><span class="p">]</span> <span class="o">></span> <span class="n">BEATS_MATRIX</span><span class="p">[</span><span class="n">o2</span><span class="p">][</span><span class="n">o1</span><span class="p">]:</span>
<span class="n">u</span> <span class="o">=</span> <span class="n">o1</span><span class="o">+</span><span class="mi">1</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">o2</span><span class="o">+</span><span class="mi">1</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">BEATS_MATRIX</span><span class="p">[</span><span class="n">o1</span><span class="p">][</span><span class="n">o2</span><span class="p">]</span> <span class="o">-</span> <span class="n">BEATS_MATRIX</span><span class="p">[</span><span class="n">o2</span><span class="p">][</span><span class="n">o1</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">u</span> <span class="o">=</span> <span class="n">o2</span><span class="o">+</span><span class="mi">1</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">o1</span><span class="o">+</span><span class="mi">1</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">BEATS_MATRIX</span><span class="p">[</span><span class="n">o2</span><span class="p">][</span><span class="n">o1</span><span class="p">]</span> <span class="o">-</span> <span class="n">BEATS_MATRIX</span><span class="p">[</span><span class="n">o1</span><span class="p">][</span><span class="n">o2</span><span class="p">]</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"option </span><span class="si">{}</span><span class="s2"> wins over </span><span class="si">{}</span><span class="s2"> by </span><span class="si">{}</span><span class="s2"> votes"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">c</span><span class="p">))</span>
<span class="n">G</span><span class="o">.</span><span class="n">add_edge</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="n">c</span><span class="p">)</span>
<span class="c1"># all pairs shortest path example</span>
<span class="n">distance</span> <span class="o">=</span> <span class="n">nx</span><span class="o">.</span><span class="n">floyd_warshall</span><span class="p">(</span><span class="n">G</span><span class="p">)</span>
<span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">NUM_OPTIONS</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">NUM_OPTIONS</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2"> "</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">distance</span><span class="p">[</span><span class="n">u</span><span class="p">][</span><span class="n">v</span><span class="p">]),</span> <span class="n">end</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
<span class="nb">print</span><span class="p">()</span>
<span class="c1">#drawing example</span>
<span class="n">pos</span><span class="o">=</span><span class="n">nx</span><span class="o">.</span><span class="n">spectral_layout</span><span class="p">(</span><span class="n">G</span><span class="p">)</span> <span class="c1"># positions for all nodes</span>
<span class="n">nx</span><span class="o">.</span><span class="n">draw_networkx_nodes</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">pos</span><span class="p">,</span> <span class="n">node_size</span><span class="o">=</span><span class="mi">700</span><span class="p">)</span>
<span class="n">nx</span><span class="o">.</span><span class="n">draw_networkx_edges</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">pos</span><span class="p">,</span> <span class="n">edgelist</span><span class="o">=</span><span class="n">G</span><span class="o">.</span><span class="n">edges</span><span class="p">(),</span> <span class="n">width</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">nx</span><span class="o">.</span><span class="n">draw_networkx_labels</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">pos</span><span class="p">,</span> <span class="n">font_size</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span> <span class="n">font_family</span><span class="o">=</span><span class="s1">'sans-serif'</span><span class="p">)</span>
<span class="n">edge_labels</span><span class="o">=</span><span class="nb">dict</span><span class="p">([((</span><span class="n">u</span><span class="p">,</span><span class="n">v</span><span class="p">,),</span><span class="n">d</span><span class="p">[</span><span class="s1">'weight'</span><span class="p">])</span>
<span class="k">for</span> <span class="n">u</span><span class="p">,</span><span class="n">v</span><span class="p">,</span><span class="n">d</span> <span class="ow">in</span> <span class="n">G</span><span class="o">.</span><span class="n">edges</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="kc">True</span><span class="p">)])</span>
<span class="n">nx</span><span class="o">.</span><span class="n">draw_networkx_edge_labels</span><span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="n">pos</span><span class="p">,</span> <span class="n">edge_labels</span><span class="o">=</span><span class="n">edge_labels</span><span class="p">,</span>\
<span class="n">font_size</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span> <span class="n">font_family</span><span class="o">=</span><span class="s1">'sans-serif'</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s1">'off'</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</code></pre></div>Music for working / learning (updated)2017-05-27T00:00:00+02:002017-05-27T00:00:00+02:00flurintag:flurischt.ch,2017-05-27:/music-for-working-learning-updated.html<p>Some nice music on youtube and soundcloud: </p>
<ul>
<li><a href="http://www.youtube.com/watch?v=2O0kuoiAm2A&list=RDHCU6G1Mt18DlE">Nujabes (Playlist)</a> and <a href="http://www.youtube.com/watch?v=2sML2bq_WGw">Never ending Nujabes</a></li>
<li><a href="https://www.youtube.com/watch?v=oasfi6EDhqg&list=RDw2NQditiTm4">Nomak</a></li>
<li><a href="http://www.youtube.com/watch?v=vHgSp0_Xumk&list=PLpyrjJvJ7GJ7bM5GjzwHvZIqe6c5l3iF6">TheSoundYouNeed</a></li>
<li><a href="https://soundcloud.com/aka-dj-quads/tracks">DJ Quads</a></li>
<li><a href="https://www.dondiablo.com/hexagonradio/">Don Diablo: Hexagon Radio</a></li>
</ul>IntelliJ Idea application menu entry for xubuntu2017-05-25T00:00:00+02:002017-05-25T00:00:00+02:00flurintag:flurischt.ch,2017-05-25:/intellij-idea-application-menu-entry-for-xubuntu.html<p>Assuming intellij has been installed to /opt/ here's how to create an application menu entry (on xubuntu). Create a file <code>~/.local/share/applications/intellij.desktop</code> with the following content:</p>
<div class="highlight"><pre><span></span><code><span class="k">[Desktop Entry]</span><span class="w"></span>
<span class="na">Version</span><span class="o">=</span><span class="s">1.0</span><span class="w"></span>
<span class="na">Type</span><span class="o">=</span><span class="s">Application</span><span class="w"></span>
<span class="na">Name</span><span class="o">=</span><span class="s">IntelliJ</span><span class="w"></span>
<span class="na">Icon</span><span class="o">=</span><span class="s">/opt/jetbrains/idea/bin/idea.png</span><span class="w"></span>
<span class="na">Exec</span><span class="o">=</span><span class="s">/opt/jetbrains/idea/bin …</span></code></pre></div><p>Assuming intellij has been installed to /opt/ here's how to create an application menu entry (on xubuntu). Create a file <code>~/.local/share/applications/intellij.desktop</code> with the following content:</p>
<div class="highlight"><pre><span></span><code><span class="k">[Desktop Entry]</span><span class="w"></span>
<span class="na">Version</span><span class="o">=</span><span class="s">1.0</span><span class="w"></span>
<span class="na">Type</span><span class="o">=</span><span class="s">Application</span><span class="w"></span>
<span class="na">Name</span><span class="o">=</span><span class="s">IntelliJ</span><span class="w"></span>
<span class="na">Icon</span><span class="o">=</span><span class="s">/opt/jetbrains/idea/bin/idea.png</span><span class="w"></span>
<span class="na">Exec</span><span class="o">=</span><span class="s">/opt/jetbrains/idea/bin/idea.sh</span><span class="w"></span>
<span class="na">NoDisplay</span><span class="o">=</span><span class="s">false</span><span class="w"></span>
<span class="na">Categories</span><span class="o">=</span><span class="s">Development;</span><span class="w"></span>
<span class="na">StartupNotify</span><span class="o">=</span><span class="s">false</span><span class="w"></span>
<span class="na">Terminal</span><span class="o">=</span><span class="s">false</span><span class="w"></span>
</code></pre></div>Extend a VirtualBox guest harddisk2017-04-18T00:00:00+02:002017-04-18T00:00:00+02:00flurintag:flurischt.ch,2017-04-18:/extend-a-virtualbox-guest-harddisk.html<p>I use VirtualBox for the rare cases when I need a Windows OS. The latest Win10 updates failed to install because there's not enough disk space. Apparently 30GB is not enough for a whole OS and office... ;-(</p>
<p>Luckily that's easy to fix:</p>
<ul>
<li>Shutdown the guest</li>
<li>Make sure there are no …</li></ul><p>I use VirtualBox for the rare cases when I need a Windows OS. The latest Win10 updates failed to install because there's not enough disk space. Apparently 30GB is not enough for a whole OS and office... ;-(</p>
<p>Luckily that's easy to fix:</p>
<ul>
<li>Shutdown the guest</li>
<li>Make sure there are no snapshots of the virtual machine (I read somewhere that it doesnt work with snapshots. Didn't try it myself)</li>
<li>Resize the disk: <code>VBoxManage modifyhd VIRTUAL_MACHINE_NAME.vdi --resize 40960</code></li>
<li>Start the guest</li>
<li>Extend the C: partition (Right click on the partition in windows disk management)</li>
</ul>
<p>The above steps resize the disk to 40GB. Don't forget the last step. Otherwise you'll have a 40GB disk but Windows won't be using the whole drive.</p>DD-WRT (kong) on Netgear R7000 and Fiber7 IPv6 configuration2017-01-21T00:00:00+01:002017-01-21T00:00:00+01:00flurintag:flurischt.ch,2017-01-21:/dd-wrt-kong-on-netgear-r7000-and-fiber7-ipv6-configuration.html<p>I'm a fan of Netgear's R7000 hardware. Not so much of the software. Since I bought this router I was not able to get IPv6 working with my <a href="https://www.fiber7.ch/">Fiber7</a> internet connection. The Netgear firmware does not support DHCPv6-PD which is what my provider requires. Anyway, not having IPv6 was not …</p><p>I'm a fan of Netgear's R7000 hardware. Not so much of the software. Since I bought this router I was not able to get IPv6 working with my <a href="https://www.fiber7.ch/">Fiber7</a> internet connection. The Netgear firmware does not support DHCPv6-PD which is what my provider requires. Anyway, not having IPv6 was not a big problem (yet). But the latest security vulnerability debacle (see <a href="http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6277">CVE-2016-6277</a> and <a href="http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5521">CVE-2017-5521</a>) was too much. Let's switch to DD-WRT.</p>
<h2>Performance side remarks</h2>
<p>According to the <a href="https://dd-wrt.com/wiki/index.php/DD-WRT_on_R7000">DD-WRT wiki</a> Netgear uses proprietary hardware acceleration for IPv4 NAT. If you use a free firmware you'll lose this hardware acceleration and the throughput will be lower. So with a fast internet connection >= 500 Mbit/s you'll notice this. I have a fast internet connection but don't care about it. We don't get the full speed over W-Lan anyway and I'd rather get rid of the Netgear firmware than have a higher throughput, no IPv6 and all the security udpates...</p>
<h2>Which version?</h2>
<p>Apparently there are two different versions of DD-WRT for the R7000. There's <a href="http://www.desipro.de/ddwrt/K3-AC-Arm/">Kong's mod</a> and then there are the builds on the <a href="ftp://ftp.dd-wrt.com/betas/2016/11-14-2016-r30880/netgear-r7000/">DD-WRT website</a>. I decided to use Kong's mod because they seem to be the dev who brought R7000 support to DD-WRT and their firmware has some additional features (like for example a cli update program).</p>
<h2>DD-WRT Installation</h2>
<p>I use <code>dd-wrt.K3_R7000.chk</code> (dated 18th of January 2017) from <a href="http://www.desipro.de/ddwrt/K3-AC-Arm/">Kong's website</a>. This assumes that currently the official netgear firmware is installed.</p>
<ul>
<li>Reset router to factory defaults using the admin interface</li>
<li>Use the admin interface to upload the new firmware</li>
<li>There might be a warning about installing the same or an older firmware. Just accept it.</li>
<li>As soon as the router is available visit <a href="http://192.168.1.1">http://192.168.1.1</a> and set a DD-WRT admin username and passwort</li>
<li>Now head to <a href="http://192.168.1.1/Factory_Defaults.asp">http://192.168.1.1/Factory_Defaults.asp</a> and <code>Restore Factory Defaults</code>.</li>
<li>Router will reboot and again you need to set username and password on <a href="http://192.168.1.1">http://192.168.1.1</a>.</li>
<li>Since it's not clear (at least for me) whether Restore Factory Defaults also deletes the nvram I did this manually:<ul>
<li>telnet 192.168.1.1</li>
<li>username: root</li>
<li>password: THE_ADMIN_PASSWORD_YOU_SET_BEFORE</li>
<li><code>nvram erase</code></li>
<li><code>reboot</code></li>
</ul>
</li>
<li>Now for the last time set a username and password on <a href="http://192.168.1.1">http://192.168.1.1</a></li>
</ul>
<p>DD-WRT is now installed and you can start configuring it. I mainly set the Wireless Regulatory Domain to Switzerland, configured wireless and port forwarding and enabled IPV6.</p>
<h2>Fiber7 IPv6 settings</h2>
<p>To get IPv6 with my provider working I enabled it here: <a href="http://192.168.1.1/IPV6.asp">http://192.168.1.1/IPV6.asp</a></p>
<ul>
<li>IPv6: enable</li>
<li>IPv6 Type: DHCPv6 with Prefix Delegation</li>
<li>Prefix Length: 48</li>
<li>Static DNS 1: leave empty</li>
<li>Static DNS 2: leave empty</li>
<li>Remaining settings: default</li>
</ul>
<p>After Save, Apply Settings and a Router reboot IPv6 was working on router and clients.</p>
<h2>Further links</h2>
<ul>
<li><a href="http://www.dd-wrt.com/phpBB2/viewtopic.php?t=264152">Kong R7000 Configuration Best Practices or Working Solutions</a></li>
<li><a href="http://www.dd-wrt.com/phpBB2/viewtopic.php?t=306845">New firmware: DD-WRT v3.0-r31160M kongac (01/18/17)</a></li>
</ul>Cups printers do not show up in Firefox (Arch)2017-01-02T00:00:00+01:002017-01-02T00:00:00+01:00flurintag:flurischt.ch,2017-01-02:/cups-printers-do-not-show-up-in-firefox-arch.html<p>If your CUPS printers do not show up in the Firefox printing dialog (but they do for example in Google Chrome) you may be missing the following package: <a href="https://bbs.archlinux.org/viewtopic.php?pid=1664877#p1664877">gtk3-print-backends</a>. Installing this solved that very annoying problem for me.</p>USB Keyboard not working at boot (between GRUB and disk decryption)2016-12-18T00:00:00+01:002016-12-18T00:00:00+01:00flurintag:flurischt.ch,2016-12-18:/usb-keyboard-not-working-at-boot-between-grub-and-disk-decryption.html<p>On my thinkpad I have an encrypted Arch installation setup similarly to <a href="https://flurischt.ch/arch-linux-on-toshiba-cb30-102-chromebook.html">my chromebook setup</a>. Since I bought my a new wireless usb keyboard this thing never worked for decrypting the system. It perfectly works once Arch has started up, but for entering the password at boot I had to …</p><p>On my thinkpad I have an encrypted Arch installation setup similarly to <a href="https://flurischt.ch/arch-linux-on-toshiba-cb30-102-chromebook.html">my chromebook setup</a>. Since I bought my a new wireless usb keyboard this thing never worked for decrypting the system. It perfectly works once Arch has started up, but for entering the password at boot I had to use the notebook keyboard.</p>
<h2>Add missing modules to initramsfs</h2>
<p>Turns out my initramfs was missing the necessary modules.</p>
<ul>
<li>Checkout the <a href="https://wiki.archlinux.org/index.php/Minimal_initramfs#Keyboard_modules">Arch wiki</a></li>
<li>Find the relevant keyboard modules. In my case it was <code>hid_generic</code> and <code>usbhid</code></li>
<li>Edit /etc/mkinitcpio.conf and set <code>MODULES="hid_generic usbhid"</code> (or whatever your modules are)</li>
<li><code>mkinitcpio -p linux</code></li>
<li>Reboot</li>
</ul>Gitlab CE setup2016-11-02T00:00:00+01:002016-11-02T00:00:00+01:00flurintag:flurischt.ch,2016-11-02:/gitlab-ce-setup.html<p>The latest addition to my server at home is a Gitlab Community Edition instance. I use the docker image provided by Gitlab behind a nginx reverse proxy. Below are some notes for setting up, configuring and troubleshooting the installation.</p>
<h2>Docker command</h2>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
sudo docker run --detach <span class="se">\</span>
--publish <span class="m">11180</span>:80 …</code></pre></div><p>The latest addition to my server at home is a Gitlab Community Edition instance. I use the docker image provided by Gitlab behind a nginx reverse proxy. Below are some notes for setting up, configuring and troubleshooting the installation.</p>
<h2>Docker command</h2>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
sudo docker run --detach <span class="se">\</span>
--publish <span class="m">11180</span>:80 --publish <span class="m">11122</span>:22 <span class="se">\</span>
--name gitlab <span class="se">\</span>
--restart always <span class="se">\</span>
--volume /var/docker/volumes/gitlab/config:/etc/gitlab:Z <span class="se">\</span>
--volume /var/docker/volumes/gitlab/logs:/var/log/gitlab:Z <span class="se">\</span>
--volume /var/docker/volumes/gitlab/data:/var/opt/gitlab:Z <span class="se">\</span>
gitlab/gitlab-ce:latest
</code></pre></div>
<p>See <a href="https://github.com/flurischt/dockerfiles/blob/master/images/gitlab/run.sh">run.sh</a></p>
<h2>Gitlab config</h2>
<p>Open a shell in the docker container (<code>sudo docker exec -it gitlab /bin/bash</code>) then edit <code>/etc/gitlab/gitlab.rb</code>. The following subsections show the parts I changed or added. After changing the config <code>gitlab-ctl reconfigure</code> can be run (still in the docker container) to restart gitlab.</p>
<h3>external_url and relative root</h3>
<p>The goal was to run Gitlab over SSL/TLS behind a reverse proxy. Instead of running Gitlab under / it should be accessible under /gitlab. This requires some extra effort:</p>
<div class="highlight"><pre><span></span><code>external_url 'https://SOMEDOMAIN/gitlab' # default: http://hostname
</code></pre></div>
<p>(note httpS and /gitlab). Also setting RAILS_RELATIVE_URL_ROOT was necessary:</p>
<div class="highlight"><pre><span></span><code>gitlab_rails['env'] = {
'RAILS_RELATIVE_URL_ROOT' => "/gitlab"
}
</code></pre></div>
<h3>Email Configuration</h3>
<div class="highlight"><pre><span></span><code>gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "**.**.ch"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_authentication'] = "plain"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_ssl'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
gitlab_rails['smtp_user_name'] = "**@**.ch"
gitlab_rails['smtp_password'] = **
gitlab_rails['smtp_domain'] = **
gitlab_rails['gitlab_email_from'] = 'gitlab@**.ch'
gitlab_rails['gitlab_email_reply_to'] = 'noreply@**.ch'
</code></pre></div>
<h3>Settings for running behind a reverse proxy</h3>
<p>SSL is terminated at the reverse proxy. The communication between nginx and Gitlab will be HTTP.</p>
<div class="highlight"><pre><span></span><code>nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
</code></pre></div>
<h2>NGINX Reverse proxy configuration</h2>
<p>The following snippet proxies requests to /gitlab on nginx back to the locally running Gitlab container.</p>
<div class="highlight"><pre><span></span><code><span class="nt">server</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="err">.....</span><span class="w"></span>
<span class="w"> </span><span class="err">location</span><span class="w"> </span><span class="err">^~</span><span class="w"> </span><span class="err">/gitlab/</span><span class="w"> </span><span class="err">{</span><span class="w"></span>
<span class="w"> </span><span class="err">client_max_body_size</span><span class="w"> </span><span class="err">0</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">gzip</span><span class="w"> </span><span class="err">off</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">##</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">gitlabhq</span><span class="o">/</span><span class="n">gitlabhq</span><span class="o">/</span><span class="n">issues</span><span class="o">/</span><span class="mi">694</span><span class="w"></span>
<span class="w"> </span><span class="err">##</span><span class="w"> </span><span class="n">Some</span><span class="w"> </span><span class="n">requests</span><span class="w"> </span><span class="n">take</span><span class="w"> </span><span class="n">more</span><span class="w"> </span><span class="n">than</span><span class="w"> </span><span class="mi">30</span><span class="w"> </span><span class="n">seconds</span><span class="o">.</span><span class="w"></span>
<span class="w"> </span><span class="n">proxy_read_timeout</span><span class="w"> </span><span class="mi">300</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_connect_timeout</span><span class="w"> </span><span class="err">300</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_redirect</span><span class="w"> </span><span class="err">off</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_http_version</span><span class="w"> </span><span class="err">1.1</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_set_header</span><span class="w"> </span><span class="err">Host</span><span class="w"> </span><span class="err">$http_host</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_set_header</span><span class="w"> </span><span class="err">X-Real-IP</span><span class="w"> </span><span class="err">$remote_addr</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_set_header</span><span class="w"> </span><span class="err">X-Forwarded-Ssl</span><span class="w"> </span><span class="err">on</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_set_header</span><span class="w"> </span><span class="err">X-Forwarded-For</span><span class="w"> </span><span class="err">$proxy_add_x_forwarded_for</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_set_header</span><span class="w"> </span><span class="err">X-Forwarded-Proto</span><span class="w"> </span><span class="err">$scheme</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">proxy_pass</span><span class="w"> </span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="mf">127.0.0.1</span><span class="o">:</span><span class="mi">11180</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="err">}</span><span class="w"></span>
</code></pre></div>
<h2>Assets not found</h2>
<p>Since Gitlab is run under /gitlab it's possible that some fonts, icons and images cannot be found. Running the following commands inside the docker container should fix this:</p>
<div class="highlight"><pre><span></span><code>gitlab-ctl reconfigure
NO_PRIVILEGE_DROP=true USE_DB=false gitlab-rake assets:clean assets:precompile
gitlab-ctl restart
</code></pre></div>
<p><a href="https://gitlab.com/gitlab-org/gitlab-ce/issues/13727#note_3924229">Source</a></p>Ugly fonts in IntelliJ IDEA on Arch Linux2016-10-11T00:00:00+02:002016-10-11T00:00:00+02:00flurintag:flurischt.ch,2016-10-11:/ugly-fonts-in-intellij-idea-on-arch-linux.html<h1>UPDATE</h1>
<p><code>intellij-jdk</code> is now marked orphaned in AUR. I therefore stopped using this package and switched to a manual install of IntelliJ IDEA. This way the bundled jdk by Jetbrains is used automatically.</p>
<h1>Old Post</h1>
<p>Java fonts on Linux have been ugly for a while. Especially in an IDE it's …</p><h1>UPDATE</h1>
<p><code>intellij-jdk</code> is now marked orphaned in AUR. I therefore stopped using this package and switched to a manual install of IntelliJ IDEA. This way the bundled jdk by Jetbrains is used automatically.</p>
<h1>Old Post</h1>
<p>Java fonts on Linux have been ugly for a while. Especially in an IDE it's very annoying. It seems Jetbrains started to ship a patched JDK with IntelliJ 2016. Make sure to use this JDK on Arch to run IntelliJ!</p>
<h2>Install</h2>
<p>Install <code>intellij-jdk</code> from AUR.</p>
<h2>Configuration</h2>
<ul>
<li>Start IntelliJ</li>
<li><code>CTRL+SHIFT+A</code> to enter action</li>
<li>enter "switch JDK"</li>
<li>chose "Switch IDE boot JDK"</li>
<li>point IntelliJ to /opt/intellij-jdk and restart</li>
</ul>
<h2>Notes</h2>
<p>I only use this JDK for running the IDE. For development I'm still using the opendjk packages provided by Arch.
Besides installing this new JDK I also force my java application to use anti-aliasing. To do so add the following to <code>/etc/environment</code>:</p>
<div class="highlight"><pre><span></span><code>_JAVA_OPTIONS='-Dawt.useSystemAAFontSettings=on'
</code></pre></div>Atom editor notes2016-08-11T00:00:00+02:002016-08-11T00:00:00+02:00flurintag:flurischt.ch,2016-08-11:/atom-editor-notes.html<p>Some notes on my atom editor setup. Will be expanded throughout time.</p>
<h2>Plugins</h2>
<div class="highlight"><pre><span></span><code>apm install atom-runner
apm install linter
apm install linter-flake8
apm install linter-gcc
</code></pre></div>
<h3>flake8</h3>
<p>linter-flake8 needs a flake8 binary. We'll install this into a virtualenv used for atom.</p>
<div class="highlight"><pre><span></span><code><span class="nv">mkvirtualenv</span><span class="w"> </span><span class="nv">atom</span><span class="w"></span>
#<span class="w"> </span><span class="nv">make</span><span class="w"> </span><span class="nv">sure</span><span class="w"> </span><span class="nv">you</span><span class="err">'re in the new virtualenv …</span></code></pre></div><p>Some notes on my atom editor setup. Will be expanded throughout time.</p>
<h2>Plugins</h2>
<div class="highlight"><pre><span></span><code>apm install atom-runner
apm install linter
apm install linter-flake8
apm install linter-gcc
</code></pre></div>
<h3>flake8</h3>
<p>linter-flake8 needs a flake8 binary. We'll install this into a virtualenv used for atom.</p>
<div class="highlight"><pre><span></span><code><span class="nv">mkvirtualenv</span><span class="w"> </span><span class="nv">atom</span><span class="w"></span>
#<span class="w"> </span><span class="nv">make</span><span class="w"> </span><span class="nv">sure</span><span class="w"> </span><span class="nv">you</span><span class="err">'re in the new virtualenv. then run:</span>
<span class="err">pip install flake8</span>
<span class="err">pip install flake8-docstrings</span><span class="w"></span>
</code></pre></div>
<h4>Modify Atom's env.PATH</h4>
<p>Open Atom and go to Edit -> Init Script...
Add the following line and make sure '/home/USERNAME/.virtualenvs/atom/bin' points to your atom virtualenv directory:</p>
<div class="highlight"><pre><span></span><code><span class="k">proc</span><span class="nv">ess.env.PATH</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">'/home/USERNAME/.virtualenvs/atom/bin'</span><span class="p">,</span><span class="w"> </span><span class="nv">process.env.PATH</span><span class="p">]</span><span class="nv">.join</span><span class="p">(</span><span class="s">':'</span><span class="p">)</span><span class="w"></span>
</code></pre></div>
<h2>Settings</h2>
<p>Go to Editor -> Preferences
* enable Soft Tabs
* set tab length to 4 spaces</p>
<h2>Shortcuts</h2>
<ul>
<li>ALT+r run file using atom-runner</li>
<li>CTR+SHIFT+m show rendered markdown</li>
</ul>Encrypted Ubuntu 14.04 LTS Installation (RAID, LLVM, LUKS)2016-04-07T00:00:00+02:002016-04-07T00:00:00+02:00flurintag:flurischt.ch,2016-04-07:/encrypted-ubuntu-1404-lts-installation-raid-llvm-luks.html<p>Google drive notes I took when setting up my encrypted Ubuntu 14.04 LTS home server (RAID, LLVM and LUKS).</p><p>I meant to document the setup procedure of my home server for a long time here. Since I never got to write up an article (and probably neverl will) I'll just share my google drive notes here. Maybe you'll find something useful below or on the <a href="https://docs.google.com/document/d/1iEebM2Lv5HhjN1UnvFjmotx62WXp-a1QIsTYjaHxE50/pub">direct link</a>.</p>
<iframe width="100%" height="100%" src="https://docs.google.com/document/d/1iEebM2Lv5HhjN1UnvFjmotx62WXp-a1QIsTYjaHxE50/pub?embedded=true"></iframe>Guided Static Analysis slides2015-10-22T00:00:00+02:002015-10-22T00:00:00+02:00flurintag:flurischt.ch,2015-10-22:/guided-static-analysis-slides.html<p>Checkout the slides of my presentation about the Guided Static Analysis paper by Denis Gopan and Thomas Reps.</p><p>It took so much effort to create these slides so why keep them private? Here's my <a href="http://www.pm.inf.ethz.ch/education/seminars/ResearchTopicsinSoftwareEngineering.html">Research Topics in Software Engineering</a> Talk about Guided Static Analysis by Denis Gopan and Thomas Reps: </p>
<script async class="speakerdeck-embed" data-id="8fa7e00696554a6abcfad890867b0c17" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<p>The paper is available <a href="http://research.cs.wisc.edu/wpis/abstracts/sas07.guided.abs.html">here</a>.</p>Downloading a website for reading offline2015-07-28T00:00:00+02:002015-07-28T00:00:00+02:00flurintag:flurischt.ch,2015-07-28:/downloading-a-website-for-reading-offline.html<p>I needed a way to download all papers and exercises of one of my lectures. Here's a good wget snippet to mirror the website:</p>
<div class="highlight"><pre><span></span><code>wget --mirror --convert-links --adjust-extension --page-requisites -np -nH -N --cut-dirs<span class="o">=</span><span class="m">1</span> http://www.ita.inf.ethz.ch/alscpr15/
</code></pre></div>
<p>Source: Tweet by <a href="https://twitter.com/doublec/status/625421321443262464">@doublec</a> (tweets are protected now)</p>Prevent Firefox from reloading pinned tabs at startup2015-07-08T00:00:00+02:002015-07-08T00:00:00+02:00flurintag:flurischt.ch,2015-07-08:/prevent-firefox-from-reloading-pinned-tabs-at-startup.html<p>Firefox has a setting "<strong>Don't load tabs until selected</strong>". But enabling this will not prevent Firefox from reloading every pinned tab at startup. Fortunately there seems to be a specific preference for this one too:</p>
<ul>
<li>open about:config</li>
<li>set <strong>browser.sessionstore.restore_pinned_tabs_on_demand</strong> to <strong>true</strong></li>
</ul>Arch Linux on Toshiba CB30-102 (Chromebook)2015-06-21T00:00:00+02:002015-06-21T00:00:00+02:00flurintag:flurischt.ch,2015-06-21:/arch-linux-on-toshiba-cb30-102-chromebook.html<p>The <a href="https://wiki.archlinux.org/index.php/Beginners%27_guide">Beginners guide</a> in the wiki is straightforward. Here are just some additional notes on setting up Arch Linux on my chromebook.</p>
<h2>Planned setup</h2>
<p>My device has a 16GB ssd. I'm planning to wipe ChromeOS and partition the disk into two partitions: 2GB /boot (ext4) and a 14GB encrypted partition …</p><p>The <a href="https://wiki.archlinux.org/index.php/Beginners%27_guide">Beginners guide</a> in the wiki is straightforward. Here are just some additional notes on setting up Arch Linux on my chromebook.</p>
<h2>Planned setup</h2>
<p>My device has a 16GB ssd. I'm planning to wipe ChromeOS and partition the disk into two partitions: 2GB /boot (ext4) and a 14GB encrypted partition (dm-crypt + LUKS). A 2GB swapfile will be created inside the encrypted partition.</p>
<h2>Preparations</h2>
<p>Check the Arch wiki for chrome device specific preparations. My device has an alternative boot loader so I just need to press <code>CTR+L</code> at the splash screen to boot from usb-stick or (later) GRUB.</p>
<h2>Installation steps</h2>
<p>Follow the beginners guide. After creating the two partitions and making the /boot partition bootable, proceed to setup the encrypted partions. </p>
<div class="highlight"><pre><span></span><code><span class="c1"># assuming /dev/sda2 is the 14GB partition that will be encrypted</span>
cryptsetup -v --cipher twofish-xts-plain64 --key-size <span class="m">512</span> --hash sha512 --iter-time <span class="m">5000</span> --use-random --verify-passphrase luksFormat /dev/sda2
<span class="c1"># now open the LUKS partition</span>
cryptsetup open --type luks /dev/sda2 root
<span class="c1"># the decrypted partition is now available at /dev/mapper/root</span>
mkfs.ext4 /dev/mapper/root
mount /dev/mapper/root /mnt
<span class="c1"># proceed with installation according to the beginners guide</span>
</code></pre></div>
<p>Check <a href="https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption">Device_encryption</a> for encryptions settings etc.</p>
<h3>Before the first reboot</h3>
<p>Assuming GRUB is used as a boot loader we'll need to make sure that it finds the root device and that the initramfs contains everything necessary to decrypt the partition.</p>
<p>Edit <strong>/etc/default/grub</strong> and configure cryptdevice in GRUB_CMDLINE_LINUX_DEFAULT:</p>
<div class="highlight"><pre><span></span><code>GRUB_CMDLINE_LINUX_DEFAULT="quiet cryptdevice=UUID=6364123f-3052-4745-bb79-ee60416b4309:root:allow-discards"
</code></pre></div>
<p>The UUID should in my case point to /dev/sda2. :root: will make the decrypted partition available at /dev/mapper/root and allow-discards is needed to make the discard mount-option work through disk-encryption. Note: allow-discards may be a security risk. I'm using it anyway. After configuring update the grub configuration with <code>grub-mkconfig -o /boot/grub/grub.cfg</code></p>
<p>At last make sure to add <strong>encrypt</strong> to <strong>/etc/mkinitcpio.conf</strong> before the filesystems hook:</p>
<div class="highlight"><pre><span></span><code>HOOKS="base udev autodetect modconf block encrypt filesystems keyboard fsck"
</code></pre></div>
<p>and update the initramfs:</p>
<div class="highlight"><pre><span></span><code>mkinitcpio -k <span class="m">4</span>.0.5-1-ARCH -g /boot/initramfs-linux.img
</code></pre></div>
<p>(the -k 4.0.5-1-ARCH argument was only needed in my case, because the installed kernel was newer than the one running on the usb-stick. Try it without -k and if it doesn't work, check /lib/modules/ for the correct kernel-version)
You're now ready to exit chroot and reboot (do not forget to install all necessary modules and firmware for the network to work... check the wiki!).</p>
<h2>Configuration</h2>
<p>After the first reboot we should now have a working arch installation. I set up x11, gdm and cinnamon following the wiki instructions. GDM can be enabled at boot with <code>systemctl enable gdm.service</code> </p>
<h3>ChromeOS Buttons</h3>
<p>I used sxhkd to make the ChromeOS Buttons work. </p>
<p>~/.config/sxhkd/sxhkdrc</p>
<div class="highlight"><pre><span></span><code># Web browser Back/Forward shortcuts
{@F1,@F2}
xte 'keydown Alt_L' 'key {Left,Right}' 'keyup Alt_L'
# Web browser Refresh shortcut
@F3
xte 'keydown Control_L' 'key r' 'keyup Control_L'
# Awesome WM maximize current window
# Adjust as necessary for different window managers
#@F4
# xte 'keydown Super_L' 'key m' 'keyup Super_L'
# Awesome WM move one desktop right
@F5
xte 'keydown Super_L' 'key Right' 'keyup Super_L'
{F6,F7}
xbacklight -{dec,inc} 10
F8
amixer set Master toggle
{F9,F10}
amixer set Master 5%{-,+} unmute
</code></pre></div>
<p>Then add /usr/bin/sxhkd to the autostart of your desktop env. For cinnamon I used gnome-session-properties (installable from AUR). You'll need alsa-utils, xorg-backlight, xautomation for the config above to work. The config above is a modified version from the wiki (% for F9, F10). Check <a href="https://wiki.archlinux.org/index.php/Chrome_OS_devices#Sxhkd_configuration">Chrome_OS_devices#Sxhkd_configuration</a>. </p>
<h3>Swapfile</h3>
<p>I use a swapfile inside the encrypted partition. Create a 2GB swapfile with:</p>
<div class="highlight"><pre><span></span><code>dd <span class="k">if</span><span class="o">=</span>/dev/zero <span class="nv">of</span><span class="o">=</span>/swapfile <span class="nv">bs</span><span class="o">=</span>1M <span class="nv">count</span><span class="o">=</span><span class="m">2000</span>
chmod <span class="m">600</span> /swapfile
mkswap /swapfile
swapon /swapfile
</code></pre></div>
<p>and enable it in /etc/fstab:</p>
<div class="highlight"><pre><span></span><code>cat >> /etc/fstab
/swapfile swap swap defaults <span class="m">0</span> <span class="m">0</span>
CTRL+D
</code></pre></div>
<h3>Hibernation</h3>
<p>For hibernate to work, the resume= and resume_offset= (only when a swapfile is used) kernel params must be set and the resume hook in initramfs must be enabled. </p>
<p>add </p>
<div class="highlight"><pre><span></span><code>resume=/dev/mapper/root resume_offset=OFFSET_NO
</code></pre></div>
<p>to <strong>GRUB_CMDLINE_LINUX_DEFAULT</strong> in /etc/default/grub and update the grub config. OFFSET_NO is the first row of physical_offset in <code>filefrag -v /swapfile</code>.</p>
<p>Then add <strong>resume</strong> to HOOKS in /etc/mkinitcpio.conf <strong>after</strong> the encrypt hook (otherwise it would try to resume before decrypting the partition) and update initramfs with <code>mkinitcpio -p linux</code></p>
<p>Hibernation should now work with <code>systemctl hibernate</code>.</p>
<h3>AUR packages</h3>
<p>Checkout <a href="https://wiki.archlinux.org/index.php/Yaourt">yaourt</a>. Quite useful for installing AUR packages.</p>OS X: Reinstall OS stuck at "2 minutes left"2015-03-21T00:00:00+01:002015-03-21T00:00:00+01:00flurintag:flurischt.ch,2015-03-21:/os-x-reinstall-os-stuck-at-2-minutes-left.html<p>You probably have used homebrew. Haven't you?
In the last step of the reinstallation the installer moves / checks files in /usr/local. If you have a lot of files over there (for example because you used homebrew), this takes forever.</p>
<p>Do not abort the installation. Press <code>cmd+L</code> to see …</p><p>You probably have used homebrew. Haven't you?
In the last step of the reinstallation the installer moves / checks files in /usr/local. If you have a lot of files over there (for example because you used homebrew), this takes forever.</p>
<p>Do not abort the installation. Press <code>cmd+L</code> to see the logs.</p>Using git for SVN repos2015-03-21T00:00:00+01:002015-03-21T00:00:00+01:00flurintag:flurischt.ch,2015-03-21:/using-git-for-svn-repos.html<p>We're forced to use SVN for some projects at the university. It's OK but when working on the go (Train) and offline it's a pain. Here are the steps for using git.</p>
<div class="highlight"><pre><span></span><code># initialize repo
git svn clone https://svn-server-address/repo/path
</code></pre></div>
<p>Now you can work and commit to your local …</p><p>We're forced to use SVN for some projects at the university. It's OK but when working on the go (Train) and offline it's a pain. Here are the steps for using git.</p>
<div class="highlight"><pre><span></span><code># initialize repo
git svn clone https://svn-server-address/repo/path
</code></pre></div>
<p>Now you can work and commit to your local git branches.</p>
<div class="highlight"><pre><span></span><code><span class="nv">git</span><span class="w"> </span><span class="nv">checkout</span><span class="w"> </span><span class="o">-</span><span class="nv">b</span><span class="w"> </span><span class="nv">myFeature</span><span class="w"></span>
#<span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="nv">some</span><span class="w"> </span><span class="nv">stuff</span><span class="w"></span>
<span class="nv">git</span><span class="w"> </span><span class="nv">commit</span><span class="w"> </span><span class="o">-</span><span class="nv">m</span><span class="w"> </span><span class="s2">"whatever"</span><span class="w"></span>
</code></pre></div>
<p>To publish my new feature to svn I use the following steps:</p>
<div class="highlight"><pre><span></span><code># fetch the latest svn updates to my master branch
git checkout master
git svn rebase
# rebase my new feature to master
git checkout myFeature
git rebase master
# merge my feature and force git to always make a merge commit
git checkout master
git merge myFeature --no-ff
# commit changes to svn
git svn dcommit
</code></pre></div>
<p>Yes, its dcommit and not commit.</p>x86 assembly on OSX2015-03-21T00:00:00+01:002015-03-21T00:00:00+01:00flurintag:flurischt.ch,2015-03-21:/x86-assembly-on-osx.html<p>During last terms compiler design course I learned x86 assembly "the hard way"... Here's some stuff that I "found out" while developing x86 assembly on OSX 10.10.</p>
<h2>Read this first</h2>
<p>I'm writing this post a couple of months after the course. I did not lookup the instructions and I'm …</p><p>During last terms compiler design course I learned x86 assembly "the hard way"... Here's some stuff that I "found out" while developing x86 assembly on OSX 10.10.</p>
<h2>Read this first</h2>
<p>I'm writing this post a couple of months after the course. I did not lookup the instructions and I'm justing writing what I can remember. It's therefore possible that some instructions below are incorrect. Better look them up yourself instead of copying from here...</p>
<h2>Tools</h2>
<p>I used gcc (compiler/assembler) and gdb (debugger). Place your assembly code in a .s file and assemble it with <code>gcc -m32 -ggdb yoursourcefile.s -o programname</code>. gcc is useful to have a look at generated assembly code too. Just write a c programm and then compile it with the -S flag to generate assembly output. </p>
<h2>Stack alignment on OSX</h2>
<p>There's this sentence </p>
<blockquote>
<p>The stack is 16-byte aligned at the point of function calls</p>
</blockquote>
<p>in the <a href="https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html">IA-32 Function Calling Conventions</a> that gave us in the beginning so much pain. What does it mean? Before calling anything make sure that the stack is aligned to 16 bytes. The annoying thing is, that <strong>inside each function there are already four bytes on the stack (the return-address)</strong>. After the normal function prologue (enter / push %ebp) there will be 8 bytes on the stack. </p>
<p>Example</p>
<div class="highlight"><pre><span></span><code>.globl _main
_main:
enter $8, $0
# stack is now 16 byte aligned.
# 4 + 4 + 8
# return-address + old %ebp value + 8 bytes because of "enter $8.."
leave ret
</code></pre></div>
<p>So, make sure to always increase the stack size by a multiple of 16. The hard part was, that the alignment is only enforced when using systemcalls. In the beginning our programs jumped around a couple of times with a misaligned stack without any problems and then just blew up when printing or reading something. Quite hard to debug but very educational... (learn the hard way indeed).</p>
<h2>Some tricks</h2>
<p>Below are just some tricks I learned. If you've programmed assembly before you'll be bored.</p>
<div class="highlight"><pre><span></span><code>; inside your assembly func you should backup the ebp
; either do
push %ebp
movl %esp, %ebp
; or use the enter instruction:
enter $0, $0
; after the steps above there will be 8 bytes on the stack.
; align it with
subl $8, %esp
; or use enter $8,$0
; because we set %ebp as the first step, we can now use it to
; address stuff in our stack frame.
; some examples:
movl $4, (%ebp) ; write 4 into the stack address where %ebp points to
movl $5, -4(%ebp) ; write 5 into the address four bytes below
movl 8(%ebp), -8(%ebp) ; move the value of a parameter (higher stack address) into a local variable (lower stack address)
; to create local variables, just make space by reducing the esp
subl $4, %esp ; create a 4 byte "variable" on the stack
movl $42, 4(%esp) ; write something to this variable
addl $4, %esp ; free/forget the variable
; instead of subl %esp you can also:
pushl $42 ; decrease %esp by 4
popl %eax ; read the previously pushed $42 to %eax and increase the stack pointer again
; set eax to zero (eax is used as the return value when exiting the program)
xor %eax, %eax
; no example but a tipp: checkout the leal instruction! it is useful for example when using scanf and writing to the stack
; there are instructions for leaving your function
leave
ret
</code></pre></div>Run IntelliJ IDEA 14 on OSX with Java 82015-02-21T00:00:00+01:002015-02-21T00:00:00+01:00flurintag:flurischt.ch,2015-02-21:/run-intellij-idea-14-on-osx-with-java-8.html<p>Starting with Yosemite Apple finally stopped shipping Java 6 with OSX. It's recommended to install the latest Java version directly from Oracle. Unfortunately IntelliJ IDEA needs Java 6 (!) to start. Here is the recommended way to run IntelliJ IDEA with Java 8.</p>
<div class="highlight"><pre><span></span><code># first, install IntelliJ to /Applications
mkdir ~/Library/Preferences …</code></pre></div><p>Starting with Yosemite Apple finally stopped shipping Java 6 with OSX. It's recommended to install the latest Java version directly from Oracle. Unfortunately IntelliJ IDEA needs Java 6 (!) to start. Here is the recommended way to run IntelliJ IDEA with Java 8.</p>
<div class="highlight"><pre><span></span><code># first, install IntelliJ to /Applications
mkdir ~/Library/Preferences/IntelliJIdea14/
cp /Applications/IntelliJ\ IDEA\ 14.app/Contents/bin/idea.properties ~/Library/Preferences/IntelliJIdea14/
# now modify ~/Library/Preferences/IntelliJIdea14/idea.properties and change the JVMVersion from 1.6* to 1.6+
</code></pre></div>
<p>The steps for WebStorm and PyCharm are similar and you can find the directory names <a href="https://intellij-support.jetbrains.com/entries/23358108">here</a>.</p>
<p>In my case the directories were:</p>
<ul>
<li>~/Library/Preferences/WebStorm9</li>
<li>~/Library/Preferences/PyCharm40</li>
</ul>Move/Copy mails between different IMAP accounts2014-11-15T00:00:00+01:002014-11-15T00:00:00+01:00flurintag:flurischt.ch,2014-11-15:/movecopy-mails-between-different-imap-accounts.html<p>I decided to switch back to Gmail/Inbox by Gmail. Copying thousands of mails in Thunderbird is a pain and after a couple of unsuccessful tries I started to search a better working alternative. <a href="http://superuser.com/a/771506">mutt to the rescue</a>!</p>
<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="n">login</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="k">old</span><span class="w"> </span><span class="n">imap</span><span class="w"> </span><span class="nl">account</span><span class="p">:</span><span class="w"></span>
<span class="n">mutt</span><span class="w"> </span><span class="o">-</span><span class="n">f</span><span class="w"> </span><span class="nl">imaps</span><span class="p">:</span><span class="o">//</span><span class="n">username</span><span class="nv">@oldmailserver</span><span class="o">/</span><span class="n">INBOX …</span></code></pre></div><p>I decided to switch back to Gmail/Inbox by Gmail. Copying thousands of mails in Thunderbird is a pain and after a couple of unsuccessful tries I started to search a better working alternative. <a href="http://superuser.com/a/771506">mutt to the rescue</a>!</p>
<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="n">login</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="k">old</span><span class="w"> </span><span class="n">imap</span><span class="w"> </span><span class="nl">account</span><span class="p">:</span><span class="w"></span>
<span class="n">mutt</span><span class="w"> </span><span class="o">-</span><span class="n">f</span><span class="w"> </span><span class="nl">imaps</span><span class="p">:</span><span class="o">//</span><span class="n">username</span><span class="nv">@oldmailserver</span><span class="o">/</span><span class="n">INBOX</span><span class="o">/</span><span class="n">folder</span><span class="w"></span>
<span class="err">#</span><span class="w"> </span><span class="n">mark</span><span class="w"> </span><span class="ow">all</span><span class="w"> </span><span class="n">messages</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">folder</span><span class="w"> </span><span class="p">(</span><span class="n">otherwise</span><span class="w"> </span><span class="k">use</span><span class="w"> </span><span class="ss">"t"</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="k">select</span><span class="w"> </span><span class="n">single</span><span class="w"> </span><span class="n">messages</span><span class="p">)</span><span class="w"></span>
<span class="n">enter</span><span class="w"> </span><span class="ss">"T"</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="ss">"~A"</span><span class="w"> </span>
<span class="err">#</span><span class="w"> </span><span class="n">either</span><span class="w"> </span><span class="n">copy</span><span class="w"> </span><span class="p">(;</span><span class="n">C</span><span class="p">)</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">move</span><span class="w"> </span><span class="p">(;</span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">messages</span><span class="p">.</span><span class="w"> </span><span class="p">;</span><span class="n">s</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">mark</span><span class="w"> </span><span class="n">them</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">deleted</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="k">old</span><span class="w"> </span><span class="n">account</span><span class="err">!</span><span class="w"></span>
<span class="n">enter</span><span class="w"> </span><span class="ss">";C"</span><span class="w"></span>
<span class="err">#</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="nf">choose</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="n">gmail</span><span class="w"> </span><span class="nl">account</span><span class="p">:</span><span class="w"></span>
<span class="nl">imaps</span><span class="p">:</span><span class="o">//</span><span class="n">gmailusername</span><span class="nv">@imap</span><span class="p">.</span><span class="n">googlemail</span><span class="p">.</span><span class="n">com</span><span class="o">/[</span><span class="n">Gmail</span><span class="o">]/</span><span class="n">folder</span><span class="w"></span>
</code></pre></div>
<p>You may want to start mutt in a "screen" session and then let it run for a while. On linux systems mutt should already be installed. On OSX you can find it in homebrew.</p>Manually installing Boost 1.55 on OSX2014-10-19T00:00:00+02:002014-10-19T00:00:00+02:00flurintag:flurischt.ch,2014-10-19:/manually-installing-boost-155-on-osx.html<p>Boost 1.56.0 which is currently installed by homebrew is broken. Just try to compile the following C++ program. It will fail.</p>
<div class="highlight"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf"><boost/graph/adjacency_matrix.hpp></span><span class="cp"></span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Here are the steps to manually install Boost 1.55:</p>
<ul>
<li>Download Boost 1.55 <a href="http://sourceforge.net/projects/boost/files/boost/1.55.0/">here</a></li>
<li>Extract the source and <code>cd …</code></li></ul><p>Boost 1.56.0 which is currently installed by homebrew is broken. Just try to compile the following C++ program. It will fail.</p>
<div class="highlight"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf"><boost/graph/adjacency_matrix.hpp></span><span class="cp"></span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Here are the steps to manually install Boost 1.55:</p>
<ul>
<li>Download Boost 1.55 <a href="http://sourceforge.net/projects/boost/files/boost/1.55.0/">here</a></li>
<li>Extract the source and <code>cd</code> into the directory</li>
<li>Compile: <code>./bootstrap.sh && ./b2</code></li>
<li>Create a directory where Boost will be installed: <code>mkdir /usr/share/boost</code></li>
<li>Install: <code>./b2 install --prefix=/usr/share/boost/</code></li>
<li>Link the include files to /usr/local/include: <code>ln -s /usr/share/boost/include/boost /usr/local/include</code></li>
</ul>
<p>You might need administrator privileges for the last three steps.</p>Enable homebrew for non admin users2014-10-18T00:00:00+02:002014-10-18T00:00:00+02:00flurintag:flurischt.ch,2014-10-18:/enable-homebrew-for-non-admin-users.html<p>Even on OSX you should not be working with an admin account. Here are the steps to make <a href="http://brew.sh">homebrew</a> usable for non admin users.</p>
<h2>Assumptions</h2>
<p>I assume brew has already been installed by an administrator and it's login is admin. Change admin below to the name of your admin account …</p><p>Even on OSX you should not be working with an admin account. Here are the steps to make <a href="http://brew.sh">homebrew</a> usable for non admin users.</p>
<h2>Assumptions</h2>
<p>I assume brew has already been installed by an administrator and it's login is admin. Change admin below to the name of your admin account.</p>
<h2>Steps</h2>
<p>Under System Preferences create a new group "brew" and add your user to it. Then open the terminal and:</p>
<div class="highlight"><pre><span></span><code>su - admin
sudo chgrp -R brew /usr/local
sudo chgrp -R brew /Library/Caches/Homebrew
sudo chmod -R g+w /usr/local
sudo chmod -R g+w /Library/Caches/Homebrew
<span class="c1"># and if you plan to use caskroom too:</span>
sudo mkdir -p /opt/homebrew-cask/Caskroom
sudo chgrp -R brew /opt/homebrew-cask
sudo chmod -R g+w /opt/homebrew-cask
</code></pre></div>
<p>(this logs in as the admin user and allows the members of the "brew" group to write to /usr/local and the Caches directory)</p>
<p>With your user account you can now run <code>brew doctor</code> to check if everything is working as it should.</p>
<p>Credits: Visit <a href="http://blog.strug.de/2012/06/my-homebrew-multi-user-setup/">this</a> for some more detailed instructions.</p>OSX 10.10 (yosemite): configure: error: C compiler cannot create executables2014-10-18T00:00:00+02:002014-10-18T00:00:00+02:00flurintag:flurischt.ch,2014-10-18:/osx-1010-yosemite-configure-error-c-compiler-cannot-create-executables.html<p>Problem:
brew fails with "configure: error: C compiler cannot create executables" </p>
<div class="highlight"><pre><span></span><code>==> Upgrading 1 outdated package, with result:
python3 3.4.2_1
==> Upgrading python3
==> Downloading https://www.python.org/ftp/python/3.4.2/Python-3.4.2.tar.xz
Already downloaded: /Library/Caches/Homebrew/python3-3.4.2.tar.xz
==> ./configure --prefix …</code></pre></div><p>Problem:
brew fails with "configure: error: C compiler cannot create executables" </p>
<div class="highlight"><pre><span></span><code>==> Upgrading 1 outdated package, with result:
python3 3.4.2_1
==> Upgrading python3
==> Downloading https://www.python.org/ftp/python/3.4.2/Python-3.4.2.tar.xz
Already downloaded: /Library/Caches/Homebrew/python3-3.4.2.tar.xz
==> ./configure --prefix=/usr/local/Cellar/python3/3.4.2_1 --enable-ipv6 --datar
checking for gcc... clang
checking whether the C compiler works... no
configure: error: in /private/tmp/python3-av3R7L/Python-3.4.2:
configure: error: C compiler cannot create executables
See config.log for more details
</code></pre></div>
<p>Solution:
Download and install Xcode 6.1 and the Command line tools (CLT) for OSX 10.10. With the release of Yosemite Xcode 6.1 should show up in the App Store sooner or later. Then a manual download will be unnecessary. </p>Hello2014-07-17T00:00:00+02:002014-07-17T00:00:00+02:00flurintag:flurischt.ch,2014-07-17:/hello.html<p>Welcome to the new website. I've created the new page mainly as an excuse for not learning during the current exam preparations... So you should not expect any updates soon. There'll hopefully be some updated stuff here after the exam session in august. Have a nice summer and come back …</p><p>Welcome to the new website. I've created the new page mainly as an excuse for not learning during the current exam preparations... So you should not expect any updates soon. There'll hopefully be some updated stuff here after the exam session in august. Have a nice summer and come back later! ;-) </p>