Jekyll2018-12-15T08:15:14-08:00https://kevzettler.com/Kev ZettlerDasung Linux Driver Decompiled2018-12-13T00:00:00-08:002018-12-13T00:00:00-08:00https://kevzettler.com/2018/12/13/dasung-linux-driver-decompiled<p>This is a follow up to the <a href="https://kevzettler.com/2018/02/11/dasung-paperlike-pro-teardown">Dasung teardown</a> post in which I decompile the software drivers. Dasung ships their monitors with a Linux driver that is sadly limited to the Ubuntu amd64 architecture. The driver can be downloaded from:
<a href="http://www.dasungtech.com/sta/en/software_en0310.html">Dasung driver download page</a></p>
<p>I have decompiled the drivers and uploaded them to github at:
<a href="https://github.com/kevzettler/decompiled_dasung_drivers">Dasung linux drivers source code decompiled</a></p>
<p>I was naively hoping I could hack this to be ARM compatible so I could use the Dasung with a Raspberry PI. I have been told that is not feasible due to architecture differences and OS API compatibility concerns. However these Drivers can potentially be used to make mods for other AMD64 systems.</p>
<p>When looking at the ‘drivers’ provided by Dasung the contents of the Ubuntu folder are as follows:</p>
<div class="highlight"><pre><span></span>-rwxrwxrwx@ <span class="m">1</span> kev staff <span class="m">67646</span> Nov <span class="m">2</span> <span class="m">2017</span> DS.ico
-rwxrwxrwx@ <span class="m">1</span> kev staff <span class="m">29404</span> Nov <span class="m">2</span> <span class="m">2017</span> paperlikepro_1.0.5_amd64.deb
-rwxrwxrwx@ <span class="m">1</span> kev staff <span class="m">180</span> Nov <span class="m">2</span> <span class="m">2017</span> readme
</pre></div>
<ul>
<li><code>DS.ico</code>
<p>is an icon file of the Dasung logo</p>
</li>
<li><code>readme</code>
<p>is a text file explaining how to install the driver on Ubuntu systems</p>
</li>
<li><code>paperlikepro_1.0.5_amd64.deb</code>
<p>is a Debian package archive containing the compiled driver and other data. The <code>deb</code> file can be extracted to the following contents:</p>
</li>
</ul>
<h2>paperlikepro_1.0.5_amd64.deb contents</h2>
<div class="highlight"><pre><span></span>-rw-r--r--@ <span class="m">1</span> kev staff <span class="m">279</span> Aug <span class="m">4</span> <span class="m">2017</span> control.tar.gz
-rw-r--r--@ <span class="m">1</span> kev staff <span class="m">28932</span> Aug <span class="m">4</span> <span class="m">2017</span> data.tar.xz
-rw-r--r--@ <span class="m">1</span> kev staff <span class="m">4</span> Aug <span class="m">4</span> <span class="m">2017</span> debian-binary
</pre></div>
<ul>
<li><code>debian-binary</code>
is a text file that contains a version number
<code>$ cat debian-binary 2.0</code></li>
<li><code>control.tar.gz</code>
is an archive that can be extracted using <code>tar</code>
it expands to a text file <code>control</code> with the following content:</li>
</ul>
<div class="highlight"><pre><span></span>$ cat control
Package: PaperlikePro
Version: 1.0.5
Section: x11
Priority: standard
Architecture: amd64
Depends:
Installed-Size: 200
Maintainer: support@dasung.com
Description: Paperlike Pro Software
</pre></div>
<ul>
<li><code>data.tar.xz</code>
<p>This is where things get interesting. It is another tar archive which contains the executables of the driver. When extracted it produces the following:</p>
</li>
</ul>
<div class="highlight"><pre><span></span>$ tar -xzvf data.tar.xz
x ./
x ./usr/
x ./usr/local/
x ./usr/local/sbin/
x ./usr/local/sbin/PaperlikePro
x ./usr/local/sbin/DS.ico
x ./usr/local/sbin/ResChange
</pre></div>
<p>This is meant to be installed at <code>/usr/local/sbin</code> on Ubuntu. We have already seen <code>DS.ico</code> and know it is the Dasung logo.</p>
<p><code>PaperLikePro</code> and <code>ResChange</code> are both executables. I am assuming that <code>PaperlikePro</code> is the UI management tool found on other platforms and that <code>ResChange</code> is a resolution driving tool.</p>
<h1>Converting amd64 binaries to other format</h1>
<p>Using the <a href="https://github.com/yegord/snowman">Snowman decompiler</a> tool against <code>PaperlikePro</code> and <code>ResChange</code> binaries I was able to produce some C++ decompiled source code. I have not attempted to re compile them and see if they work as expected. I have uploaded the decompiled code to github at <a href="https://github.com/kevzettler/decompiled_dasung_drivers">https://github.com/kevzettler/decompiled_dasung_drivers</a>.</p>Dasung Paperlike Pro Teardown2018-02-11T00:00:00-08:002018-02-11T00:00:00-08:00https://kevzettler.com/2018/02/11/dasung-paperlike-pro-teardown<img src='/img/dasung_teardown/title.png'
alt='Dasung Paperlike Pro control board says. Oops, you have lost the warranty :-('
title='Dasung Paperlike Pro control board says. Oops, you have lost the warranty :-('
/>
<blockquote>
<p><b>Disclaimer</b> This is my first real electronics, hardware project. I’m picking this up as I go. I don’t yet have a mature mental model on electronics. I appreciate any guidance and coaching in the comments.</p>
</blockquote>
<h2>Building a DIY E-ink or Epaper laptop</h2>
<p>This is a follow up to my previous <a href="/2018/01/12/dasung-paperlike-pro-review">Dasung Paperlike Pro Review</a> post. For visitors landing here, a quick recap. The Dasung Paperlike Pro is billed as “The worlds first HDMI e-ink monitor” It is high performance for a e-ink display and renders at about 40fps. Check the review post for more info.</p>
<p>I Bought the Dasung with intentions to tear it down for ‘research’ purposes. Mainly to confirm what e-ink display module they were using. This research was for the goal of building an <a href="https://www.youtube.com/watch?v=4-cVNJwhAqo">e-ink laptop</a>. In this post I will walk through my experience dismantling the Dasung and discuss its internal components. Hopefully readers will find this useful in their own e-ink hardware projects, or in the chance they need to repair a Dasung.</p>
<p>You can click through any of the images below for full high res versions.</p>
<h2>How to open the Dasung Paperlike Pro</h2>
<p>The Dasung has a seemingly, solid one piece construction. It took me a few days to devise a method of disassembly that wasn’t aggressively destructive, like cracking the frame open with a hammer, or pry-bar. After prodding it for a few days I discovered the front outer frame bezel was glued on and could be pried with a knife.</p>
<a href='/img/dasung_teardown/2017-12-26 19.49.20.jpg'>
<img src='/img/dasung_teardown/2017-12-26 19.49.20.jpg' alt="How to remove Dasung Paperlike Pro faceplate" title="How to remove Dasung Paperlike Pro faceplate" />
</a>
<a href='/img/dasung_teardown/2017-12-26 19.49.39.jpg'>
<img src='/img/dasung_teardown/2017-12-26 19.49.39.jpg' alt="How to remove Dasung Paperlike Pro faceplate" title="How to remove Dasung Paperlike Pro faceplate" />
</a>
<a href='/img/dasung_teardown/2017-12-26 19.52.19.jpg' >
<img src='/img/dasung_teardown/2017-12-26 19.52.19.jpg' title="How to dissasemble Dasung Paperlike Pro" alt="How to dissasemble Dasung Paperlike Pro" />
</a>
<a href='/img/dasung_teardown/2017-12-26 19.54.26.jpg'>
<img src='/img/dasung_teardown/2017-12-26 19.54.26.jpg' alt="How to unscrew Dasung Paperlike Pro" title="How to unscrew Dasung Paperlike Pro dissasembly" />
</a>
<h2>The Dasung E-ink display module</h2>
<p>My main objective in purchasing the Dasung, was to confirm what e-ink display module was in use. I had suspected it was the <a href="http://shopkits.eink.com/product/13-3%CB%9D-epaper-display-ed133ut2/">13.3˝ ePaper Display (ED133UT2)</a> However other notes from Dasung about a “Carta” version change lead me to doubt that. One of my biggest complaints in my <a href="2018/01/12/dasung-paperlike-pro-review">Dasung Paperlike Pro Review</a> post, was that the monitor display was reflective and has an aggressive glare.</p>
<a href='/img/dasung_teardown/2017-12-26 19.56.24.jpg'>
<img src='/img/dasung_teardown/2017-12-26 19.56.24.jpg' alt="" title="" />
</a>
<h3>Detaching the E-ink display module</h3>
<p>This step was sensitive. The Display module is attached by a fragile ribbon cable to a latch bracket. This is called a ZIF (Zero Insertion Force) connector. It took me a bit to track down how to open it. You Lift the black latch off and can remove the ribbon cable.</p>
<a href='/img/dasung_teardown/2017-12-26 20.28.23.jpg'>
<img src='/img/dasung_teardown/2017-12-26 20.28.23.jpg' alt="How to open ZIF (Zero Insertion Force) connector" title="How to open ZIF (Zero Insertion Force) connector" />
</a>
<a href='/img/dasung_teardown/2017-12-26 21.21.55.jpg'>
<img src='/img/dasung_teardown/2017-12-26 21.21.55.jpg' alt="" title="" />
</a>
<h3>Reviewing the E-ink Epaper display module</h3>
<p>On inspection of the E-ink display module I was disappointed to find that the glass was actually part of the module and not a separate pane like I first expected and hoped.</p>
<a href='/img/dasung_teardown/2018-02-07 19.31.52.jpg'>
<img src='/img/dasung_teardown/2018-02-07 19.31.52.jpg' alt="Broken glass on dasung e-ink display module" title="borken glass on dasung e-ink module" />
</a>
<a href='/img/dasung_teardown/2018-02-07 19.30.16.jpg'>
<img src='/img/dasung_teardown/2018-02-07 19.30.16.jpg' alt="e-ink module identification" title="e-ink module identification" />
</a>
<p>The tag on the display module has a model number <b>ED133UT2</b> that confirms my suspicious of it being the <a href="http://shopkits.eink.com/product/13-3%CB%9D-epaper-display-ed133ut2/">e-ink 13.3 ed133ut2</a>. This is unfortunate as it appears that E-ink offers another module the <b>ES133UT2</b> model. Note that the difference between the model numbers is the <b>S</b> and <b>D</b>. The <b>S</b> model is marketed as “Flexible” and has sales points of:</p>
<ul>
<li>Antiglare hard-coated front-surface</li>
<li>Plastic substrate</li>
</ul>
<p>It is hugely disappointing that Dasung went with the <b>D</b> model as I suspect the <b>S</b> model would be an <a href="http://shopkits.eink.com/product/13-3%CB%9D-epaper-display-es133ut2/">anti-glare e-ink display module</a> solving a major problem with the Dasung. I could almost see a mistake being made during production ordering because of the very close model identifiers.</p>
<p>On further exploration of these model numbers I found a <a href="http://www.panelook.com/product_cat.php?catid=73&pl=photo&st=&tag=74&panel_size_inch=1330">PaneLook.com a whole sale display panel site</a> which lists other 13.3 e paper, display models:</p>
<ul>
<li><b>EN133UT1</b></li>
<li><b>ES133UT1</b></li>
<li><b>ED133UT1</b></li>
<li><b>ED133TT1</b></li>
<li><b>ES133TT2</b></li>
<li><b>ES133TE1</b></li>
<li><b>ED133UT2</b></li>
<li><b>ES133TT3</b></li>
</ul>
<p>Panelook curiously does not have a listing for <b>ES133UT2</b></p>
<p>A <a href="http://www.panelook.com/modelcompare.php?ids=25596,25552,25553,27057,27058,27059,31868,31869">comparison of 13.3 epaper displays</a> on PaneLook shows some interesting details about the available options.</p>
<ul>
<li>The <b>ES133TE1</b> has embbed touch screen capabilities.</li>
<li><b>EN133UT1</b> and <b>ES133TT3</b> are the only models listed with ‘Antiglare’</li>
</ul>
<p>After comparing these options it looks as if <b>ES133TT3</b> would be the best Epaper laptop display from these options.</p>
<h2>The Control Board</h2>
<p>When I first saw this control board I was shocked at how large it is and how many components are packed into it. I had assumed that most of the proprietary Dasung functionality was handled in software.</p>
<a href='/img/dasung_teardown/2017-12-26 21.33.30.jpg' >
<img src='/img/dasung_teardown/2017-12-26 21.33.30.jpg' alt="Dasung Paperlike control board" title="Dasung Paperlike Pro control board" />
</a>
<p>On closer inspection all the chip components have had their labels chemically peeled off to prevernt reverse engineering.</p>
<h3>Two PCBs ?</h3>
<p>There are actually two PCBs. A smaller PCB towards the top of the enclosure is a USB port with an IC and wires hooked to the main board.</p>
<a href='/img/dasung_teardown/2017-12-26 20.22.38.jpg' >
<img src='/img/dasung_teardown/2017-12-26 20.22.38.jpg' alt="Dasung Paperlike control board" title="Dasung Paperlike Pro control board" />
</a>
<p>The Dasung manual claims that this USB port is intended to be used as an interface for a USB external lamp. Then elsewhere, on the included accessories section of a ‘quick start’ sheet, it says:</p>
<ul>
<li>A USB to USB cable for firmware upgrade in some emergency (non standard).</li>
</ul>
<p>This implies that the USB interface can used for firmware updates. I suspect with some further hacking this could be used to load custom firmware or maybe dump the existing firmware of the board.</p>
<p>There are only two input ports to the device. The USB on top, and the mini HDMI in the bottom left.</p>
<h1>Dasung Paperlike Pro control board components</h1>
<p>I am way too junior in electronics to accurately identify the components of the board. I leave this as an exercise for any readers, and a learning challenge for myself. I will pursue this in future work.</p>
<p>I reached out to some 3rd party help and the best lead I got was:</p>
<blockquote>
<p>from top to bottom…
some kind of IO breakout, maybe an MCU for platform management, might actually be running the whole show and below is just a display controller
main SoC, probably contains display driver they’re using for just the internal screen
the two little ones are DRAM
an FPGA, used as glue logic and DMA buffer for both displays
highly integrated hdmi controller, handles the full spec + audio and just clocks in a frame</p>
<p>the collection of shit in the white boxes are various power regulators for the display etc, on the far top left you have a power management controller and support circuitry, handles just about all the IC and IO voltages by the looks.</p>
</blockquote>
<p>Looking forward to further discussion in the comments.</p>
<h1>Updates</h1>
<h2>2018/02/14</h2>
<p>User thomasjfox on <a href="https://hackaday.com/2018/02/14/tearing-down-a-1000-e-ink-display/#comment-4362437">hackaday comments</a> suggests:</p>
<blockquote>
<p>On the bottom left is a HDMI signal decoder that feeds directly into a FPGA with RAM chips next to it.
The FPGA is connected to the eink controller on the right. I couldn’t make out the largish chip above the eink controller.
Wild guess: A MCU to configure the HDMI signal decoder + eink controller.</p>
</blockquote>Dasung Paperlike Pro(grammer) Review2018-01-12T00:00:00-08:002018-01-12T00:00:00-08:00https://kevzettler.com/2018/01/12/dasung-paperlike-pro-review<p>I recently purchased a <a href="http://www.dasung.com/english/">Dasung Paperlike Pro 13.3 E-ink monitor</a> to use for coding, reading, and terminal work. I have many thoughts on the overall e-ink market and consumer experience. I will save them for another post. This post will be brief and focused on personal expectations with the Dasung. Additionally, there are <a href="https://www.youtube.com/results?search_query=dasung+paperlike+pro">many other, more thorough reviews</a> online demonstrating the capabilities of the monitor.</p>
<p>After telling people I purchased this monitor the common reaction is:</p>
<blockquote>
<p>“E-ink? Isn’t that slow!? How do you code on that?” - Tech Friend</p>
</blockquote>
<p>This is an understandable concern as most people’s personal experience with E-ink has been on smaller low powered devices like Kindles or other E-readers. The smaller e-reader screens tend to have an extended ‘refresh’ rate built in. This is an attempt to conserve battery power.</p>
<p>The Dasung doesn’t have to make this compromise; it has a dedicated power source. The Dasung monitor performance runs at about 40 FPS on HDMI hookup. This thing can play videos.</p>
<h2>Coding in Emacs on a Dasung Paperlike Pro 13.3 E-ink monitor</h2>
<p>Below is a video I sent to a few friends demonstrating the responsiveness and performance</p>
<p>e-ink emacs video:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/zp8-eUmAnhg" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<h2>The pros</h2>
<ul>
<li>The overall physical design and form factor of the monitor is great.
<p>The monitor has a solid one-piece construction. As a bonus, it comes with a stand. HDMI hookup</p>
</li>
<li>Works excellent for Emacs.
<p>Can be a dedicated Emacs monitor.</p>
</li>
<li>Dasung support was fast, friendly and shipping was quick.</li>
</ul>
<h3>Dasung driver and software performance</h3>
<p>Dasung packages software to help drive and configure the monitor on popular operating systems: Windows, OSX, and 64bit Ubuntu. I primarily used the monitor on an OSX system.</p>
<p>The Monitor has three primary rendering modes: <b>Floyd</b>, <b>A2</b>, <b>A16</b>. I find myself spending most of the time in the <b>A2</b> mode. The different modes correspond to different algorithms that the monitor uses to convert the colored display pixel data into grey-scale e-ink data. The numbers in the <b>A2</b> and <b>A16</b> modes are the different shades of grey each pixel will render. The <b>A2</b> mode is a hard binary contrast containing only 2 colors, black and white. I found this great for text editing and reading.</p>
<p>The <b>A16</b> mode maps color pixels into one of 16 shades of grey. This mode is useful for viewing operating system UI and Apps that don’t render well in a black and white mode.</p>
<p>The <b>Floyd</b> mode is apparently a proprietary custom Dasung algorithm that is based on <del><a href="https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm">The Floyd-Warshall algorithim</a></del> <a href="https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering">Floyd–Steinberg dithering algorithim</a>. Overall the <b>Floyd</b> mode renders multi shade grey output at a high frame rate. You can watch videos in this mode. Wikipedia states that:</p>
<blockquote>
<p><del>the Floyd–Warshall algorithm is an algorithm for finding shortest paths in a weighted graph with positive or negative edge weights (but with no negative cycles).</del></p>
</blockquote>
<p>I am not sure how Dasung applies that graph pathfinding algorithm to the pixel data of the display output. I haven’t thought too hard about this yet, I would appreciate any ideas left in the comments below.</p>
<h2>The cons</h2>
<h3>Reflective screen glare</h3>
<p>As you can see in the video above, there is an obvious glare on the screen. The video was captured in a moderately lit room. The monitor actually ships with a plastic anti-glare protective screen cover to help alleviate this. This is a huge problem and defeats the purpose of the monitor. Dasung’s advertising is aggressive on claims of “Relax Your Eyes”, “Ultimate Eye Protection” “No blue light, No flashing, No backlight, No glossy”.</p>
<p>Unfortunately, putting a reflective pane of glass over the e-ink display is a bad move.</p>
<h3>Dasung driver and software issues</h3>
<p>I listed the Dasung software as a Pro, unfortunately, it also has some frustrating issues. Again my experience was on MacOSX; your experience may be different.</p>
<p>The monitor has a “change mode” hardware button that lets you cycle through these differnt modes. There is a software driver UI that also changes these modes. It seems the software can get out of sync with the hardware. You can set a resolution and contrast and mode in the software, Then press a hardware button and that resolution will be lost.</p>
<p>At times the monitor goes in to some kind of “sleep mode” even while plugged into an active computer. The screen goes black and unresponsive. By messing with a combination of the hardware buttons on the screen you can wake it up.</p>
<p>Unfortunatly, the driver UI defaults to Chinese, I was able to navigate it blindly and change to English. It should detect the operating system’s language setting.</p>
<h1>Summary</h1>
<p>Overall I think the Dasung is a pretty awesome piece of equipment. I am majorly dissapointed about the reflective glass screen. I am happy with my purchase and hope funds go to help further improve the company and product line. If you spend a lot of time editing text or reading with tired eyes I would recommend one. You can use it as a dedicated text editor or terminal screen to great success.</p>
<h1>Updates</h1>
<h2>2018/02/02:</h2>
<p><a href="https://kevzettler.com/2018/01/12/dasung-paperlike-pro-review#comment-3754833721">Jon Hendry</a> in the comments pointed out that the Dasung PaperlikePro Floyd mode is probably the <a href="https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering">Floyd–Steinberg dithering algorithim</a> and not the Floyd-Warshall I pointed out above. This makes much more sense I have updated the content above</p>Rapid Local Development with Vagrant, Docker and Node.js2015-06-07T00:00:00-07:002015-06-07T00:00:00-07:00https://kevzettler.com/programming/2015/06/07/rapid_local_development_vagrant_docker_node<h3 id="tldr">TLDR</h3>
<ul>
<li>Using a cascade of Vagrant shared directories, Docker volumes and cleverly placed symlinks, you can rig Vagrant and Docker to instantly reflect your local application code updates.</li>
<li>Docker volume -> Vagrant shared directory -> Host machine code.</li>
<li>Enable NPM link style development in Docker container.</li>
<li>Dosen’t cover <code class="highlighter-rouge">gulp</code> <code class="highlighter-rouge">webpack</code> asset generation but you can figure it out.</li>
<li>There might be a better way to do this or improvements to make. Leave it in the comments.</li>
</ul>
<h2 id="the-problem">The Problem</h2>
<p>I wanted to use <a href="https://github.com/js-platform/node-webrtc">isomorphic WebRTC</a> with the awesome <a href="https://github.com/feross/simple-peer">SimplePeer</a> in a recent Node.js project. However the server WebRTC has a bunch of system level dependencies that are a pain to install. Luckily they provide a <a href="https://github.com/js-platform/node-webrtc/blob/develop/Dockerfile">Dockerfile</a> which does it all for you. I didn’t end up using their exact Dockerfile but copy pasted the majority of it to my project to use as a <code class="highlighter-rouge">Base web</code> Dockerfile.</p>
<p>I also wanted to do development on a custom Node module. Usually on your local machine you would do <code class="highlighter-rouge">npm link</code> which creates a symlink to your module’s code directory and you can rapidly iterate there. However, working with Vagrant and Docker makes this more complicated.</p>
<p>I wanted all this to work without having to rebuild Docker images, rerun docker containers, or reprovision Vagrant.</p>
<h2 id="the-base-web-image">The Base Web Image</h2>
<figure class="highlight"><pre><code class="language-docker" data-lang="docker"><span class="c"># baseweb Dockerfile</span>
<span class="k">FROM</span><span class="s"> ubuntu:14.04</span>
<span class="k">ENV</span><span class="s"> DEBIAN_FRONTEND noninteractive</span>
<span class="k">RUN </span><span class="nb">echo </span>debconf shared/accepted-oracle-license-v1-1 <span class="k">select </span><span class="nb">true</span> | debconf-set-selections
<span class="k">RUN </span><span class="nb">echo </span>debconf shared/accepted-oracle-license-v1-1 seen <span class="nb">true</span> | debconf-set-selections
<span class="k">RUN </span>apt-get update <span class="o">&&</span> apt-get <span class="nb">install</span> <span class="nt">-y</span> software-properties-common
<span class="k">RUN </span>add-apt-repository ppa:webupd8team/java <span class="o">&&</span> add-apt-repository ppa:chris-lea/node.js <span class="o">&&</span> apt-get update
<span class="k">RUN </span>apt-get <span class="nb">install</span> <span class="nt">-y</span> git subversion g++ python libnss3-dev libasound2-dev libpulse-dev <span class="se">\
</span>libjpeg62-dev libxv-dev libgtk2.0-dev libexpat1-dev libxss-dev libudev-dev libdrm-dev libgconf2-dev <span class="se">\
</span>libgcrypt11-dev libpci-dev libxtst-dev libgnome-keyring-dev libssl-dev nodejs oracle-java6-installer oracle-java6-set-default
<span class="k">ENV</span><span class="s"> JAVA_HOME /usr/lib/jvm/java-6-oracle/</span>
<span class="k">ENV</span><span class="s"> PATH $PATH:/usr/lib/jvm/java-6-oracle/jre/bin/</span>
<span class="k">RUN </span>npm <span class="nb">install</span> <span class="nt">-g</span> forever</code></pre></figure>
<p>With the <code class="highlighter-rouge">BaseWeb</code> Dockerfile inplace I then have my Nodejs application. It’s structured as follows.</p>
<h2 id="the-web-application-code">The Web Application Code</h2>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">/Projects/demo/web
├── Dockerfile
├── index.js
├── node_modules -> /dist/node_modules/
└── package.json</code></pre></figure>
<p>Take note here that my <code class="highlighter-rouge">node_modules</code> is actually a symlink to <code class="highlighter-rouge">/dist/node_modules/</code> this is committed to my repo. This may seem odd but it’s key to letting us rapidly develop on a custom module. It enables a <code class="highlighter-rouge">npm link</code> style work flow.</p>
<h3 id="the-vagrant-setup">The Vagrant Setup</h3>
<p>Assume we have a Vagrantfile outside of our web project like so:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">/Projects/demo/
├── Vagrantfile
└── web</code></pre></figure>
<p>This will automatically mount the web code as a shared directory inside the Vagrant machine at <code class="highlighter-rouge">/vagrant/web</code>. At this point we can <code class="highlighter-rouge">vagrant up</code> and edit the application code on the host machine as usual and Vagrant will pickup the changes. This dosen’t help us yet because the code is dependent on the ismorphic WebRTC dependences. We need Vagrant to run the Docker containers.</p>
<p>Before we get to the <code class="highlighter-rouge">Vagrantfile</code> let’s look at the Web Applications’ Dockerfile.</p>
<h2 id="the-web-application-dockerfile">The Web Application Dockerfile</h2>
<figure class="highlight"><pre><code class="language-dockerfile" data-lang="dockerfile"><span class="c"># web DockerFile</span>
<span class="k">FROM</span><span class="s"> base_web</span>
<span class="k">COPY</span><span class="s"> package.json /dist/package.json</span>
<span class="k">RUN </span><span class="nb">mkdir</span> /dist/node_modules <span class="o">&&</span> <span class="nb">cd</span> /dist <span class="o">&&</span> npm <span class="nb">install</span>
<span class="k">ADD</span><span class="s"> . /srv/www</span>
<span class="k">RUN </span><span class="nb">ln</span> <span class="nt">-s</span> /dist/node_modules /srv/www/node_modules
<span class="k">WORKDIR</span><span class="s"> /srv/www</span>
<span class="k">EXPOSE</span><span class="s"> 5000</span>
<span class="k">CMD</span><span class="s"> ["forever", "index.js"]</span></code></pre></figure>
<h4 id="points-of-interest">Points Of Interest</h4>
<ul>
<li>
<p>The key to this whole thing here is the <code class="highlighter-rouge">node_modules</code> setup. We don’t do the <code class="highlighter-rouge">npm install</code> in the application code directory. We create a <code class="highlighter-rouge">/dist/</code> directory and copy <code class="highlighter-rouge">package.json</code> there. We then <code class="highlighter-rouge">npm install</code> in <code class="highlighter-rouge">/dist</code> and get <code class="highlighter-rouge">/dist/node_modules</code>. This is really the seceret sauce. In production you don’t rebuild your modules each time you re-build your container. If your <code class="highlighter-rouge">package.json</code> file changes then your modules will be rebuilt. I got this from <a href="http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/">Building Efficient Dockerfiles</a></p>
</li>
<li>
<p><code class="highlighter-rouge">RUN ln -s /dist/node_modules /srv/www/node_modules</code></p>
<p>This creates a symlink for <code class="highlighter-rouge">node_modues</code> from our application code at <code class="highlighter-rouge">/srv/www</code>. to our <code class="highlighter-rouge">/dist</code>. This also overrides the symlink that is committed in the web repo. You might be thinking, “well what was the point of that then?”. I promise we’ll get to that soon. It’s key to the <code class="highlighter-rouge">npm link</code> style.</p>
</li>
</ul>
<h3 id="the-vagrant-file">The Vagrant File</h3>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="no">Vagrant</span><span class="p">.</span><span class="nf">configure</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">config</span><span class="p">.</span><span class="nf">vm</span><span class="p">.</span><span class="nf">box</span> <span class="o">=</span> <span class="s2">"Ubuntu 14.04 with Docker enabled"</span>
<span class="n">config</span><span class="p">.</span><span class="nf">vm</span><span class="p">.</span><span class="nf">box_url</span> <span class="o">=</span> <span class="s2">"https://github.com/jose-lpa/packer-ubuntu_14.04/releases/download/v2.0/ubuntu-14.04.box"</span>
<span class="n">config</span><span class="p">.</span><span class="nf">vm</span><span class="p">.</span><span class="nf">provision</span> <span class="s2">"docker"</span> <span class="k">do</span> <span class="o">|</span><span class="n">d</span><span class="o">|</span>
<span class="n">d</span><span class="p">.</span><span class="nf">build_image</span> <span class="s2">"/vagrant/Dockerfiles/base_web"</span><span class="p">,</span> <span class="ss">args: </span><span class="s1">'-t "base_web"'</span>
<span class="n">d</span><span class="p">.</span><span class="nf">build_image</span> <span class="s2">"/vagrant/web"</span><span class="p">,</span> <span class="ss">args: </span><span class="s1">'-t "web"'</span>
<span class="n">d</span><span class="p">.</span><span class="nf">run</span> <span class="s2">"web"</span><span class="p">,</span>
<span class="ss">cmd: </span><span class="s2">"forever -w bin/server.js"</span><span class="p">,</span>
<span class="ss">args: </span><span class="s2">"-v '/vagrant/web:/srv/www'\
-e NODE_ENV=development\
-p 5000:5000"</span>
<span class="k">end</span>
<span class="n">config</span><span class="p">.</span><span class="nf">vm</span><span class="p">.</span><span class="nf">network</span> <span class="s2">"forwarded_port"</span><span class="p">,</span> <span class="ss">guest: </span><span class="mi">5000</span><span class="p">,</span> <span class="ss">host: </span><span class="mi">5000</span>
<span class="k">end</span></code></pre></figure>
<h4 id="points-of-interest-1">Points of interest</h4>
<ul>
<li>We use a ‘Docker enabled’ image for our Docker box.</li>
<li>We use Vagrant’s built-in Docker provisioner.</li>
<li>We then run our container with some new arguments.</li>
</ul>
<p>Let’s look at the run command more in-depth.</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="n">d</span><span class="p">.</span><span class="nf">run</span> <span class="s2">"web"</span><span class="p">,</span>
<span class="ss">cmd: </span><span class="s2">"forever -w index.js"</span><span class="p">,</span>
<span class="ss">args: </span><span class="s2">"-v '/vagrant/web:/srv/www'\
-e NODE_ENV=development\
-p 5000:5000"</span>
</code></pre></figure>
<p>We’re overriding the Dockerfiles’ <code class="highlighter-rouge">CMD ["forever", "index.js"]</code> with <code class="highlighter-rouge">forever -w index.js</code> The <code class="highlighter-rouge">-w</code> flag restarts our server on code updates, which is what we want in a development environment.</p>
<h3 id="bringing-it-all-together">Bringing It All Together</h3>
<p>The Most important part of the <code class="highlighter-rouge">docker run</code> options is the <code class="highlighter-rouge">-v</code> flag, which is for Docker Volumes. We are telling our container to mount <code class="highlighter-rouge">/srv/www</code> as a volume that points to <code class="highlighter-rouge">/vagrant/web/</code>. If you review our Vagrant setup from earlier you can see that <code class="highlighter-rouge">/srv/www</code> is actualy a shared directory to our application code directory <code class="highlighter-rouge">/web</code> on the host machine!</p>
<p>A quick diagram of this shared filesystem cascade looks like this:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">Docker <span class="sb">`</span>/srv/www<span class="sb">`</span> ->
Vagrant <span class="sb">`</span>/vagrant/web ->
Host <span class="sb">`</span>/web<span class="sb">`</span>/</code></pre></figure>
<p>At this point you’re set up to rapidly develop on your application code and have updates reflected in your Docker container.</p>
<p>The next challenge I faced was figuring out how to handle a local NPM module dependency that I wanted to iterate on in the same rapid manner.</p>
<h2 id="npm-link-development-in-a-docker-container">NPM Link Development In A Docker Container</h2>
<p>So in this scenario. Lets assume that <code class="highlighter-rouge">web</code> has an entry in <code class="highlighter-rouge">package.json</code> like this:</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="w"> </span><span class="s2">"dependencies"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"customModule"</span><span class="p">:</span><span class="w"> </span><span class="s2">"git://github.com/kevzettler/customModule"</span><span class="p">,</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<p><code class="highlighter-rouge">customModule</code> is a NPM module that we maintain and develop. This package.json setup works fine for production because we just install from the repo and forget about it. In development we want to rapidly make changes to <code class="highlighter-rouge">customModule</code>and not have to rebuild everything. Normally when developing on local machine, we would <code class="highlighter-rouge">cd</code> into <code class="highlighter-rouge">web</code> and do <code class="highlighter-rouge">npm link customModule</code> which would build a symlink to our <code class="highlighter-rouge">customModule</code> code that would give us a rapid development setup.</p>
<p>When we add Vagrant and Docker to the dev environment, this completly breaks NPM Link.</p>
<p>Here’s an updated directory diagram of our project with the new <code class="highlighter-rouge">customModule</code> code:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">/Projects/demo/
├── Vagrantfile
├── web
└── customModule</code></pre></figure>
<p>So similliar to the web code, Vagrant will mount our customModule code at <code class="highlighter-rouge">/vagrant/customModule</code></p>
<p>We can then update our VagrantFile to add a new Docker Volume:
<code class="highlighter-rouge">-v '/vagrant/engine:/dist/node_modules/engine'</code></p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="n">d</span><span class="p">.</span><span class="nf">run</span> <span class="s2">"web"</span><span class="p">,</span>
<span class="ss">cmd: </span><span class="s2">"forever -w index.js"</span><span class="p">,</span>
<span class="ss">args: </span><span class="s2">"-v '/vagrant/web:/srv/www'\
-v '/vagrant/customModule:/dist/node_modules/customModule'\
-e NODE_ENV=development\
-p 5000:5000"</span>
</code></pre></figure>
<h3 id="whats-all-this-symlink-business-then">What’s All This Symlink Business Then?</h3>
<p>So we have this symlink in 2 places.</p>
<ul>
<li>
<p>The <code class="highlighter-rouge">RUN</code> symlink in Web Dockerfile
<code class="highlighter-rouge">RUN ln -s /dist/node_modules /srv/www/node_modules</code></p>
</li>
<li>
<p>In ‘Filesystem’ symlink
<code class="highlighter-rouge">node_modules -> /dist/node_modules/</code></p>
</li>
</ul>
<p>Docker does not support symlinks when using the <code class="highlighter-rouge">ADD</code> command in a DockerFile.
It will drop them from the <code class="highlighter-rouge">ADD</code> filesystem. That’s why we need the <code class="highlighter-rouge">RUN</code> symlink in the dockerfile.</p>
<p>When we want to do development work, we run the container with the <code class="highlighter-rouge">-v</code> flag to mount our local code. The volume doesn’t get attached until after our container has already been created. At that time, the <code class="highlighter-rouge">RUN</code> symlink exists; however, the <code class="highlighter-rouge">-v</code> option overrides everything in the container’s <code class="highlighter-rouge">/srv/www/</code>, wiping out the <code class="highlighter-rouge">RUN</code> symlink.</p>
<p>But wait! We have a ‘Filesystem’ symlink in our shared code. The volume respects this symlink and it routes internally to the container’s filesystem. You don’t necessarily have to commit the symlink to your repo like I was dong. You just need it around when you build the Docker image. I committed it because I kept forgetting. Try this out and let me know if you have a better solution to it.</p>
<p>Thanks to <a href="http://gabriellenicolet.com/">Gabrielle Nicolet</a> for editing this post.</p>TLDR Using a cascade of Vagrant shared directories, Docker volumes and cleverly placed symlinks, you can rig Vagrant and Docker to instantly reflect your local application code updates. Docker volume -> Vagrant shared directory -> Host machine code. Enable NPM link style development in Docker container. Dosen’t cover gulp webpack asset generation but you can figure it out. There might be a better way to do this or improvements to make. Leave it in the comments.How To Route Docker.io Containers To Public IPV6 on Linode2014-06-25T00:00:00-07:002014-06-25T00:00:00-07:00https://kevzettler.com/programming/2014/06/25/docker_ipv6_linode<ul>
<li>If you want to us ipv6 with docker.io on linode make sure you have the following <code class="highlighter-rouge">sysctl</code> set
<ul>
<li><code class="highlighter-rouge">net.ipv6.conf.all.accept_ra = 2</code></li>
<li><code class="highlighter-rouge">net.ipv6.conf.all.forwarding = 1</code></li>
</ul>
</li>
<li>Then you can pretty much follow this post <a href="http://zargony.com/2013/10/13/ipv6-in-docker-containers#sthash.xNFG3NCx.dpuf">http://zargony.com/2013/10/13/ipv6-in-docker-containers</a></li>
<li>If you want auto configured addresses you can install and configure <code class="highlighter-rouge">radvd</code></li>
</ul>If you want to us ipv6 with docker.io on linode make sure you have the following sysctl set net.ipv6.conf.all.accept_ra = 2 net.ipv6.conf.all.forwarding = 1 Then you can pretty much follow this post http://zargony.com/2013/10/13/ipv6-in-docker-containers If you want auto configured addresses you can install and configure radvdDisable Any Element With jQuery2012-07-05T00:00:00-07:002012-07-05T00:00:00-07:00https://kevzettler.com/code/2012/07/05/Disable_any_element_with_jquery<p>In HTML the <a href="http://www.w3schools.com/tags/att_input_disabled.asp">disabled attribute</a> alows you to mark an input element as ‘disabled’ Which will trigger
the browser to render the input in a ‘greyed out’ style:</p>
<table style="padding:20px;">
<tr>
<td>
<form>
<p>Enabled elements</p>
<button>Click</button><br /><br />
<input type="text" value="text" /><br />
<select><br />
<option>Select</option>
</select>
</form>
</td>
<td>
<form style="padding-left:40px;">
<p>Disabled elements</p>
<button disabled="disabled">Click</button><br /><br />
<input type="text" disabled="disabled" value="text" /><br />
<select disabled="disabled"><br />
<option>Select</option>
</select>
</form>
</td>
</tr>
</table>
<p>This is helpful for limiting user interaction when an app is in an unknown state. Like waiting for an Ajax response. However this attribute is only available on form input elements.
This is unfortunate if you are heavily using your own custom UI components. Say you have a bunch of buttons throughout your UI that are actually <code class="highlighter-rouge"><a></code> elements.</p>
<p>I’ve ran into this problem on several projects and developed a pattern which grew into a plugin I now use on most projects. You can get the plugin here <a href="https://github.com/kevzettler/jquery.disable/downloads">download jquery.disable</a>
or check it out and contribute to <a href="https://github.com/kevzettler/jquery.disable">jquery.disable on github</a></p>In HTML the disabled attribute alows you to mark an input element as ‘disabled’ Which will trigger the browser to render the input in a ‘greyed out’ style:jQuery Autobox Plugin2010-10-30T00:00:00-07:002010-10-30T00:00:00-07:00https://kevzettler.com/2010/10/30/jquery-autobox-plugin<p>I have worked on several site designs that expect form inputs to render with a default value. Upon focus of the input the default text should clear and allow user input to stick. Sometimes the design calls for this to happen with a password field as well.</p>
<p>Password fields are a special condition as the text is rendered as dots. You cannot dynamically change the ‘type’ attribute of a password input field. This is a browser security feature. To obtain this behavior with password fields you need to dynamically create a text field on top of the password and hide it on focus. This plugin handles this.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code> "You cannot dynamically change the 'type' attribute of a password input field."
</code></pre></div></div>
<p>Handle any font colors or styling with css.</p>
<p>Downloads</p>
<p><a href="https://github.com/kevzettler/jquery.autobox/tarball/master">download - tar.gz</a></p>
<p><a href="https://github.com/kevzettler/jquery.autobox/zipball/master">download - .zip</a></p>
<p>Installation</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="jquery.autobox.js" type="text/javascript"></script>
<script type="text/javascript"></script>
<form> <input value="default text" type="text" /> <input value="default pass" type="pass" /> </form>
</code></pre></div></div>
<p>Demo
See it live <a href="http://www.callmekev.com/demo">here</a></p>I have worked on several site designs that expect form inputs to render with a default value. Upon focus of the input the default text should clear and allow user input to stick. Sometimes the design calls for this to happen with a password field as well.IE Button Bug2010-09-05T00:00:00-07:002010-09-05T00:00:00-07:00https://kevzettler.com/2010/09/05/IE-button-bug<p>I recently encountered an annoying bug in multiple versions of IE regarding forms and button elements. I am writing about it to remind myself in the future and to hopefully save time for someone else. The bug spawned from my decision to use <code class="highlighter-rouge"><button></code> elements over <code class="highlighter-rouge"><input type="submit"></code> elements as the submit buttons for my forms. I chose button elements because they are generally more consistent in cross browser rendering and also allow for more semantic textual content than text in the input element’s type attribute.
The behavior of modern browsers matched my own expected behavior. That is:</p>
<p>if a from element contains a button element, and no input <code class="highlighter-rouge">type='submit'</code>, that button should trigger the submit event of the form</p>
<p>However, IE does not.</p>
<p>“IE will not fire a form submit event on a <code class="highlighter-rouge"><button></button></code> click by default.”</p>
<p>I found this out after testing in IE and discovering that none of the forms on a site would submit. I first assumed that it was some bug with an inline validation plugin that I had used. The submission bug remained after disabling the plugin.</p>
<p>Solutions to this bug were:</p>
<p>Replace all the button elements with input <code class="highlighter-rouge">type='submit'</code> and apply the button styles.
Or attach an explicit click event to the button elements that would fire the parent form elements submit event.</p>I recently encountered an annoying bug in multiple versions of IE regarding forms and button elements. I am writing about it to remind myself in the future and to hopefully save time for someone else. The bug spawned from my decision to use <button> elements over <input type="submit"> elements as the submit buttons for my forms. I chose button elements because they are generally more consistent in cross browser rendering and also allow for more semantic textual content than text in the input element’s type attribute. The behavior of modern browsers matched my own expected behavior. That is: