<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Lee Packham - Medium]]></title>
        <description><![CDATA[Posts of an AWS Solutions Architect (posts are my own, not AWS’) - Medium]]></description>
        <link>https://blog.leepackham.com?source=rss----18bbcd357609---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Lee Packham - Medium</title>
            <link>https://blog.leepackham.com?source=rss----18bbcd357609---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 06 Mar 2024 19:23:49 GMT</lastBuildDate>
        <atom:link href="https://blog.leepackham.com/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[D3D Screenshots With Anti-Aliasing… Quickly]]></title>
            <link>https://blog.leepackham.com/d3d-screenshots-with-anti-aliasing-quickly-554173a8131a?source=rss----18bbcd357609---4</link>
            <guid isPermaLink="false">https://medium.com/p/554173a8131a</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Lee Packham]]></dc:creator>
            <pubDate>Mon, 12 Jun 2017 19:35:17 GMT</pubDate>
            <atom:updated>2017-07-22T08:01:13.183Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/672/1*BVDheVKuwqgMf1mEEmYK0A.jpeg" /></figure><p>A little while ago now, I looked at how d3dx is actually quite slow and looked at why that was and that it’s better to use Direct3D directly to do such things. Generally when one wants to take a screenshot, it needs to beveryfast as to not interfere with the gameplay. This post breaks down what to do when presented with an anti-aliased display so that screenshot taking is nice and quick:</p><pre>LPDIRECT3DSURFACE9 pd3dsBack = NULL;</pre><pre>if ( SUCCEEDED ( device-&gt;GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &amp;pd3dsBack) )) {<br>    D3DSURFACE_DESC desc; pd3dsBack-&gt;GetDesc(&amp;desc);<br>    LPDIRECT3DSURFACE9 pd3dsCopy = NULL;<br>    if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) {<br>        if (SUCCEEDED(device-&gt;CreateRenderTarget(desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &amp;pd3dsCopy, NULL))) {<br>            if (SUCCEEDED(device-&gt;StretchRect(pd3dsBack, NULL, pd3dsCopy, NULL, D3DTEXF_NONE))) {<br>                pd3dsBack-&gt;Release();<br>                pd3dsBack = pd3dsCopy;<br>            } else<br>                pd3dsCopy-&gt;Release();<br>        }<br>    }<br>}</pre><p>The first thing you’ll notice is we grab the back buffer and query whether it has multi-sampling. If it is, we create a new render target and then render the scene onto it. This is far quicker to do than trying to take a shot of a multi-sampled scene as you’ve forced the GPU to do the rendering down onto a surface with no multi-sampling. Job done! That way you can then continue with LockRect() etc. and take the shot as you would do normally.</p><p>This makes taking shots of multi-sampled scenes not more than 1–2ms longer than those that aren’t. Enjoy!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=554173a8131a" width="1" height="1" alt=""><hr><p><a href="https://blog.leepackham.com/d3d-screenshots-with-anti-aliasing-quickly-554173a8131a">D3D Screenshots With Anti-Aliasing… Quickly</a> was originally published in <a href="https://blog.leepackham.com">Lee Packham</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Experiments With Docker-py]]></title>
            <link>https://blog.leepackham.com/experiments-with-docker-py-faa9d50f4273?source=rss----18bbcd357609---4</link>
            <guid isPermaLink="false">https://medium.com/p/faa9d50f4273</guid>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Lee Packham]]></dc:creator>
            <pubDate>Sun, 11 Jun 2017 15:44:23 GMT</pubDate>
            <atom:updated>2017-07-22T07:58:10.827Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/300/1*mw5ovknu32qYO18SEi_msA.png" /></figure><p><a href="https://www.docker.com/">Docker</a> is a hot topic at the moment in the DevOps world. I use it almost every day and want to look at how automation can be achieved in terms of security and monitoring.</p><p>Containers in computing aren’t new. In fact FreeBSD had containers before Google was using them in Linux; although it call them <a href="https://www.freebsd.org/doc/handbook/jails.html">jails</a>.</p><p>Docker is great in that it’s brought containers to the masses. Once the reserve of people with the patience to set up LXC on Linux or the painful jails on FreeBSD — side note: it’s very painful I might talk about that another time.</p><p>We can talk to Docker via it’s RESTful API and libraries exist for almost every language. The two popular obvious ones are Go and Python — I say obvious, but it’s more that I just prefer these two languages. I’m sure the Ruby one is awesome too.</p><p>The downside of Docker that’s coming up more and more is managing security of containers. People often just use official images without a second thought and these end up in production. There’s posts containing loads of FUD on the topic which exist already — but in general how do you ensure you keep your containers’ operating system packages up to date?</p><p>Sounds like a task for a script. I broke it down into the following tasks:</p><ul><li>Connect to Docker (boot2docker in my case)</li><li>Get a list of installed packages in debian:jessie image</li><li>Get a list of packages from security.debian.org</li><li>Compare the two</li></ul><p>I need to add I used Python 3.4 for this. This makes the syntax seem a little odd to a Python 2.x view so needed to say!</p><p>Let’s get connecting out of the way:</p><pre>from docker.client import Client<br>from docker.utils import kwargs_from_env</pre><pre># So we can use boot2docker<br>kwargs = kwargs_from_env()<br>kwargs[&#39;tls&#39;].assert_hostname = False<br>kwargs[&#39;tls&#39;].verify = False  # Workaround <a href="https://github.com/docker/docker-py/issues/465">https://github.com/docker/docker-py/issues/465</a></pre><pre># Set up the client<br>client = Client(**kwargs)</pre><p>Took me a small while to figure out the issue where OpenSSL 1.0.2a causes problems with quite a few libraries and talking to APIs. To get out of it for now I disable the verify part of requests — It’ll complain a lot about it.</p><p>Now we’re connected we can make a container and get some stuff out:</p><pre># Create my Debian Jessie container<br>container = client.create_container(<br>    image=&#39;debian:jessie&#39;,<br>    stdin_open=True,<br>    tty=True,<br>    command=&quot;/usr/bin/dpkg-query -Wf &#39;${Package},${Version}\n&#39;&quot;,<br>)</pre><pre># Launch it with the custom command<br>client.start(container)</pre><pre># Grab the dpkg-query output<br>output = client.logs(container).decode(&quot;utf-8&quot;)</pre><pre>packages = {}</pre><pre>lines = output.split(&#39;\n&#39;)<br>lines.pop(0)<br>for line in lines:<br>    # Last line is a blank<br>    if not line:<br>        continue</pre><pre>k, v = line.split(&#39;,&#39;)<br>    packages[k] = v</pre><p>We now have a stack of packages in a dictionary keyed by package name. To do this we make good use of dpkg-query to get a CSV like list of package,version.</p><p>What we want next is a similar dict for up to date packages. Now, I know a lot of people who might read this would launch into apt-get update and then query the global list of packages. Would you do that in production? Really? You just want a list of stuff… Let’s just get it from security.debian.org directly.</p><pre>import gzip<br>import re</pre><pre>import requests</pre><pre>r = requests.get(&#39;<a href="http://security.debian.org/dists/jessie/updates/main/binary-amd64/Packages.gz&#39;">http://security.debian.org/dists/jessie/updates/main/binary-amd64/Packages.gz&#39;</a>, stream=True)<br>gz = gzip.GzipFile(fileobj=r.raw)</pre><p>A small point here… We make use of the gzip library directly to ungzip the file downloaded via Requests. To do this we use ‘r.raw’ like a file which GzipFile can use without any issue.</p><p>Now the format of this file is a bit weird. It’s a list of key value pairs for each package with a blank line between packages. The two keys we’re interested in for each package are Package (the name) and Version.</p><pre>kvregex = re.compile(r&#39;(\w+): (.*)&#39;)<br>security_updates = {}</pre><pre>current_package = None<br>current_version = None</pre><pre># Build up a security updates dict<br>for line in gz.readlines():<br>    m = kvregex.match(line.decode(&quot;utf-8&quot;))<br>    if not m:<br>        security_updates[current_package] = current_version<br>        continue</pre><pre>g = m.groups()<br>    if g[0] == &#39;Package&#39;:<br>        current_package = g[1]<br>    elif g[0] == &#39;Version&#39;:<br>        current_version = g[1]</pre><pre>r.close()</pre><p>Perfect! We now have a dict with all the security updates in Jessie keyed by the package name again.</p><p>With these two dicts we can intersect them and only get elements that are in both. If the version doesn’t match spit it out. I had to fake an update to exist to test this properly as when I tested there were no out of date packages.</p><pre>def common_entries(*dcts):<br>    for i in set(dcts[0]).intersection(*dcts[1:]):<br>        yield (i,) + tuple(d[i] for d in dcts)</pre><pre># Fake a security update for Sed... (cos Jessie 8.1 is quite up to date)<br>security_updates[&#39;sed&#39;] = &#39;4.2.2-4+b2&#39;</pre><pre>for entry in common_entries(packages, security_updates):<br>    if entry[1] != entry[2]:<br>        print(&#39;%s is %s and a security update exists for %s&#39; % entry)</pre><p>And, there we have it (spot the whining from requests…):</p><pre>$ python foobar.py<br>.../venv/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: <a href="https://urllib3.readthedocs.org/en/latest/security.html">https://urllib3.readthedocs.org/en/latest/security.html</a><br>  InsecureRequestWarning)<br>.../venv/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: <a href="https://urllib3.readthedocs.org/en/latest/security.html">https://urllib3.readthedocs.org/en/latest/security.html</a><br>  InsecureRequestWarning)<br>.../venv/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: <a href="https://urllib3.readthedocs.org/en/latest/security.html">https://urllib3.readthedocs.org/en/latest/security.html</a><br>  InsecureRequestWarning)<br>sed is 4.2.2-4+b1 and a security update exists for 4.2.2-4+b2</pre><p>Awesome! There we have it — a quick way to grab and compare packages against containers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=faa9d50f4273" width="1" height="1" alt=""><hr><p><a href="https://blog.leepackham.com/experiments-with-docker-py-faa9d50f4273">Experiments With Docker-py</a> was originally published in <a href="https://blog.leepackham.com">Lee Packham</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Node.js Piping]]></title>
            <link>https://blog.leepackham.com/node-js-piping-59b623c3ea33?source=rss----18bbcd357609---4</link>
            <guid isPermaLink="false">https://medium.com/p/59b623c3ea33</guid>
            <category><![CDATA[nodejs]]></category>
            <dc:creator><![CDATA[Lee Packham]]></dc:creator>
            <pubDate>Sun, 11 Jun 2017 15:39:13 GMT</pubDate>
            <atom:updated>2017-07-22T07:57:17.747Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-Nq1fQSPq9aeoWxn4WFbhg.png" /></figure><p>It has been a while since I’ve used Node.js for anything serious. To give you an idea of how long go we’re talking… I originally hacked together the Green Man Gaming stock control system in Node.js 0.1.x and to this day it only runs on 0.2.x because of the way 0.4.x changed things way way back and it works so no one dare upgrade it.</p><p>Since then, the Node.js ecosystem has matured and although people make fun of it… Node.js is heavily used on things at massive scale. I’d also like to think I’ve learnt to write better Javascript since working on TweetDeck… but let’s not get ahead of ourselves!</p><p>So I wanted to get up to date on Node and figured I’d have a quick go at using the ‘parse the deb Packages.gz’ file as a quick thing to try out piping.</p><p>This is going to be very crude in places, I’m sure… but here was my quick hack around:</p><pre>// There be lots of dragons...<br>var zlib = require(&#39;zlib&#39;);</pre><pre>var R = require(&#39;request&#39;),<br>    _ = require(&#39;lodash&#39;),<br>    through2 = require(&#39;through2&#39;),<br>    es = require(&#39;event-stream&#39;);</pre><pre>var url = &#39;<a href="http://security.debian.org/dists/jessie/updates/main/binary-amd64/Packages.gz&#39;">http://security.debian.org/dists/jessie/updates/main/binary-amd64/Packages.gz&#39;</a>;</pre><pre>var all = [];</pre><pre>R.get(url)<br>    .pipe(zlib.createGunzip())<br>    .on(&#39;error&#39;, function() {<br>        console.log(&quot;it&#39;s all broke yo&quot;);<br>    })<br>    // Split by each &#39;object&#39; in the packages file<br>    .pipe(es.split(/\n\n/))<br>    .pipe(through2.obj(function(chunk, enc, callback) {<br>        // We&#39;ll get an empty chunk at the end<br>        if (chunk === &quot;&quot;) {<br>            callback();<br>            return;<br>        }<br>        // Create kv Pairs from each line<br>        var kvPairs = _.map(chunk.split(&#39;\n&#39;), function(line) {<br>            return line.split(&#39;: &#39;);<br>        });<br>        // Lower case the attributes - cos that&#39;s better<br>        var fixedAttribs = _.map(kvPairs, function(obj) {<br>            return [obj[0].toLowerCase(), obj[1]]<br>        });</pre><pre>this.push(_.zipObject(fixedAttribs));<br>        callback();<br>    }))<br>    .on(&#39;data&#39;, function(data) {<br>        all.push(data)<br>    })<br>    .on(&#39;end&#39;, function () {<br>        console.log(JSON.stringify(all));<br>    });</pre><p>I know Streams were introduced way back in 0.8.x of Node.js — but… wow that code is far simpler to understand than counterparts in other languages. It also improved debugging — as I was able to debug each part of the pipe.</p><p>The only thing that took me a short while was ‘what if the request fails’. It turned out that I had to use the ‘on’ error bit at the point in the pipe where I was adding the gunzip streaming. If I threw up there — then I’d be all good.</p><p>Either way — as a post Dota2 TI5 final night bit of experimenting it was certainly worthwhile.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=59b623c3ea33" width="1" height="1" alt=""><hr><p><a href="https://blog.leepackham.com/node-js-piping-59b623c3ea33">Node.js Piping</a> was originally published in <a href="https://blog.leepackham.com">Lee Packham</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>