<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: gvalkov</title><link>https://news.ycombinator.com/user?id=gvalkov</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Mon, 15 Jun 2026 13:09:42 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=gvalkov" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by gvalkov in "32GB of DDR5 now costs $375 – AI shortage continues to squeeze PC building"]]></title><description><![CDATA[
<p>The squeeze is real even at the SME level. We recently wanted to add another TB of memory to several servers (we do EDA chip design, which eats a lot of memory). Quotes came back to about €200k for 48 x 96GB DDR5-5600 RDIMMs. Mind you, this is for refurbished memory with 1 year warranty. I'm still figuring out if this is FU-pricing or just how things are going to be from now on.<p>Spec-ing and buying servers has become quite the pain in the past year, at least at the relatively-small scale we operate at. It's "dynamic pricing" with most quotes being valid for 24 hours :(</p>
]]></description><pubDate>Wed, 03 Jun 2026 14:28:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=48384617</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=48384617</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48384617</guid></item><item><title><![CDATA[New comment by gvalkov in "Shell Tricks That Make Life Easier (and Save Your Sanity)"]]></title><description><![CDATA[
<p>In zsh you can bind "push-line-or-edit". In bash and all readline programs, you can approximate it with C-u followed by C-y (i.e. cut and paste). My history is still full of '#' and ':' (csh trauma) prefixed command-lines like you described though ...</p>
]]></description><pubDate>Thu, 26 Mar 2026 12:36:01 +0000</pubDate><link>https://news.ycombinator.com/item?id=47529680</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=47529680</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47529680</guid></item><item><title><![CDATA[New comment by gvalkov in "The Synology End Game"]]></title><description><![CDATA[
<p>I'm using that case with with a 200mm fan front-panel mod[1]. Despite its size, it gets pretty cramped. It's just hard to keep it organized without a dedicated SATA backplane.<p>[1]: <a href="https://www.printables.com/model/866109-200mm-fan-front-for-fractal-node-304" rel="nofollow">https://www.printables.com/model/866109-200mm-fan-front-for-...</a></p>
]]></description><pubDate>Fri, 29 Aug 2025 10:02:45 +0000</pubDate><link>https://news.ycombinator.com/item?id=45062196</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=45062196</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45062196</guid></item><item><title><![CDATA[New comment by gvalkov in "I'm switching to Python and actually liking it"]]></title><description><![CDATA[
<p>In Python 3.8 - <a href="https://peps.python.org/pep-0572/" rel="nofollow">https://peps.python.org/pep-0572/</a></p>
]]></description><pubDate>Wed, 16 Jul 2025 16:08:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=44583878</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=44583878</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44583878</guid></item><item><title><![CDATA[New comment by gvalkov in "I'm switching to Python and actually liking it"]]></title><description><![CDATA[
<p>This is nitpicking, but this is a good usecase for the := operator:<p><pre><code>  if not (API_KEY := os.getenv("API_KEY")):
      ...
</code></pre>
For internal tools I just let os.environ["API_KEY"] raise a KeyError. It's descriptive enough.</p>
]]></description><pubDate>Wed, 16 Jul 2025 15:31:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=44583402</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=44583402</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44583402</guid></item><item><title><![CDATA[New comment by gvalkov in "Serving 200M requests per day with a CGI-bin"]]></title><description><![CDATA[
<p>We're still serving a cgi-bin directory at work for the occasional quick and dirty internal web app. The ergonomics are great as long as you keep it simple. The fact that it's cgi doesn't mean you have to print http/1.0 to stdout manually. For example, in python the builtin wsgiref.handlers.CGIHandler lets you run any wsgi app as a cgi script:<p><pre><code>  import wsgiref.handlers, flask
  app = flask.Flask(__name__)
  wsgiref.handlers.CGIHandler().run(app)
</code></pre>
The way we run the scripts is with uwsgi and its cgi plugin[1]. I find it simpler and more flexible than running apache or lighttpd just for mod_cgi. Since uwsgi runs as a systemd unit, we also have all of systemd's hardening and sandboxing capabilities at our disposal. Something very convenient in uwsgi's cgi handling that's missing from mod_cgi, is the ability to set the interpreter for a given file type:<p><pre><code>  cgi = /cgi-bin=/webapps/cgi-bin/src
  cgi-allowed-ext = .py
  cgi-helper = .py=/webapps/cgi-bin/venv/bin/python3  # all dependencies go here
</code></pre>
Time to first byte is 250-350ms, which is acceptable for our use case.<p>[1]: <a href="https://uwsgi-docs.readthedocs.io/en/latest/CGI.html" rel="nofollow">https://uwsgi-docs.readthedocs.io/en/latest/CGI.html</a></p>
]]></description><pubDate>Sun, 06 Jul 2025 10:14:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=44479388</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=44479388</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44479388</guid></item><item><title><![CDATA[New comment by gvalkov in "Boxie – an always offline audio player for my 3 year old"]]></title><description><![CDATA[
<p>I recently built something[1] similar, though with far less effort and sophistication than the author. The goal was to have a plug-and-play audiobook player for an elderly family member with impaired vision. In retrospect, it would have been better to adapt an old phone or tablet with a macropad rather than build this on top of an espmuse speaker[2].<p>I keep thinking that a cassette player would be the ideal interface for something like this. The controls are as obvious and as tactile as it gets and the whole analog-mechanical experience is familiar to folks from that generation. If only tapes could hold more than two hours of audio ...<p>[1]: <a href="https://www.printables.com/model/1269288-audiobook-player" rel="nofollow">https://www.printables.com/model/1269288-audiobook-player</a><p>[2]: <a href="https://raspiaudio.com/product/esp-muse-luxe/" rel="nofollow">https://raspiaudio.com/product/esp-muse-luxe/</a></p>
]]></description><pubDate>Mon, 28 Apr 2025 07:37:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=43818639</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=43818639</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43818639</guid></item><item><title><![CDATA[New comment by gvalkov in "Ruby 3.2’s YJIT is Production-Ready"]]></title><description><![CDATA[
<p>Python 3.11 also claims [1] to be 10-60% faster than 3.10, which is the version that the benchmarks game is using at this time. The difference in used RSS is also quite interesting in this comparison.<p><pre><code>  [1]: https://docs.python.org/3/whatsnew/3.11.html#whatsnew311-faster-cpython</code></pre></p>
]]></description><pubDate>Tue, 17 Jan 2023 17:21:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=34415393</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=34415393</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=34415393</guid></item><item><title><![CDATA[New comment by gvalkov in "Python 3.12.0 is to remove long-deprecated items"]]></title><description><![CDATA[
<p>A hidden gem of pyenv is its 'python-build' plugin, which just lets you build and install any Python version in the least number of steps:<p><pre><code>  git clone https://github.com/pyenv/pyenv.git
  cd pyenv/plugins/python-build/bin
  ./python-build --definitions
  ./python-build 3.10.8 /opt/python/3.10.8
  PYTHON_CONFIGURE_OPTS="--enable-shared" ./python-build 3.10.8 /opt/python/3.10.8</code></pre></p>
]]></description><pubDate>Wed, 16 Nov 2022 11:50:20 +0000</pubDate><link>https://news.ycombinator.com/item?id=33621707</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=33621707</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=33621707</guid></item><item><title><![CDATA[New comment by gvalkov in "The cult of dd (2017)"]]></title><description><![CDATA[
<p>One nice use of dd is to append an ssh key to .authorized_keys on a host that doesn't allow shell or sftp access (which is what ssh-copy-id needs):<p><pre><code>  cat id_rsa.pub | ssh $host 'dd of=.ssh/authorized_keys oflag=append conv=notrunc'</code></pre></p>
]]></description><pubDate>Tue, 25 Oct 2022 08:42:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=33327863</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=33327863</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=33327863</guid></item><item><title><![CDATA[New comment by gvalkov in "Podman: A Daemonless Container Engine"]]></title><description><![CDATA[
<p>It's great to see how far Podman (and its sister projects) have come. I think it's a reliable tool and I'm a happy user both personally and professionally.<p>We make heavy use of Podman in our infrastructure and it's mostly a pleasure. My current pet peeves are that:<p>1) Ansible's podman_container module is not as polished as docker_container. I regularly run into idempotency issues with it (so lots of needlessly restarted containers).<p>2) Gitlab's Docker executor doesn't support Podman and all our CI agents run on CentOS 8. I ended up writing a custom executor for it and it's working quite well though (we're probably not going back to the container executor even if it supported Podman, since the custom executor offers so much more flexibility).<p>3) GPU support is easier/more documented on Docker. For this reason, the GPU servers we have are all Ubuntu 20.04 + Docker since it's the more beaten path.<p>4) Podman-compose just needs more work. Luckily for us, it seems that Podman 3.x will support docker-compose natively [1].<p>As mentioned, our CI environment is very dependent on Podman. The first step of every Gitlab pipelines is to build the container image in which the rest of the jobs will run. I find that it's simpler to have a shell executor in a unprivileged, restricted environment (i.e. can only run `podman build`) than setting up dind just for building images. All jobs that follow are ran in rootless containers, for that nice added layer of security.<p>Wishing all the best to the Podman, Buildah and Skopeo teams.<p>[1]: <a href="https://www.redhat.com/sysadmin/podman-docker-compose" rel="nofollow">https://www.redhat.com/sysadmin/podman-docker-compose</a></p>
]]></description><pubDate>Fri, 12 Feb 2021 01:03:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=26109677</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=26109677</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=26109677</guid></item><item><title><![CDATA[New comment by gvalkov in "Podman: A Daemonless Container Engine"]]></title><description><![CDATA[
<p>Quite a lot is possible with CNI [1]. For example, we use this setup to give real IPs to containers:<p><pre><code>  # /etc/cni/net.d/testnet.conflist
  {
    "cniVersion": "0.4.0",
    "name": "testnet",
    "plugins": [
      {
        "type": "bridge",
        "bridge": "br0",  # main host interface is part of this bridge
        "ipam": {
          "type": "host-local",
          "subnet": "10.0.0.0/16",
          "gateway": "10.0.0.1",
          "routes": [{ "dst": "0.0.0.0/0"}]
        }
      }
    ]
  }
</code></pre>
You can then start a container and operate on its network namespace for added flexibility:<p><pre><code>  podman run -it --net testnet --ip 10.0.0.2 ...

  ns=$(basename $(podman inspect $id | jq -r '.[0] .NetworkSettings .SandboxKey'))
  ip netns exec $ns ip route add ...
</code></pre>
[1]: <a href="https://github.com/containernetworking/cni" rel="nofollow">https://github.com/containernetworking/cni</a></p>
]]></description><pubDate>Thu, 11 Feb 2021 23:46:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=26109097</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=26109097</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=26109097</guid></item><item><title><![CDATA[New comment by gvalkov in "Ask HN: What do you do with your Raspberry Pi?"]]></title><description><![CDATA[
<p>A device that waits for the SSID of my Olympus WiFi-enabled camera to show up and then sync all new photos:<p><a href="https://github.com/gvalkov/olympus-photosync-server" rel="nofollow">https://github.com/gvalkov/olympus-photosync-server</a>
<a href="https://github.com/gvalkov/olympus-photosync" rel="nofollow">https://github.com/gvalkov/olympus-photosync</a></p>
]]></description><pubDate>Tue, 25 Jun 2019 08:54:49 +0000</pubDate><link>https://news.ycombinator.com/item?id=20272271</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=20272271</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=20272271</guid></item><item><title><![CDATA[New comment by gvalkov in "SCons: A Software Construction Tool"]]></title><description><![CDATA[
<p>It's not possible in the way it's possible in SCons. You can basically use custom_target, but its usefulness is limited since there are no user-defined functions in Meson's subset of Python. CMake is a little better in this regard here, since it at least offers macros and functions.</p>
]]></description><pubDate>Sun, 09 Jun 2019 16:11:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=20140059</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=20140059</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=20140059</guid></item><item><title><![CDATA[New comment by gvalkov in "SCons: A Software Construction Tool"]]></title><description><![CDATA[
<p>Personally I see Meson as an attempt to do CMake right. A big differences between Meson and SCons is that SCons handles the execution of the build graph, while Meson delegates execution to Ninja. The nice thing about the former is that while the graph is being walked, new nodes can be added. The nice thing about the latter is that it's incredibly efficient.</p>
]]></description><pubDate>Sun, 09 Jun 2019 16:01:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=20140002</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=20140002</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=20140002</guid></item><item><title><![CDATA[New comment by gvalkov in "SCons: A Software Construction Tool"]]></title><description><![CDATA[
<p>I'm a build engineer and SCons is one of the gems in my tool belt. Where it truly shines is as a framework for building build systems. At its core, it's just a library for building and executing a DAG. What most SCons users work with is the standard-library of rules built on top of the core API, that makes it immediately usable as a "high-level" build system like Meson or Cmake. In my experience, it's unparalleled when you have to model an entirely custom build-flow in a clean way. I've used it to model build-flows for custom tool-chains that would have been a nightmare to reason about if they were written in GNU Make and outright impossible with a meta-build system.<p>The only other tools I've found to rival this flexibility are Gradle (see the Software Domain Modeling chapter of its  documentation) and Shake (though having to write rules in Haskell makes it a hard pill to swallow).</p>
]]></description><pubDate>Sun, 09 Jun 2019 15:46:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=20139914</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=20139914</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=20139914</guid></item><item><title><![CDATA[New comment by gvalkov in "Pipenv: promises a lot, delivers very little"]]></title><description><![CDATA[
<p><p><pre><code>  > Use it. Talk about it. Write about it.
</code></pre>
I have a project that converts basic setup.py files to setup.cfg files [1].<p>Still happily using plain setuptools for library development and pip-tools for application development.<p>[1]: <a href="https://github.com/gvalkov/setuptools-py2cfg" rel="nofollow">https://github.com/gvalkov/setuptools-py2cfg</a></p>
]]></description><pubDate>Thu, 06 Dec 2018 09:52:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=18616658</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=18616658</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=18616658</guid></item><item><title><![CDATA[New comment by gvalkov in "12 Factor CLI Apps"]]></title><description><![CDATA[
<p>A problem with color is that people end up optimizing the aesthetics for their own terminal setup. There is a wild number of different color schemes out there and it's really hard to make something that looks good on all of them. In my experience the only safe choice is bold text (i.e. \033[1m) since it stands out in all cases.</p>
]]></description><pubDate>Tue, 09 Oct 2018 07:20:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=18173938</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=18173938</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=18173938</guid></item><item><title><![CDATA[New comment by gvalkov in "Show HN: Rb – Turns Ruby into a command line utility"]]></title><description><![CDATA[
<p>Several people have tried to tackle this in Python. My attempt was python-oneliner[1]. There's also a list of similar projects in the readme.<p>[1] <a href="https://github.com/gvalkov/python-oneliner" rel="nofollow">https://github.com/gvalkov/python-oneliner</a></p>
]]></description><pubDate>Tue, 14 Aug 2018 10:27:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=17756673</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=17756673</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=17756673</guid></item><item><title><![CDATA[New comment by gvalkov in "Bash Infinity: Standard library and boilerplate framework for Bash"]]></title><description><![CDATA[
<p>I think you're making this more complicated than it needs to be. For simple things, it's ok to just:<p><pre><code>  from subprocess import run
  run('foo | bar', shell=True, check=True)</code></pre></p>
]]></description><pubDate>Sun, 12 Aug 2018 10:24:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=17743780</link><dc:creator>gvalkov</dc:creator><comments>https://news.ycombinator.com/item?id=17743780</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=17743780</guid></item></channel></rss>