Dowry
Few days back, had posted about the movie Raksha Bandhan and whatever I felt about it. Sadly, just couple of days back, somebody shared this link. Part of me was shocked and part of me was not. Couple of acquaintances of mine in the past had said the same thing for their daughters. And in such situations you are generally left speechless because you don t know what the right thing to do is. If he has shared it with you being an outsider, how many times he must have told the same to their wife and daughters? And from what little I have gathered in life, many people have justified it on similar lines. And while the protests were there, sadly the book was not removed. Now if nurses are reading such literature, how their thought process might be forming, you can tell :(. And these are the ones whom we call for when we are sick and tired :(. And I have not taken into account how the girls/women themselves might be feeling. There are similar things in another country but probably not the same, nor the same motivations though although feeling helplessness in both would be a common thing.
But such statements are not alone. Another gentleman in slightly different context shared this as well
The above is a statement shared in a book recommended for CTET (Central Teacher s Eligibility Test that became mandatory to be taken as the RTE (Right To Education) Act came in.). The statement says People from cold places are white, beautiful, well-built, healthy and wise. And people from hot places are black, irritable and of violent nature.
Now while I can agree with one part of the statement that people residing in colder regions are more fair than others but there are loads of other factors that determine fairness or skin color/skin pigmentation. After a bit of search came to know that this and similar articulation have been made in an idea/work called Environmental Determinism . Now if you look at that page, you would realize this was what colonialism is and was all about. The idea that the white man had god-given right to rule over others. Similarly, if you are fair, you can lord over others. Seems simplistic, but yet it has a powerful hold on many people in India. Forget the common man, this thinking is and was applicable to some of our better-known Freedom fighters. Pune s own Bal Gangadhar Tilak The Artic Home to the Vedas. It sort of talks about Aryans and how they invaded India and became settled here. I haven t read or have access to the book so have to rely on third-party sources. The reason I m sharing all this is that the right-wing has been doing this myth-making for sometime now and unless and until you put a light on it, it will continue to perpetuate . For those who have read this blog, do know that India is and has been in casteism from ever. They even took the fair comment and applied it to all Brahmins. According to them, all Brahmins are fair and hence have god-given right to lord over others. What is called the Eton boy s network serves the same in this casteism. The only solution is those idea under limelight and investigate. To take the above, how does one prove that all fair people are wise and peaceful while all people black and brown are violent. If that is so, how does one count for Mahatma Gandhi, Martin Luther King Junior, Nelson Mandela, Michael Jackson the list is probably endless. And not to forget that when Mahatma Gandhiji did his nonviolent movements either in India or in South Africa, both black and brown people in millions took part. Similar examples of Martin Luther King Jr. I know and read of so many non-violent civl movements that took place in the U.S. For e.g. Rosa Parks and the Montgomery Bus Boycott. So just based on these examples, one can conclude that at least the part about the fair having exclusive rights to being fair and noble is not correct.
Now as far as violence goes, while every race, every community has had done violence in the past or been a victim of the same. So no one is and can be blameless, although in light of the above statement, the question can argumentated as to who were the Vikings? Both popular imagination and serious history shares stories about Vikings. The Vikings were somewhat nomadic in nature even though they had permanent settlements but even then they went on raids, raped women, captured both men and women and sold them at slaves. So they are what pirates came to be, but not the kind Hollywood romanticizes about. Europe in itself has been a tale in conflict since time immemorial. It is only after the formation of EU that most of these countries stopped fighting each other From a historical point perspective, it is too new. So even the part of fair being non-violent dies in face of this evidence. I could go on but this is enough on that topic.
Railways and Industrial Action around the World.
While I have shared about Railways so many times on this blog, it continues to fascinate me that how people don t understand the first things about Railways. For e.g. Railways is a natural monopoly. What that means is and you can look at all and any type of privatization around the world, you will see it is a monopoly. Unlike the road or Skies, Railways is and would always be limited by infrastructure and the ability to have new infrastructure. Unlike in road or Skies (even they have their limits) you cannot run train services on a whim. At any particular point in time, only a single train could and should occupy a stretch of Railway network. You could have more trains on one line, but then the likelihood of front or rear-end collisions becomes a real possibility. You also need all sorts of good and reliable communications, redundant infrastructure so if one thing fails then you have something in place. The reason being a single train can carry anywhere from 2000 to 5000 passengers or more. While this is true of Indian Railways, Railways around the world would probably have some sort of similar numbers.It is in this light that I share the below videos.
To be more precise, see the fuller video
Now to give context to the recording above, Mike Lynch is the general secretary at RMT. For those who came in late, both UK and the U.S. have been threatened by railway strikes. And the reason for the strikes or threat of strikes is similar. Now from the company perspective, all they care is to invest less and make the most profits that can be given to equity shareholders. At the same time, they have freezed the salaries of railway workers for the last 3 years. While the politicians who were asking the questions, apparently gave themselves raise twice this year. They are asking them to negotiate at 8% while inflation in the UK has been 12.3% and projected to go higher. And it is not only the money. Since the 1980s when UK privatized the Railways, they stopped investing in the infrastructure. And that meant that the UK Railway infrastructure over period of time started getting behind and is even behind say Indian Railways which used to provide most bang for the buck. And Indian Railways is far from ideal. Ironically, most of the operators on UK are nationalized Railways of France, Germany etc. but after the hard Brexit, they too are mulling to cut their operations short, they have too There is also the EU Entry/Exit system that would come next year.
Why am I sharing about what is happening in UK Rail, because the Indian Government wants to follow the same thing, and fooling the public into saying we would do it better. What inevitably will happen is that ticket prices go up, people no longer use the service, the number of services go down and eventually they are cancelled. This has happened both in Indian Railways as well as Airlines. In fact, GOI just recently announced a credit scheme just a few days back to help Airlines stay afloat. I was chatting with a friend who had come down to Pune from Chennai and the round-trip cost him INR 15k/- on that single trip alone. We reminisced how a few years ago, 8 years to be precise, we could buy an Air ticket for 2.5k/- just a few days before the trip and did it. I remember doing/experiencing at least a dozen odd trips via air in the years before 2014. My friend used to come to Pune, almost every weekend because he could afford it, now he can t do that. And these are people who are in the above 5-10% of the population. And this is not just in UK, but also in the United States. There is one big difference though, the U.S. is mainly a freight carrier while the UK Railway Operations are mostly passenger based. What was and is interesting that Scotland had to nationalize their services as they realized the Operators cannot or will not function when they were most needed. Most of the public even in the UK seem to want a nationalized rail service, at least their polls say so. So, it would definitely be interesting to see what happens in the UK next year.
In the end, I know I promised to share about books, but the above incidents have just been too fascinating to not just share the news but also share what I think about them. Free markets function good where there is competition, for example what is and has been happening in China for EV s but not where you have natural monopolies. In all Railway privatization, you have to handover the area to one person, then they have no motivation. If you have multiple operators, then there would always be haggling as to who will run the train and at what time. In either scenario, it doesn t work and raises prices while not delivering anything better
I do take examples from UK because lot of things are India are still the legacy of the British. The whole civil department that was created in 1953 is/was a copy of the British civil department at that time and it is to this day.
P.S. Just came to know that the UK Chancellor Kwasi Kwarteng was just sacked as UK Chancellor. I do commend Truss for facing the press even though she might be dumped a week later unlike our PM who hasn t faced a single press conference in the last 8 odd years.
https://www.youtube.com/watch?v=oTP6ogBqU7of
The difference in Indian and UK politics seems to be that the English are now asking questions while here in India, most people are still sleeping without a care in the world.
Another thing to note Minidebconf Palakkad is gonna happen 12-13th November 2022. I am probably not gonna go but would request everyone who wants to do something in free software to attend it. I am not sure whether I would be of any use like this and also when I get back, it would be an empty house. But for people young and old, who want to do anything with free/open source software it is a chance not to be missed. Registration of the same closes on 1st of November 2022. All the best, break a leg
Just read this, beautifully done.
I m on the train back from MuniHac, where I gave a talk about the rec-def library that I have excessively blogged about recently (here, here, here and here). I got quite flattering comments about that talk, so if you want to see if they were sincere, I suggest you watch the recording of Getting recursive definitions off their bottoms (but it s not necessary for the following).
After the talk, Franz Thoma approached me and told me a story of how we was once implementing the game Minesweeper in Haskell, and in particular the part of the logic where, after the user has uncovered a field, the game would automatically uncover all fields that are next to a neutral field, i.e. one with zero adjacent bombs. He was using a comonadic data structure, which makes a context-dependent parallel computation such as uncovering one field quite natural, and was hoping that using a suitable fix-point operator, he can elegantly obtain not just the next step, but directly the result of recursively uncovering all these fields. But, much to his disappointment, that did not work out: Due to the recursion inherent in that definition, a knot-tying fixed-point operator will lead to a cyclic definition.
Microsoft Minesweeper
He was wondering if the rec-def library could have helped him, and we sat down to find out, and this is the tale of this blog post. I will avoid the comonadic abstractions and program it more naively, though, to not lose too many readers along the way. Maybe read Chris Penner s blog post and Finch s functional pearl Getting a Quick Fix on Comonads if you are curious about that angle.
Minesweeper setup
Let s start with defining a suitable data type for the grid of the minesweeper board. I ll use the Array data type, it s Ix-based indexing is quite useful for grids:
This entry explains how I have configured a linux bridge, dnsmasq and
iptables to be able to run and communicate different virtualization systems
and containers on laptops running Debian GNU/Linux.
I ve used different variations of this setup for a long time with
VirtualBox and KVM for
the Virtual Machines and Linux-VServer,
OpenVZ, LXC and lately
Docker or Podman for the
Containers.
Required packagesI m running Debian Sid with systemd and network-manager to configure the
WiFi and Ethernet interfaces, but for the bridge I use bridge-utils with
ifupdown (as I said this setup is old, I guess ifupdow2 and ifupdown-ng
will work too).
To start and stop the DNS and DHCP services and add NAT rules when the
bridge is brought up or down I execute a script that uses:
ip from iproute2 to get the network information,
dnsmasq to provide the DNS and DHCP services (currently only the
dnsmasq-base package is needed and it is recommended by network-manager,
so it is probably installed),
iptables to configure NAT (for now docker kind of forces me to keep using
iptables, but at some point I d like to move to nftables).
To make sure you have everything installed you can run the following command:
Warning: To use a separate file with ifupdown make sure that /etc/network/interfaces
contains the line:
source /etc/network/interfaces.d/*
or add its contents to /etc/network/interfaces directly, if you prefer.
This configuration creates a bridge with the address 10.0.4.1 and
assumes that the machines connected to it will use the 10.0.4.0/24 network;
you can change the network address if you want, as long as you use a private
range and it does not collide with networks used in your Virtual Machines all
should be OK.
The vmbridge script is used to start the dnsmasq server and setup the NAT
rules when the interface is brought up and remove the firewall rules and stop
the dnsmasq server when it is brought down.
The vmbridge scriptThe vmbridge script launches an instance of dnsmasq that binds to the
bridge interface (vmbr0 in our case) that is used as DNS and DHCP server.
The DNS server reads the /etc/hosts file to publish local DNS names and
forwards all the other requests to the the dnsmasq server launched by
NetworkManager that is listening on the loopback interface.
As this server already does catching we disable it for our server, with the
added advantage that, if we change networks, new requests go to the new
resolvers because the DNS server handled by NetworkManager gets restarted and
flushes its cache (this is useful if we connect to a new network that has
internal DNS servers that are configured to do split DNS for internal services;
if we use this model all requests get the internal address as soon as the DNS
server is queried again).
The DHCP server is configured to provide IPs to unknown hosts for a sub range
of the addresses on the bridge network and use fixed IPs if the /etc/ethers
file has a MAC with a matching hostname on the /etc/hosts file.
To make things work with old DHCP clients the script also adds checksums to
the DHCP packets using iptables (when the interface is not linked to a
physical device the kernel does not add checksums, but we can fix it adding a
rule on the mangle table).
If we want external connectivity we can pass the nat argument and then the
script creates a MASQUERADE rule for the bridge network and enables IP
forwarding.
The script source code is the following:
/usr/local/sbin/vmbridge
Which means that it will leave interfaces managed by ifupdown alone and, by
default, will send the connection DNS configuration to systemd-resolved if it
is installed.
As we want to use dnsmasq for DNS resolution, but we don t want
NetworkManager to modify our /etc/resolv.conf we are going to add the
following file (/etc/NetworkManager/conf.d/dnsmasq.conf) to our system:
/etc/NetworkManager/conf.d/dnsmasq.conf
[main]dns=dnsmasqrc-manager=unmanaged
and restart the NetworkManager service:
$sudo systemctl restart NetworkManager.service
From now on the NetworkManager will start a dnsmasq service that queries
the servers provided by the DHCP servers we connect to on 127.0.0.1:53 but
will not touch our /etc/resolv.conf file.
Configuring systemd-resolvedIf we start using our own name server but our system has systemd-resolved
installed we will no longer need or use the DNS stub; programs using it will
use our dnsmasq server directly now, but we keep running systemd-resolved
for the host programs that use its native api or access it through
/etc/nsswitch.conf (when libnss-resolve is installed).
To disable the stub we add a /etc/systemd/resolved.conf.d/disable-stub.conf
file to our machine with the following content:
# Disable the DNS Stub Listener, we use our own dnsmasq
[Resolve]DNSStubListener=no
and restart the systemd-resolved to make sure that the stub is stopped:
$sudo systemctl restart systemd-resolved.service
Adjusting /etc/resolv.confFirst we remove the existing /etc/resolv.conf file (it does not matter if it
is a link or a regular file) and then create a new one that contains at least
the following line (we can add a search line if is useful for us):
nameserver 10.0.4.1
From now on we will be using the dnsmasq server launched when we bring up the
vmbr0 for multiple systems:
as our main DNS server from the host (if we use the standard
/etc/nsswitch.conf and libnss-resolve is installed it is queried first,
but the systemd-resolved uses it as forwarder by default if needed),
as the DNS server of the Virtual Machines or containers that use DHCP for
network configuration and attach their virtual interfaces to our bridge,
as the DNS server of docker containers that get the DNS information from
/etc/resolv.conf (if we have entries that use loopback addresses the
containers that don t use the host network tend to fail, as those addresses
inside the running containers are not linked to the loopback device of the
host).
TestingAfter all the configuration files and scripts are in place we just need to
bring up the bridge interface and check that everything works:
$# Bring interface up$sudo ifup vmbr0
$# Check that it is available$ip a ls dev vmbr0
4: vmbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP>mtu 1500 qdisc noqueue state DOWN
group default qlen 1000
link/ether 0a:b8:ef:b8:07:6c brd ff:ff:ff:ff:ff:ff
inet 10.0.4.1/24 brd 10.0.4.255 scope global vmbr0
valid_lft forever preferred_lft forever
$# View the listening ports used by our dnsmasq servers$sudo ss -tulpangrep dnsmasq
udp UNCONN 0 0 127.0.0.1:53 0.0.0.0:* users:(("dnsmasq",pid=1733930,fd=4))
udp UNCONN 0 0 10.0.4.1:53 0.0.0.0:* users:(("dnsmasq",pid=1705267,fd=6))
udp UNCONN 0 0 0.0.0.0%vmbr0:67 0.0.0.0:* users:(("dnsmasq",pid=1705267,fd=4))
tcp LISTEN 0 32 10.0.4.1:53 0.0.0.0:* users:(("dnsmasq",pid=1705267,fd=7))
tcp LISTEN 0 32 127.0.0.1:53 0.0.0.0:* users:(("dnsmasq",pid=1733930,fd=5))
$# Verify that the DNS server works on the vmbr0 address$host www.debian.org 10.0.4.1
Name: 10.0.4.1
Address: 10.0.4.1#53
Aliases:
www.debian.org has address 130.89.148.77
www.debian.org has IPv6 address 2001:67c:2564:a119::77
Managing running systemsIf we want to update DNS entries and/or MAC addresses we can edit the
/etc/hosts and /etc/ethers files and reload the dnsmasq configuration
using the vmbridge script:
$sudo /usr/local/sbin/vmbridge vmbr0 reload
That call sends a signal to the running dnsmasq server and it reloads the
files; after that we can refresh the DHCP addresses from the client machines or
start using the new DNS names immediately.
Welcome to the September 2022 report from the Reproducible Builds project! In our reports we try to outline the most important things that we have been up to over the past month. As a quick recap, whilst anyone may inspect the source code of free software for malicious flaws, almost all software is distributed to end users as pre-compiled binaries. If you are interested in contributing to the project, please visit our Contribute page on our website.
David A. Wheeler reported to us that the US National Security Agency (NSA), Cybersecurity and Infrastructure Security Agency (CISA) and the Office of the Director of National Intelligence (ODNI) have released a document called Securing the Software Supply Chain: Recommended Practices Guide for Developers (PDF).
As David remarked in his post to our mailing list, it expressly recommends having reproducible builds as part of advanced recommended mitigations . The publication of this document has been accompanied by a press release.
Holger Levsen was made aware of a small Microsoft project called oss-reproducible. Part of, OSSGadget, a larger collection of tools for analyzing open source packages , the purpose of oss-reproducible is to:
analyze open source packages for reproducibility. We start with an existing package (for example, the NPM left-pad package, version 1.3.0), and we try to answer the question, Do the package contents authentically reflect the purported source code?
More details can be found in the README.md file within the code repository.
David A. Wheeler also pointed out that there are some potential upcoming changes to the OpenSSF Best Practices badge for open source software in relation to reproducibility. Whilst the badge programme has three certification levels ( passing , silver and gold ), the gold level includes the criterion that The project MUST have a reproducible build .
David reported that some projects have argued that this reproducibility criterion should be slightly relaxed as outlined in an issue on the best-practices-badge GitHub project. Essentially, though, the claim is that the reproducibility requirement doesn t make sense for projects that do not release built software, and that timestamp differences by themselves don t necessarily indicate malicious changes. Numerous pragmatic problems around excluding timestamps were raised in the discussion of the issue.
Sonatype, a pioneer of software supply chain management , issued a press release month to report that they had found:
[ ] a massive year-over-year increase in cyberattacks aimed at open source project ecosystems. According to early data from Sonatype s 8th annual State of the Software Supply Chain Report, which will be released in full this October, Sonatype has recorded an average 700% jump in repository attacks over the last three years.
More information is available in the press release.
A number of changes were made to the Reproducible Builds website and documentation this month, including Chris Lamb adding a redirect from /projects/ to /who/ in order to keep old or archived links working [], Jelle van der Waa added a Rust programming language example for SOURCE_DATE_EPOCH [][] and Mattia Rizzolo included Protocol Labs amongst our project-level sponsors [].
Debian
There was a large amount of reproducibility work taking place within Debian this month:
The nfft source package was removed from the archive, and now all packages in Debian bookworm now have a corresponding .buildinfo file. This can be confirmed and tracked on the associated page on thetests.reproducible-builds.org site.
Vagrant Cascadian announced on our mailing list an informal online sprint to help clear the huge backlog of reproducible builds patches submitted by performing NMU (Non-Maintainer Uploads). The first such sprint took place on September 22nd with the following results:
Holger Levsen:
Mailed #1010957 in man-db asking for an update and whether to remove the patch tag for now. This was subsequently removed and the maintainer started to address the issue.
Emailed #1017372 in plymouth and asked for the maintainer s opinion on the patch. This resulted in the maintainer improving Vagrant s original patch (and uploading it) as well as filing an issue upstream.
The plan is to repeat these sprints every two weeks, with the next taking place on Thursday October 6th at 16:00 UTC on the #debian-reproducible IRC channel.
Roland Clobus posted his 13th update of the status of reproducible Debian ISO images on our mailing list. During the last month, Roland ensured that the live images are now automatically fed to openQA for automated testing after they have been shown to be reproducible. Additionally Roland asked on the debian-devel mailing list about a way to determine the canonical timestamp of the Debian archive. []
Lastly, 44 reviews of Debian packages were added, 91 were updated and 17 were removed this month adding to our knowledge about identified issues. A number of issue types have been updated too, including the descriptions of cmake_rpath_contains_build_path [], nondeterministic_version_generated_by_python_param [] and timestamps_in_documentation_generated_by_org_mode []. Furthermore, two new issue types were created: build_path_used_to_determine_version_or_package_name [] and captures_build_path_via_cmake_variables [].
Other distributions
In openSUSE, Bernhard M. Wiedemann published his usual openSUSE monthly report.
diffoscopediffoscope is our in-depth and content-aware diff utility. Not only can it locate and diagnose reproducibility issues, it can provide human-readable diffs from many kinds of binary formats. This month, Chris Lamb prepared and uploaded versions 222 and 223 to Debian, as well as made the following changes:
The cbfstools utility is now provided in Debian via the coreboot-utils package so we can enable that functionality within Debian. []
Fixed the try.diffoscope.org service by addressing a compatibility issue between glibc/seccomp that was preventing the Docker-contained diffoscope instance from spawning any external processes whatsoever []. I also updated the requirements.txt file, as some of the specified packages were no longer available [][].
In addition Jelle van der Waa added support for file version 5.43 [] and Mattia Rizzolo updated the packaging:
Also include coreboot-utils in the Build-Depends and Test-Depends fields so that it is available for tests. []
Use pep517 and pip to load the requirements. []
Remove packages in Breaks/Replaces that have been obsoleted since the release of Debian bullseye. []
Reprotestreprotest is our end-user tool to build the same source code twice in widely and deliberate different environments, and checking whether the binaries produced by the builds have any differences. This month, reprotest version 0.7.22 was uploaded to Debian unstable by Holger Levsen, which included the following changes by Philip Hands:
Actually ensure that the setarch(8) utility can actually execute before including an architecture to test. []
Include all files matching *.*deb in the default artifact_pattern in order to archive all results of the build. []
Emit an error when building the Debian package if the Debian packaging version does not patch the Python version of reprotest. []
Remove an unneeded invocation of the head(1) utility. []
Upstream patches
The Reproducible Builds project detects, dissects and attempts to fix as many currently-unreproducible packages as possible. We endeavour to send all of our patches upstream where appropriate. This month, we wrote a large number of such patches, including:
Testing framework
The Reproducible Builds project runs a significant testing framework at tests.reproducible-builds.org in order to check packages and other artifacts for reproducibility. This month, however, the following changes were made:
Holger Levsen:
Add a job to build reprotest from Git [] and use the correct Git branch when building it [].
Mattia Rizzolo:
Enable syncing of results from building live Debian ISO images. []
Use scp -p in order to preserve modification times when syncing live ISO images. []
Apply the shellcheck shell script analysis tool. []
In a build node wrapper script, remove some debugging code which was messing up calling scp(1) correctly [] and consquently add support to use both scp -p and regular scp [].
Roland Clobus:
Track and handle the case where the Debian archive gets updated between two live image builds. []
Remove a call to sudo(1) as it is not (or no longer) required to delete old live-build results. []
Contact
As ever, if you are interested in contributing to the Reproducible Builds project, please visit our Contribute page on our website. However, you can get in touch with us via:
Version 0.3.14 of the Rblpapi package arrived on CRAN earlier today. Rblpapi provides a direct interface between R and the Bloomberg Terminal via the C++ API provided by Bloomberg (but note that a valid Bloomberg license and installation is required).
This is the fourteenth release since the package first appeared on CRAN in 2016. It comprises a nice PR from Robert Harlow extending support to B-PIPE authentication (for those who have it) along with a few fixes made since the last release in January. The last one provided from a kind assist by Tomas Kalibera who pointed out how to overcome an absolute rpath dynamic linker instruction (and as I noticed noticed something I already did in another package ah well) so that we no longer require StagedInstall: yes.
The detailed list of changes follow below.
Changes in Rblpapi version 0.3.14 (2022-10-05)
Build configuration was generalized to consider local copies of library and headers (Dirk in #362)
A ticker symbol was corrected (Dirk in #368 addressing an issue #366 and #367)
Support for B-PIPE was added (Robert Harlow in #369 closing #342)
The package no longer requires staged installation thanks to an assist from Tomas Kalibera (Dirk in #373)
The retired package fts is no longer suggested (Dirk in #374 closing #372)
Courtesy of my CRANberries, there is also a diffstat report for the this release. As always, more detailed information is on the Rblpapi page. Questions, comments etc should go to the issue tickets system at the GitHub repo.
If you like this or other open-source work I do, you can now sponsor me at GitHub.
I work on OpenJDK backports:
taking a patch that was committed to a current version of JDK, and adapting it
to an older one. There are four main OpenJDK versions that I am concerned with:
the current version ("jdk"), 8, 11 and 17. These are all maintained in separate
Git(Hub) repositories.
It's very useful to have access to the other JDKs when working on any
particular version. For example, to backport a patch from the latest version to
17, where the delta is not too big, a lot of the time you can cherry-pick the
patch unmodified. To do git cherry-pick <some-commit> in a git repository
tracking JDK17, where <some-commit> is in "jdk", I need the "jdk" repository
configured as a remote for my local jdk17 repository.
Maintaining completely separate local git repositories for all four JDK versions,
with each of them having a subset of the others added as remotes, adds up to a
lot of duplicated data on local storage.
For a little while I was exploring using shared clones: a local clone of another local git
repository which share some local metadata. This saves on some disc space, but
it does not share the configuration for remotes: so I still have to add any other
JDK versions I want as remotes in each shared clone (even if the underlying objects
already exist in the shared metadata)
Then I discovered git worktree. The
git repositories that I've used up until now have had exactly zero (for a bare
clone) or one worktree: in other words, the check-out, the actual source code
files. Git does actually support having more than one worktree, which can be
achieved like so:
The result (in this example) is a new checkout, in this case of a new local
branch named jdk8u-master at the sibling directory path jdk.worktree.jdk8u,
tracking the remote branch jdk8u-dev/master. Within that checkout, there is a
file .git which contains a pointer to (indirectly) the main local repository
path:
The directory itself behaves exactly like the real one, in that I can see all
the configured remotes, and other checked out branches in other worktree
paths:
Above, you can see that the current worktree is the branch 8237479-jdk8u-dev,
marked (as usual) by the prefix *, and two other branches are checked out
in other worktrees, marked by the prefix +.
I only need to configure one local git repository with all of the remotes
I am concerned about; I can inspect, compare, cherry-pick, check out, etc.
any objects from any of those branches from any of my work trees; there's
only one .git directory with all the configuration and storage for the
git blobs across all the versions.
(Sorry if you have read this already, due to a tag mistake, my draft
copy got published)
I recently bought a refurbished thinkpad x260. If you have read my
post of my <a href= <!DOCTYPE html>
Laptop refreshment
Canon Space is run, in a way, by the noble mercantile houses, who spread
their cities, colonies, and mines through the mysterious Web that allows
faster-than-light interstellar travel. The true rulers of Canon Space,
though, are the Guardships: enormous, undefeatable starships run by crews
who have become effectively immortal by repeated uploading and
reincarnation. Or, in the case of the Deified, without reincarnation,
observing, ordering, advising, and meddling from an entirely virtual
existence. The Guardships have enforced the status quo for four thousand
years.
House Tregesser thinks they have the means to break the stranglehold of
the Guardships. They have contact with Outsiders from beyond Canon Space
who can provide advanced technology. They have their own cloning
technology, which they use to create backup copies of their elites. And
they have Lupo Provik, a quietly brilliant schemer who has devoted his
life to destroying Guardships.
This book was so bad. A more sensible person than I would have given up
after the first hundred pages, but I was too stubborn. The stubbornness
did not pay off.
Sometimes I pick up an older SFF novel and I'm reminded of how much the
quality bar in the field has been raised over the past twenty years. It's
not entirely fair to treat The Dragon Never Sleeps as typical of
1980s science fiction: Cook is far better known for his Black
Company military fantasy series, this is one of his minor novels, and
it's only been intermittently in print. But I'm dubious this would have
been published at all today.
First, the writing is awful. It's choppy, cliched, awkward, and has no
rhythm or sense of beauty. Here's a nearly random paragraph near the
beginning of the book as a sample:
He hurled thunders and lightnings with renewed fury. The whole damned
universe was out to frustrate him. XII Fulminata! What the
hell? Was some malign force ranged against him?
That was his most secret fear. That somehow someone or something was
using him the way he used so many others.
(Yes, this is one of the main characters throwing a temper tantrum with a
special effects machine.)
In a book of 450 pages, there are 151 chapters, and most chapters switch
viewpoint characters. Most of them also end with a question or some
vaguely foreboding sentence to try to build tension, and while I'm willing
to admit that sometimes works when used sparingly, every three pages is
not sparingly.
This book is also weirdly empty of description for its size. We get a few
set pieces, a few battles, and a sentence or two of physical description
of most characters when they're first introduced, but it's astonishing how
little of a mental image I had of this universe after reading the whole
book. Cook probably describes a Guardship at some point in this book, but
if he does, it completely failed to stick in my memory. There are aliens
that everyone recognizes as aliens, so presumably they look different than
humans, but for most of them I have no idea how. Very belatedly we're
told one important species (which never gets a name) has a distinctive
smell. That's about it.
Instead, nearly the whole book is dialogue and scheming. It's clear that
Cook is intending to write a story of schemes and counter-schemes and
jousting between brilliant characters. This can work if the dialogue is
sufficiently sharp and snappy to carry the story. It is not.
"What mischief have you been up to, Kez Maefele?"
"Staying alive in a hostile universe."
"You've had more than your share of luck."
"Perhaps luck had nothing to do with it, WarAvocat. Till now."
"Luck has run out. The Ku Question has run its course. The symbol is
about to receive its final blow."
There are hundreds of pages of this sort of thing.
The setting is at least intriguing, if not stunningly original. There are
immortal warships oppressing human space, mysterious Outsiders, great
house politics, and an essentially immortal alien warrior who ends up
carrying most of the story. That's material for a good space opera if the
reader slowly learns the shape of the universe, its history, and its
landmarks and political factions. Or the author can decline to explain
any of that. I suppose that's also a choice.
Here are some things that you may have been curious about after reading
my summary, and which I'm still curious about after having finished the
book: What laws do the Guardships impose and what's the philosophy
behind those laws? How does the economic system work? Who built the
Guardships originally, and how? How do the humans outside of Canon Space
live? Who are the Ku? Why did they start fighting the humans? How
many other aliens are there? What do they think of this? How does the
Canon government work? How have the Guardships remained technologically
superior for four thousand years?
Even where the reader gets a partial explanation, such as what Web is and
how it was built, it's an unimportant aside that's largely devoid of a
sense of wonder. The one piece of world-building that this book is
interested in is the individual Guardships and the different ways in which
they've handled millennia of self-contained patrol, and even there we only
get to see a few of them.
There is a plot with appropriately epic scope, but even that is undermined
by the odd pacing. Five, ten, or fifty years sometimes goes by in a
sentence. A war starts, with apparently enormous implications for Canon
Space, and then we learn that it continues for years without warranting
narrative comment. This is done without transitions and without signposts
for the reader; it's just another sentence in the narration, mixed in with
the rhetorical questions and clumsy foreshadowing.
I would like to tell you that at least the book has a satisfying ending
that resolves the plot conflict that it finally reveals to the reader, but
I had a hard time understanding why the ending even mattered. The plot
was so difficult to follow that I'm sure I missed something, but it's not
difficult to follow in the fun way that would make me want to re-read it.
It's difficult to follow because Cook doesn't seem able to explain the
plot in his head to the reader in any coherent form. I think the status
quo was slightly disrupted? Maybe? Also, I no longer care.
Oh, and there's a gene-engineered sex slave in this book, who various
male characters are very protective and possessive of, who never develops
much of a personality, and who has no noticeable impact on the plot despite
being a major character. Yay.
This was one of the worst books I've read in a long time. In retrospect,
it was an awful place to start with Glen Cook. Hopefully his better-known
works are also better-written, but I can't say I feel that inspired to
find out.
Rating: 2 out of 10
Death Certificate
After waiting for almost two, two, and a half months, I finally got mum s death certificate last week. A part of me was saddened as it felt like I was nailing her or putting nails to the coffin or whatever it is, (even though I m an Agarwal) I just felt sad and awful. I was told just get a death certificate and your problems will be over. Some people wanted me to give some amount under the table or something which I didn t want to party of and because of that perhaps it took a month, month and a half more as I came to know later that it had been issued almost a month and a half back. The inflation over the last 8 years of the present Govt. has made the corrupt even more corrupt, all the while projecting and telling others that the others are corrupt. There had been also a few politicians who were caught red-handed but then pieces of evidence & witnesses vanish overnight. I don t really wanna go in that direction as it would make for an unpleasant reading with no solutions at all unless the present Central Govt. goes out.
Intestate and Will
I came to know the word Intestate. This was a new word/term for me. A lookup told me that intestate means a person dying without putting a will. That legal term comes from U.K. law. I had read a long long time back that almost all our laws have and were made or taken from U.K. law. IIRC, massive sections of the CRPC Act even today have that colonial legacy. While in its (BJP) manifesto that had been shared with the public at the time of the election, they had shared that they will remove a whole swathe of laws that don t make sense in today s environment. But when hard and good questions were asked, they trimmed a few, modified a few, and left most of them as it is. Sadly, most of the laws that they did modify increased Government control over people instead of decreasing, It s been 8 years and yet we still don t have a Privacy law. They had made something but it was too vague and would have invited suits from day 1 so pretty much on backburner :(. A good insight into what I mean is an article in the Hindu I read a few days back. Once you read that article, I am sure you will have as many questions as I have but sadly no answers.
Law is not supposed to be partisan but today it is. I could cite examples from both the U.S. and UK courts about progressive judgments or the way they go about it, but then again when our people think they know better But this again does not help me apart from setting some kind of background of where we are.) I have on this blog also shared how Africans have been setting new records in transparency and they did it almost 5 years back. For those new to the blog, African countries have been now broadcasting proceedings of their SC for almost 5 years now. I noticed it when privacy law was being debated and a few handles that I follow on Twitter and elsewhere had gone and given their submission in their SC. It was fascinating to not only hear but also read about the case from multiple viewpoints.
And just to remind people, I am sharing all of this from Pune, Maharashtra which is the second-biggest city in Maharashtra that has something like six million people and probably a million or more transitory students, and casual laborers but then again that doesn t help me other than providing a kind of context to what I m sharing..
Now a couple of years back or more I had asked mum to make a will. If she wanted to bequeath something to somebody else she could do that, had shared about that. There was some article in Indian Express or elsewhere that told people what they should be doing, especially if they had cost the barrier of age 60. Now for reasons best known to her, she refused and now I have to figure out what is the right way to go about doing things.
Twitter Experiences
Now before Twitter, a few people had been asking me about having a legal heir certificate, while others are asking about a succession certificate and some claim a Death Certificate is enough. Now I asked the same question on Twitter hoping at the max of 5-10 responses but was overwhelmed by the response. I got something like 50-60 odd replies. Probably, one of the better responses was given by Dr. Paras Jain who shared the following
Answer is qualified Movable assets nothing required Bank LIC flat with society nomination done nothing required except death certificate. However, each will insist on a notarized indemnity bond If the nomination is not done. Depends on whims & fancy of each mind legal heir certificate,+ all Dr. Paras Jain. (cleared up the grammar a little, otherwise, views are of Dr. Paras.)
What was interesting for me is that most people just didn t give me advice, many of them also shared their own experiences or what they did or went through. I was surprised to learn e.g. that a succession certificate can take up to 6 months or more. Part of me isn t surprised to learn that as do know we have a huge pendency of cases in High Courts, District Courts leading all the way to the Supreme Court. India Today shared a brief article sharing the same and similar issues. Such delays have become far too common now
Supertech Demolition and Others
Over the last couple of months, a number of high-profile demolitions have taken place and in most cases, the loss has been of homebuyers. See for e.g. the case of Supertech. A much more detailed article was penned by Moneylife. There were a few Muslims whose homes were demolished just a couple of months back that were being celebrated, but now just 2-3 days back a politician by the name of Shrikant Tyagi, a BJP leader, his flat was partly demolished and there was a lot of hue and cry. Although we shouldn t be discussing on the basis of religion but legality, somehow the idea has been put that there are two kinds of laws, one for the majority, the other for the minority. And this has been going on for the last 8 odd years, hence you see different reactions to the same incidents instead of similar reactions. In all the cases, no strictures are passed either against the Municipality or against lenders.
The most obvious question, let s say for argument s sake, I was a homeowner in Supertech. I bought a flat for say 10 lakhs in 2012. According to the courts, today I am supposed to get 22 lakhs at 12% simple interest for 10 years. Let s say even if the builder was in a position and does honor the order, the homeowner will not get a house in the same area as the circle rate would probably have quadrupled by then at the very least. The circle rate alone might be the above amount. The reason is very simple, a builder buys land on the cheap when there is no development around. His/her/their whole idea is once development happens due to other builders also building flats, the whole area gets developed and they are able to sell the flats at a premium. Even Circle rates get affected as the builder pays below the table and asks the officers of the municipal authority to hike the circle rate every few months. Again, wouldn t go into much depth as the whole thing is rotten to the core. There are many such projects. I have shared Krishnaraj Rao s videos on this blog a few times. I am sure there are a few good men like him. At the end, sadly this is where we are
P.S. I haven t shared any book reviews this week as this post itself has become too long. I probably may blog about a couple of books in the next couple of days, till later.
Well this is a mouthful.
I recently worked on a neat hack called puppet-package-check. It
is designed to warn about manually installed packages, to make sure
"everything is in Puppet". But it turns out it can (probably?)
dramatically decrease the bootstrap time of Puppet bootstrap when it
needs to install a large number of packages.
Detecting manual packages
On a cleanly filed workstation, it looks like this:
Yuck! That's a lot of shit to go through.
Notice how the packages get sorted between "old" and "new"
packages. This is because popcon is used as a tool to mark which
packages are "old". If you have unmanaged packages, the "old" ones are
likely things that you can uninstall, for example.
If you don't have popcon installed, you'll also get this warning:
popcon stats not available: [Errno 2] No such file or directory: '/var/log/popularity-contest'
The error can otherwise be safely ignored, but you won't get "help"
prioritizing the packages to add to your manifests.
Note that the tool ignores packages that were "marked" (see
apt-mark(8)) as automatically installed. This implies that you
might have to do a little bit of cleanup the first time you run this,
as Debian doesn't necessarily mark all of those packages correctly on
first install. For example, here's how it looks like on a clean
install, after Puppet ran:
Normally, there should be unmanaged packages here. But because of the
way Debian is installed, a lot of libraries and some core packages are
marked as manually installed, and are of course not managed through
Puppet. There are two solutions to this problem:
really manage everything in Puppet (argh)
mark packages as automatically installed
I typically chose the second path and mark a ton of stuff as
automatic. Then either they will be auto-removed, or will stop being
listed. In the above scenario, one could mark all libraries as
automatically installed with:
apt-mark auto $(./bin/puppet-package-check grep -o 'lib[^ ]*')
... but if you trust that most of that stuff is actually garbage that
you don't really want installed anyways, you could just mark it all
as automatically installed:
apt-mark auto $(./bin/puppet-package-check)
In my case, that ended up keeping basically all libraries (because of
course they're installed for some reason) and auto-removing this:
You'll notice xorg in there: yep, that's bad. Not what I wanted. But
for some reason, on other workstations, I did not actually have
xorg installed. Turns out having xserver-xorg is enough, and that
one has dependencies. So now I guess I just learned to stop worrying
and live without X(org).
Optimizing large package installs
But that, of course, is not all. Why make things simple when you can
have an unreadable title that is trying to be both syntactically
correct and click-baity enough to flatter my vain ego? Right.
One of the challenges in bootstrapping Puppet with large package lists
is that it's slow. Puppet lists packages as individual resources and
will basically run apt install $PKG on every package in the
manifest, one at a time. While the overhead of apt is generally
small, when you add things like apt-listbugs, apt-listchanges,
needrestart, triggers and so on, it can take forever setting up a
new host.
So for initial installs, it can actually makes sense to skip the queue
and just install everything in one big batch.
And because the above tool inspects the packages installed by Puppet,
you can run it against a catalog and have a full lists of all the
packages Puppet would install, even before I even had Puppet
running.
So when reinstalling my laptop, I basically did this:
That massive grep was because there are currently a lot of
packages missing from bookworm. Those are all packages that I have
in my catalog but that still haven't made it to bookworm. Sad, I
know. I eventually worked around that by adding bullseye sources so
that the Puppet manifest actually ran.
The point here is that this improves the Puppet run time a lot. All
packages get installed at once, and you get a nice progress bar. Then
you actually run Puppet to deploy configurations and all the other
goodies:
puppet agent --test
I wish I could tell you how much faster that ran. I don't know, and I
will not go through a full reinstall just to please your
curiosity. The only hard number I have is that it installed 444
packages (which exploded in 10,191 packages with dependencies) in a
mere 10 minutes. That might also be with the packages already
downloaded.
In any case, I have that gut feeling it's faster, so you'll have to
just trust my gut. It is, after all, much more important than you
might think.
It figures out what you ve done manually, stores it locally in a Git
repository, generates code that s able to recreate your efforts, and
helps you deploy those changes to production
That tool has unfortunately been abandoned for a decade at this point.
Also note that the AutoRemove::RecommendsImportant and
AutoRemove::SuggestsImportant are relevant here. If it is set to
true (the default), a package will not be removed if it is
(respectively) a Recommends or Suggests of another package (as
opposed to the normal Depends). In other words, if you want to also
auto-remove packages that are only Suggests, you would, for example,
add this to apt.conf:
AutoRemove::SuggestsImportant false;
Paul Wise has tried to make the Debian installer and debootstrap
properly mark packages as automatically installed in the past, but his
bug reports were rejected. The other suggestions in this section are
also from Paul, thanks!
This summer, I signed up to participate in the Northcape 4000
<https://www.northcape4000.com/>, an annual 4000km bike ride between Rovereto
(in northern Italy) and the northernmost point of Europe, the North cape.
The Northcape event has been held for several years, and while it always ends
on the North Cape, the route there varies. Last years route went through the
Baltics, but this years was perhaps as direct as possible - taking us through
Italy, Austria, Switzerland, Germany, the Czech republic, Germany again, Sweden,
Finland and finally Norway.
The ride is unsupported, meaning you have to find your own food and
accomodation and can only avail yourself of resupply and sleeping options on
the route that are available to everybody else as well. The event is not meant
to be a race (unlike the Transcontinental, which starts at the same day),
so there is a minimum time to finish it in (10 days) and a maximum (21 days).
Unfortunately, this meant skipping some other events I d wanted attend
(DebConf, MCH).
The new version of QSoas has just been released ! It brings in a host of new features, as the releases before, but maybe the most important change is the following...
Binary images now freely available !
Starting from now, all the binary images for the new versions of QSoas will freely available from the download page. You can download the precompiled versions of QSoas for MacOS or windows. So now, you have no reason anymore not to try !
My aim with making the binaries freely available is also to simplify the release process for me and therefore increase the rate at which new versions are released.
Improvements to the fit interface
Some work went into improving the fit interface, in particular for the handling of fit trajectories when doing parameter space exploration, for difficult fits with many parameters and many local minima. The fit window now features real menus, along with tab a way to display the terminal (see the menus and the tabs selection on the image).
Individual fits have also been improved, with, among others, the possibility to easily simulate voltammograms with the kinetic-system fits, and the handling of Marcus-Hush-Chidsey (or Marcus "distribution of states") kinetics for electron transfers.
Column and row names
This release greatly improves the handling of column and row names, including commands to easily modify them, the possibility to use Ruby formulas to change them, and a much better way read and write them to data files. Mastering the use of column names (and to a lesser extent, row names) can greatly simplify data handling, especially when dealing with files with a large number of columns.
Complex numbers
Version 3.1 brings in support for formulas handling complex numbers. Although it is not possible to store complex numbers directly into datasets, it is easy to separate them in real and imaginary parts to your liking.
Scripting improvement
Two important improvements for scripting are included in version 3.1. The first is the possibility to define virtual files inside a script file, which makes it easy to define subfunctions to run using commands like run-for-each. The second is the possibility to define variables to be reused later (like the script arguments) using the new command let.
There are a lot of other new features, improvements and so on, look for the full list there.
About QSoas QSoas is a powerful open source data analysis program that focuses on flexibility and powerful fitting capacities. It is released under the GNU General Public License. It is described in Fourmond, Anal. Chem., 2016, 88 (10), pp 5050 5052. Current version is 3.1. You can download its source code or precompiled versions for MacOS and Windows there. Alternatively, you can clone from the GitHub repository.
This post describes how I ve put together a simple static content server for
kubernetes clusters using a Pod with a persistent volume and multiple
containers: an sftp server to manage contents, a web server to publish them
with optional access control and another one to run scripts which need access
to the volume filesystem.
The sftp server runs using
MySecureShell, the web
server is nginx and the script runner uses the
webhook tool to publish endpoints to call
them (the calls will come from other Pods that run backend servers or are
executed from Jobs or CronJobs).
HistoryThe system was developed because we had a NodeJS API with endpoints to upload
files and store them on S3 compatible services that were later accessed via
HTTPS, but the requirements changed and we needed to be able to publish folders
instead of individual files using their original names and apply access
restrictions using our API.
Thinking about our requirements the use of a regular filesystem to keep the
files and folders was a good option, as uploading and serving files is simple.
For the upload I decided to use the sftp protocol, mainly because I already
had an sftp container image based on
mysecureshell prepared; once
we settled on that we added sftp support to the API server and configured it
to upload the files to our server instead of using S3 buckets.
To publish the files we added a nginx container configured
to work as a reverse proxy that uses the
ngx_http_auth_request_module
to validate access to the files (the sub request is configurable, in our
deployment we have configured it to call our API to check if the user can
access a given URL).
Finally we added a third container when we needed to execute some tasks
directly on the filesystem (using kubectl exec with the existing containers
did not seem a good idea, as that is not supported by CronJobs objects, for
example).
The solution we found avoiding the NIH Syndrome (i.e. write our own tool) was
to use the webhook tool to provide the
endpoints to call the scripts; for now we have three:
one to get the disc usage of a PATH,
one to hardlink all the files that are identical on the filesystem,
one to copy files and folders from S3 buckets to our filesystem.
Container definitions
mysecureshellThe mysecureshell container can be used to provide an sftp service with
multiple users (although the files are owned by the same UID and GID) using
standalone containers (launched with docker or podman) or in an
orchestration system like kubernetes, as we are going to do here.
The image is generated using the following Dockerfile:
The /etc/sftp_config file is used to
configure
the mysecureshell server to have all the user homes under /sftp/data, only
allow them to see the files under their home directories as if it were at the
root of the server and close idle connections after 5m of inactivity:
etc/sftp_config
# Default mysecureshell configuration<Default>
# All users will have access their home directory under /sftp/data
Home /sftp/data/$USER
# Log to a file inside /sftp/logs/ (only works when the directory exists)
LogFile /sftp/logs/mysecureshell.log
# Force users to stay in their home directory
StayAtHome true
# Hide Home PATH, it will be shown as /
VirtualChroot true
# Hide real file/directory owner (just change displayed permissions)
DirFakeUser true
# Hide real file/directory group (just change displayed permissions)
DirFakeGroup true
# We do not want users to keep forever their idle connection
IdleTimeOut 5m
</Default>
# vim: ts=2:sw=2:et
The entrypoint.sh script is the one responsible to prepare the container for
the users included on the /secrets/user_pass.txt file (creates the users with
their HOME directories under /sftp/data and a /bin/false shell and
creates the key files from /secrets/user_keys.txt if available).
The script expects a couple of environment variables:
SFTP_UID: UID used to run the daemon and for all the files, it has to be
different than 0 (all the files managed by this daemon are going to be
owned by the same user and group, even if the remote users are different).
SFTP_GID: GID used to run the daemon and for all the files, it has to be
different than 0.
And can use the SSH_PORT and SSH_PARAMS values if present.
It also requires the following files (they can be mounted as secrets in
kubernetes):
/secrets/host_keys.txt: Text file containing the ssh server keys in mime
format; the file is processed using the reformime utility (the one included
on busybox) and can be generated using the
gen-host-keys script included on the container (it uses ssh-keygen and
makemime).
/secrets/user_pass.txt: Text file containing lines of the form
username:password_in_clear_text (only the users included on this file are
available on the sftp server, in fact in our deployment we use only the
scs user for everything).
And optionally can use another one:
/secrets/user_keys.txt: Text file that contains lines of the form
username:public_ssh_ed25519_or_rsa_key; the public keys are installed on
the server and can be used to log into the sftp server if the username
exists on the user_pass.txt file.
The contents of the entrypoint.sh script are:
entrypoint.sh
#!/bin/shset-e# ---------# VARIABLES# ---------# Expects SSH_UID & SSH_GID on the environment and uses the value of the# SSH_PORT & SSH_PARAMS variables if present# SSH_PARAMSSSH_PARAMS="-D -e -p $ SSH_PORT:=22$ SSH_PARAMS"# Fixed values# DIRECTORIESHOME_DIR="/sftp/data"CONF_FILES_DIR="/secrets"AUTH_KEYS_PATH="/etc/ssh/auth_keys"# FILESHOST_KEYS="$CONF_FILES_DIR/host_keys.txt"USER_KEYS="$CONF_FILES_DIR/user_keys.txt"USER_PASS="$CONF_FILES_DIR/user_pass.txt"USER_SHELL_CMD="/usr/bin/mysecureshell"# TYPESHOST_KEY_TYPES="dsa ecdsa ed25519 rsa"# ---------# FUNCTIONS# ---------# Validate HOST_KEYS, USER_PASS, SFTP_UID and SFTP_GID
_check_environment()# Check the ssh server keys ... we don't boot if we don't have themif[!-f"$HOST_KEYS"];then
cat<<EOF
We need the host keys on the '$HOST_KEYS' file to proceed.
Call the 'gen-host-keys' script to create and export them on a mime file.
EOF
exit 1
fi# Check that we have users ... if we don't we can't continueif[!-f"$USER_PASS"];then
cat<<EOF
We need at least the '$USER_PASS' file to provision users.
Call the 'gen-users-tar' script to create a tar file to create an archive that
contains public and private keys for users, a 'user_keys.txt' with the public
keys of the users and a 'user_pass.txt' file with random passwords for them
(pass the list of usernames to it).
EOF
exit 1
fi# Check SFTP_UIDif[-z"$SFTP_UID"];then
echo"The 'SFTP_UID' can't be empty, pass a 'GID'."exit 1
fi
if["$SFTP_UID"-eq"0"];then
echo"The 'SFTP_UID' can't be 0, use a different 'UID'"exit 1
fi# Check SFTP_GIDif[-z"$SFTP_GID"];then
echo"The 'SFTP_GID' can't be empty, pass a 'GID'."exit 1
fi
if["$SFTP_GID"-eq"0"];then
echo"The 'SFTP_GID' can't be 0, use a different 'GID'"exit 1
fi# Adjust ssh host keys
_setup_host_keys()opwd="$(pwd)"tmpdir="$(mktemp-d)"cd"$tmpdir"ret="0"
reformime <"$HOST_KEYS"ret="1"for kt in$HOST_KEY_TYPES;do
key="ssh_host_$ kt_key"pub="ssh_host_$ kt_key.pub"if[!-f"$key"];then
echo"Missing '$key' file"ret="1"fi
if[!-f"$pub"];then
echo"Missing '$pub' file"ret="1"fi
if["$ret"-ne"0"];then
continue
fi
cat"$key">"/etc/ssh/$key"chmod 0600 "/etc/ssh/$key"chown root:root "/etc/ssh/$key"cat"$pub">"/etc/ssh/$pub"chmod 0600 "/etc/ssh/$pub"chown root:root "/etc/ssh/$pub"done
cd"$opwd"rm-rf"$tmpdir"return"$ret"# Create users
_setup_user_pass()opwd="$(pwd)"tmpdir="$(mktemp-d)"cd"$tmpdir"ret="0"[-d"$HOME_DIR"]mkdir"$HOME_DIR"# Make sure the data dir can be managed by the sftp userchown"$SFTP_UID:$SFTP_GID""$HOME_DIR"# Allow the user (and root) to create directories inside the $HOME_DIR, if# we don't allow it the directory creation fails on EFS (AWS)chmod 0755 "$HOME_DIR"# Create usersecho"sftp:sftp:$SFTP_UID:$SFTP_GID:::/bin/false">"newusers.txt"sed-n"/^[^#]/ s/:/ /p ""$USER_PASS"while read-r _u _p;do
echo"$_u:$_p:$SFTP_UID:$SFTP_GID::$HOME_DIR/$_u:$USER_SHELL_CMD"done>>"newusers.txt"
newusers --badnames newusers.txt
# Disable write permission on the directory to forbid remote sftp users to# remove their own root dir (they have already done it); we adjust that# here to avoid issues with EFS (see before)chmod 0555 "$HOME_DIR"# Clean up the tmpdircd"$opwd"rm-rf"$tmpdir"return"$ret"# Adjust user keys
_setup_user_keys()if[-f"$USER_KEYS"];then
sed-n"/^[^#]/ s/:/ /p ""$USER_KEYS"while read-r _u _k;do
echo"$_k">>"$AUTH_KEYS_PATH/$_u"done
fi# Main function
exec_sshd()
_check_environment
_setup_host_keys
_setup_user_pass
_setup_user_keys
echo"Running: /usr/sbin/sshd $SSH_PARAMS"# shellcheck disable=SC2086exec /usr/sbin/sshd -D$SSH_PARAMS# ----# MAIN# ----case"$1"in"server") exec_sshd ;;*)exec"$@";;esac# vim: ts=2:sw=2:et
The container also includes a couple of auxiliary scripts, the first one can be
used to generate the host_keys.txt file as follows:
$docker run --rm stodh/mysecureshell gen-host-keys > host_keys.txt
Where the script is as simple as:
bin/gen-host-keys
#!/bin/shset-e# Generate new host keys
ssh-keygen -A>/dev/null
# Replace hostnamesed-i-e's/@.*$/@mysecureshell/' /etc/ssh/ssh_host_*_key.pub
# Print in mime format (stdout)
makemime /etc/ssh/ssh_host_*# vim: ts=2:sw=2:et
And there is another script to generate a .tar file that contains auth data
for the list of usernames passed to it (the file contains a user_pass.txt
file with random passwords for the users, public and private ssh keys for them
and the user_keys.txt file that matches the generated keys).
To generate a tar file for the user scs we can execute the following:
$docker run --rm stodh/mysecureshell gen-users-tar scs > /tmp/scs-users.tar
To see the contents and the text inside the user_pass.txt file we can do:
Basically we are removing the existing docker-entrypoint.d scripts from the
standard image and adding a new one that configures the web server as we want
using a couple of environment variables:
AUTH_REQUEST_URI: URL to use for the auth_request, if the variable is not
found on the environment auth_request is not used.
HTML_ROOT: Base directory of the web server, if not passed the default
/usr/share/nginx/html is used.
Note that if we don t pass the variables everything works as if we were using
the original nginx image.
The contents of the configuration script are:
docker-entrypoint.d/10-update-default-conf.sh
As we will see later the idea is to use the /sftp/data or /sftp/data/scs
folder as the root of the web published by this container and create an
Ingress object to provide access to it outside of our kubernetes cluster.
webhook-scsThe webhook-scs container is generated using the following Dockerfile:
Again, we use a multi-stage build because in production we wanted to support a
functionality that is not already on the official versions (streaming the
command output as a response instead of waiting until the execution ends); this
time we build the image applying the PATCH included on this
pull request against a released
version of the source instead of creating a fork.
The entrypoint.sh script is used to generate the webhook configuration file
for the existing hooks using environment variables (basically the
WEBHOOK_WORKDIR and the *_TOKEN variables) and launch the webhook
service:
entrypoint.sh
#!/bin/shset-e# ---------# VARIABLES# ---------WEBHOOK_BIN="$ WEBHOOK_BIN:-/webhook/hooks"WEBHOOK_YML="$ WEBHOOK_YML:-/webhook/scs.yml"WEBHOOK_OPTS="$ WEBHOOK_OPTS:--verbose"# ---------# FUNCTIONS# ---------
print_du_yml()cat<<EOF
- id: du
execute-command: '$WEBHOOK_BIN/du.sh'
command-working-directory: '$WORKDIR'
response-headers:
- name: 'Content-Type'
value: 'application/json'
http-methods: ['GET']
include-command-output-in-response: true
include-command-output-in-response-on-error: true
pass-arguments-to-command:
- source: 'url'
name: 'path'
pass-environment-to-command:
- source: 'string'
envname: 'OUTPUT_FORMAT'
name: 'json'
EOF
print_hardlink_yml()cat<<EOF
- id: hardlink
execute-command: '$WEBHOOK_BIN/hardlink.sh'
command-working-directory: '$WORKDIR'
http-methods: ['GET']
include-command-output-in-response: true
include-command-output-in-response-on-error: true
EOF
print_s3sync_yml()cat<<EOF
- id: s3sync
execute-command: '$WEBHOOK_BIN/s3sync.sh'
command-working-directory: '$WORKDIR'
http-methods: ['POST']
include-command-output-in-response: true
include-command-output-in-response-on-error: true
pass-environment-to-command:
- source: 'payload'
envname: 'AWS_KEY'
name: 'aws.key'
- source: 'payload'
envname: 'AWS_SECRET_KEY'
name: 'aws.secret_key'
- source: 'payload'
envname: 'S3_BUCKET'
name: 's3.bucket'
- source: 'payload'
envname: 'S3_REGION'
name: 's3.region'
- source: 'payload'
envname: 'S3_PATH'
name: 's3.path'
- source: 'payload'
envname: 'SCS_PATH'
name: 'scs.path'
stream-command-output: true
EOF
print_token_yml()if["$1"];then
cat<<EOF
trigger-rule:
match:
type: 'value'
value: '$1'
parameter:
source: 'header'
name: 'X-Webhook-Token'
EOF
fi
exec_webhook()# Validate WORKDIRif[-z"$WEBHOOK_WORKDIR"];then
echo"Must define the WEBHOOK_WORKDIR variable!">&2
exit 1
fi
WORKDIR="$(realpath"$WEBHOOK_WORKDIR" 2>/dev/null)"true
if[!-d"$WORKDIR"];then
echo"The WEBHOOK_WORKDIR '$WEBHOOK_WORKDIR' is not a directory!">&2
exit 1
fi# Get TOKENS, if the DU_TOKEN or HARDLINK_TOKEN is defined that is used, if# not if the COMMON_TOKEN that is used and in other case no token is checked# (that is the default)DU_TOKEN="$ DU_TOKEN:-$COMMON_TOKEN"HARDLINK_TOKEN="$ HARDLINK_TOKEN:-$COMMON_TOKEN"S3_TOKEN="$ S3_TOKEN:-$COMMON_TOKEN"# Create webhook configuration
print_du_yml
print_token_yml "$DU_TOKEN"echo""
print_hardlink_yml
print_token_yml "$HARDLINK_TOKEN"echo""
print_s3sync_yml
print_token_yml "$S3_TOKEN" >"$WEBHOOK_YML"# Run the webhook command# shellcheck disable=SC2086exec webhook -hooks"$WEBHOOK_YML"$WEBHOOK_OPTS# ----# MAIN# ----case"$1"in"server") exec_webhook ;;*)exec"$@";;esac
The entrypoint.sh script generates the configuration file for the webhook
server calling functions that print a yaml section for each hook and
optionally adds rules to validate access to them comparing the value of a
X-Webhook-Token header against predefined values.
The expected token values are taken from environment variables, we can define
a token variable for each hook (DU_TOKEN, HARDLINK_TOKEN or S3_TOKEN)
and a fallback value (COMMON_TOKEN); if no token variable is defined for a
hook no check is done and everybody can call it.
The Hook
Definition documentation explains the options you can use for each hook, the
ones we have right now do the following:
du: runs on the $WORKDIR directory, passes as first argument to the
script the value of the path query parameter and sets the variable
OUTPUT_FORMAT to the fixed value json (we use that to print the output of
the script in JSON format instead of text).
hardlink: runs on the $WORKDIR directory and takes no parameters.
s3sync: runs on the $WORKDIR directory and sets a lot of environment
variables from values read from the JSON encoded payload sent by the caller
(all the values must be sent by the caller even if they are assigned an empty
value, if they are missing the hook fails without calling the script); we
also set the stream-command-output value to true to make the script show
its output as it is working (we patched the webhook source to be able to
use this option).
The du hook scriptThe du hook script code checks if the argument passed is a directory,
computes its size using the du command and prints the results in text format
or as a JSON dictionary:
hooks/du.sh
#!/bin/shset-e# Script to print disk usage for a PATH inside the scs folder# ---------# FUNCTIONS# ---------
print_error()if["$OUTPUT_FORMAT"="json"];then
echo" \"error\":\"$*\" "else
echo"$*">&2
fi
exit 1
usage()if["$OUTPUT_FORMAT"="json"];then
echo" \"error\":\"Pass arguments as '?path=XXX\" "else
echo"Usage: $(basename"$0") PATH">&2
fi
exit 1
# ----# MAIN# ----if["$#"-eq"0"][-z"$1"];then
usage
fi
if["$1"="."];then
DU_PATH="./"else
DU_PATH="$(find .-name"$1"-mindepth 1 -maxdepth 1)"true
fi
if[-z"$DU_PATH"][!-d"$DU_PATH/."];then
print_error "The provided PATH ('$1') is not a directory"fi# Print disk usage in bytes for the given PATHOUTPUT="$(du-b-s"$DU_PATH")"if["$OUTPUT_FORMAT"="json"];then# Format output as "path":"PATH","bytes":"BYTES" echo"$OUTPUT"sed-e"s%^\(.*\)\t.*/\(.*\)$%\"path\":\"\2\",\"bytes\":\"\1\" %"tr-d'\n'else# Print du output as isecho"$OUTPUT"fi# vim: ts=2:sw=2:et:ai:sts=2
The hardlink hook scriptThe hardlink hook script is really simple, it just runs the
util-linux version of the
hardlink
command on its working directory:
hooks/hardlink.sh
#!/bin/sh
hardlink --ignore-time--maximize .
We use that to reduce the size of the stored content; to manage versions of
files and folders we keep each version on a separate directory and when one or
more files are not changed this script makes them hardlinks to the same file on
disc, reducing the space used on disk.
The s3sync hook scriptThe s3sync hook script uses the s3fs
tool to mount a bucket and synchronise data between a folder inside the bucket
and a directory on the filesystem using rsync; all values needed to execute
the task are taken from environment variables:
hooks/s3sync.sh
#!/bin/ashset-euo pipefail
set-o errexit
set-o errtrace
# Functions
finish()ret="$1"echo""echo"Script exit code: $ret"exit"$ret"# Check variablesif[-z"$AWS_KEY"][-z"$AWS_SECRET_KEY"][-z"$S3_BUCKET"][-z"$S3_PATH"][-z"$SCS_PATH"];then["$AWS_KEY"]echo"Set the AWS_KEY environment variable"["$AWS_SECRET_KEY"]echo"Set the AWS_SECRET_KEY environment variable"["$S3_BUCKET"]echo"Set the S3_BUCKET environment variable"["$S3_PATH"]echo"Set the S3_PATH environment variable"["$SCS_PATH"]echo"Set the SCS_PATH environment variable"
finish 1
fi
if["$S3_REGION"]&&["$S3_REGION"!="us-east-1"];then
EP_URL="endpoint=$S3_REGION,url=https://s3.$S3_REGION.amazonaws.com"else
EP_URL="endpoint=us-east-1"fi# Prepare working directoryWORK_DIR="$(mktemp-p"$HOME"-d)"MNT_POINT="$WORK_DIR/s3data"PASSWD_S3FS="$WORK_DIR/.passwd-s3fs"# Check the moutpointif[!-d"$MNT_POINT"];then
mkdir-p"$MNT_POINT"elif mountpoint "$MNT_POINT";then
echo"There is already something mounted on '$MNT_POINT', aborting!"
finish 1
fi# Create password filetouch"$PASSWD_S3FS"chmod 0400 "$PASSWD_S3FS"echo"$AWS_KEY:$AWS_SECRET_KEY">"$PASSWD_S3FS"# Mount s3 bucket as a filesystem
s3fs -odbglevel=info,retries=5 -o"$EP_URL"-o"passwd_file=$PASSWD_S3FS"\"$S3_BUCKET""$MNT_POINT"echo"Mounted bucket '$S3_BUCKET' on '$MNT_POINT'"# Remove the password file, just in caserm-f"$PASSWD_S3FS"# Check source PATHret="0"SRC_PATH="$MNT_POINT/$S3_PATH"if[!-d"$SRC_PATH"];then
echo"The S3_PATH '$S3_PATH' can't be found!"ret=1
fi# Compute SCS_UID & SCS_GID (by default based on the working directory owner)SCS_UID="$ SCS_UID:=$(stat-c"%u""." 2>/dev/null)"true
SCS_GID="$ SCS_GID:=$(stat-c"%g""." 2>/dev/null)"true# Check destination PATHDST_PATH="./$SCS_PATH"if["$ret"-eq"0"]&&[-d"$DST_PATH"];then
mkdir-p"$DST_PATH"ret="$?"fi# Copy using rsyncif["$ret"-eq"0"];then
rsync -rlptv--chown="$SCS_UID:$SCS_GID"--delete--stats\"$SRC_PATH/""$DST_PATH/"ret="$?"fi# Unmount the S3 bucket
umount -f"$MNT_POINT"echo"Called umount for '$MNT_POINT'"# Remove mount point dirrmdir"$MNT_POINT"# Remove WORK_DIRrmdir"$WORK_DIR"# We are done
finish "$ret"# vim: ts=2:sw=2:et:ai:sts=2
Deployment objectsThe system is deployed as a StatefulSet with one replica.
Our production deployment is done on AWS and to be
able to scale we use EFS for our
PersistenVolume; the idea is that the volume has no size limit, its
AccessMode can be set to ReadWriteMany and we can mount it from multiple
instances of the Pod without issues, even if they are in different availability
zones.
For development we use k3d and we are also able to scale the
StatefulSet for testing because we use a ReadWriteOnce PVC, but it points
to a hostPath that is backed up by a folder that is mounted on all the
compute nodes, so in reality Pods in different k3d nodes use the same folder
on the host.
secrets.yamlThe secrets file contains the files used by the mysecureshell container that
can be generated using kubernetes pods as follows (we are only creating the
scs user):
$kubectl run "mysecureshell"--restart='Never'--quiet--rm--stdin\ --image "stodh/mysecureshell:latest" -- gen-host-keys >"./host_keys.txt"$kubectl run "mysecureshell"--restart='Never'--quiet--rm--stdin\ --image "stodh/mysecureshell:latest" -- gen-users-tar scs >"./users.tar"
Once we have the files we can generate the secrets.yaml file as follows:
On this definition we don t set the storageClassName to use the default one.
Volumes in our development environment (k3d)In our development deployment we create the following PersistentVolume as
required by the
Local
Persistence Volume Static Provisioner (note that the /volumes/scs-pv has to
be created by hand, in our k3d system we mount the same host directory on the
/volumes path of all the nodes and create the scs-pv directory by hand
before deploying the persistent volume):
k3d-pv.yaml
Volumes in our production environment (aws)In the production deployment we don t create the PersistentVolume (we are
using the
aws-efs-csi-driver which
supports Dynamic Provisioning) but we add the storageClassName (we set it
to the one mapped to the EFS driver, i.e. efs-sc) and set ReadWriteMany
as the accessMode:
efs-pvc.yaml
nginx: As this is an example the web server is not using an
AUTH_REQUEST_URI and uses the /sftp/data directory as the root of the web
(to get to the files uploaded for the scs user we will need to use /scs/
as a prefix on the URLs).
mysecureshell: We are adding the IPC_OWNER capability to the container to
be able to use some of the sftp-* commands inside it, but they are
not really needed, so adding the capability is optional.
webhook: We are launching this container in privileged mode to be able to
use the s3fs-fuse, as it will not work otherwise for now (see this
kubernetes issue); if
the functionality is not needed the container can be executed with regular
privileges; besides, as we are not enabling public access to this service we
don t define *_TOKEN variables (if required the values should be read from a
Secret object).
Notes about the volumes:
the devfuse volume is only needed if we plan to use the s3fs command on
the webhook container, if not we can remove the volume definition and its
mounts.
service.yamlTo be able to access the different services on the statefulset we publish the
relevant ports using the following Service object:
service.yaml
ingress.yamlTo download the scs files from the outside we can add an ingress object like
the following (the definition is for testing using the localhost name):
DeploymentTo deploy the statefulSet we create a namespace and apply the object
definitions shown before:
$kubectl create namespace scs-demo
namespace/scs-demo created
$kubectl -n scs-demo apply -f secrets.yaml
secret/scs-secrets created
$kubectl -n scs-demo apply -f pvc.yaml
persistentvolumeclaim/scs-pvc created
$kubectl -n scs-demo apply -f statefulset.yaml
statefulset.apps/scs created
$kubectl -n scs-demo apply -f service.yaml
service/scs-svc created
$kubectl -n scs-demo apply -f ingress.yaml
ingress.networking.k8s.io/scs-ingress created
Once the objects are deployed we can check that all is working using kubectl:
$kubectl -n scs-demo get all,secrets,ingress
NAME READY STATUS RESTARTS AGE
pod/scs-0 3/3 Running 0 24s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/scs-svc ClusterIP 10.43.0.47 <none>22/TCP,80/TCP,9000/TCP 21s
NAME READY AGE
statefulset.apps/scs 1/1 24s
NAME TYPE DATA AGE
secret/default-token-mwcd7 kubernetes.io/service-account-token 3 53s
secret/scs-secrets Opaque 3 39s
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/scs-ingress nginx localhost 172.21.0.5 80 17s
At this point we are ready to use the system.
Usage examples
File uploadsAs previously mentioned in our system the idea is to use the sftp server from
other Pods, but to test the system we are going to do a kubectl port-forward
and connect to the server using our host client and the password we have
generated (it is on the user_pass.txt file, inside the users.tar archive):
$kubectl -n scs-demo port-forward service/scs-svc 2020:22 &
Forwarding from 127.0.0.1:2020 ->22
Forwarding from [::1]:2020 ->22
$PF_PID=$!$sftp -P 2020 scs@127.0.0.1 1
Handling connection for 2020
The authenticity of host '[127.0.0.1]:2020 ([127.0.0.1]:2020)' can't be \
established.
ED25519 key fingerprint is SHA256:eHNwCnyLcSSuVXXiLKeGraw0FT/4Bb/yjfqTstt+088.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[127.0.0.1]:2020' (ED25519) to the list of known \
hosts.
scs@127.0.0.1's password: **********
Connected to 127.0.0.1.
sftp>ls-ladrwxr-xr-x 2 sftp sftp 4096 Sep 25 14:47 .
dr-xr-xr-x 3 sftp sftp 4096 Sep 25 14:36 ..
sftp>!date-R> /tmp/date.txt 2
sftp>put /tmp/date.txt .Uploading /tmp/date.txt to /date.txt
date.txt 100% 32 27.8KB/s 00:00
sftp>ls-l-rw-r--r-- 1 sftp sftp 32 Sep 25 15:21 date.txt
sftp>ln date.txt date.txt.1 3
sftp>ls-l-rw-r--r-- 2 sftp sftp 32 Sep 25 15:21 date.txt
-rw-r--r-- 2 sftp sftp 32 Sep 25 15:21 date.txt.1
sftp>put /tmp/date.txt date.txt.2 4
Uploading /tmp/date.txt to /date.txt.2
date.txt 100% 32 27.8KB/s 00:00
sftp>ls-l5
-rw-r--r-- 2 sftp sftp 32 Sep 25 15:21 date.txt
-rw-r--r-- 2 sftp sftp 32 Sep 25 15:21 date.txt.1
-rw-r--r-- 1 sftp sftp 32 Sep 25 15:21 date.txt.2
sftp>exit$kill"$PF_PID"[1] + terminated kubectl -n scs-demo port-forward service/scs-svc 2020:22
We connect to the sftp service on the forwarded port with the scs user.
We put a file we have created on the host on the directory.
We do a hard link of the uploaded file.
We put a second copy of the file we created locally.
On the file list we can see that the two first files have two hardlinks
File retrievalsIf our ingress is configured right we can download the date.txt file from the
URL http://localhost/scs/date.txt:
Use of the webhook containerTo finish this post we are going to show how we can call the hooks directly,
from a CronJob and from a Job.
Direct script call (du)In our deployment the direct calls are done from other Pods, to simulate it we
are going to do a port-forward and call the script with an existing PATH (the
root directory) and a bad one:
$kubectl -n scs-demo port-forward service/scs-svc 9000:9000 >/dev/null &
$PF_PID=$!$JSON="$(curl -s"http://localhost:9000/hooks/du?path=.")"$echo$JSON "path":"","bytes":"4160"
$JSON="$(curl -s"http://localhost:9000/hooks/du?path=foo")"$echo$JSON "error":"The provided PATH ('foo') is not a directory"
$kill$PF_PID
As we only have files on the base directory we print the disk usage of the .
PATH and the output is in json format because we export OUTPUT_FORMAT with
the value json on the webhook configuration.
Cronjobs (hardlink)As explained before, the webhook container can be used to run cronjobs; the
following one uses an alpine container to call the hardlink script each
minute (that setup is for testing, obviously):
webhook-cronjob.yaml
The following console session shows how we create the object, allow a couple of
executions and remove it (in production we keep it running but once a day, not
each minute):
$kubectl -n scs-demo apply -f webhook-cronjob.yaml 1
cronjob.batch/hardlink created
$kubectl -n scs-demo get pods -l"cronjob=hardlink"-w2
NAME READY STATUS RESTARTS AGE
hardlink-27735351-zvpnb 0/1 Pending 0 0s
hardlink-27735351-zvpnb 0/1 ContainerCreating 0 0s
hardlink-27735351-zvpnb 0/1 Completed 0 2s
^C
$kubectl -n scs-demo logs pod/hardlink-27735351-zvpnb 3
Mode: real
Method: sha256
Files: 3
Linked: 1 files
Compared: 0 xattrs
Compared: 1 files
Saved: 32 B
Duration: 0.000220 seconds
$sleep 60
$kubectl -n scs-demo get pods -l"cronjob=hardlink"4
NAME READY STATUS RESTARTS AGE
hardlink-27735351-zvpnb 0/1 Completed 0 83s
hardlink-27735352-br5rn 0/1 Completed 0 23s
$kubectl -n scs-demo logs pod/hardlink-27735352-br5rn 5
Mode: real
Method: sha256
Files: 3
Linked: 0 files
Compared: 0 xattrs
Compared: 0 files
Saved: 0 B
Duration: 0.000070 seconds
$kubectl -n scs-demo delete -f webhook-cronjob.yaml 6
cronjob.batch "hardlink" deleted
This command creates the cronjob object.
This checks the pods with our cronjob label, we interrupt it once we see
that the first run has been completed.
With this command we see the output of the execution, as this is the fist
execution we see that date.txt.2 has been replaced by a hardlink (the
summary does not name the file, but it is the only option knowing the
contents from the original upload).
After waiting a little bit we check the pods executed again to get the name
of the latest one.
The log now shows that nothing was done.
As this is a demo, we delete the cronjob.
Jobs (s3sync)The following job can be used to synchronise the contents of a directory in a
S3 bucket with the SCS Filesystem:
job.yaml
Once we have both files we can run the Job as follows:
$kubectl -n scs-demo create secret generic webhook-job-secrets \ 1
--from-file="s3sync.json=s3sync.json"
secret/webhook-job-secrets created
$kubectl -n scs-demo apply -f webhook-job.yaml 2
job.batch/s3sync created
$kubectl -n scs-demo get pods -l"cronjob=s3sync"3
NAME READY STATUS RESTARTS AGE
s3sync-zx2cj 0/1 Completed 0 12s
$kubectl -n scs-demo logs s3sync-zx2cj 4
Mounted bucket 's3fs-test' on '/root/tmp.jiOjaF/s3data'
sending incremental file list
created directory ./test
./
kyso.png
Number of files: 2 (reg: 1, dir: 1)
Number of created files: 2 (reg: 1, dir: 1)
Number of deleted files: 0
Number of regular files transferred: 1
Total file size: 15,075 bytes
Total transferred file size: 15,075 bytes
Literal data: 15,075 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.147 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 15,183
Total bytes received: 74
sent 15,183 bytes received 74 bytes 30,514.00 bytes/sec
total size is 15,075 speedup is 0.99
Called umount for '/root/tmp.jiOjaF/s3data'
Script exit code: 0
$kubectl -n scs-demo delete -f webhook-job.yaml 5
job.batch "s3sync" deleted
$kubectl -n scs-demo delete secrets webhook-job-secrets 6
secret "webhook-job-secrets" deleted
Here we create the webhook-job-secrets secret that contains the
s3sync.json file.
This command runs the job.
Checking the label cronjob=s3sync we get the Pods executed by the job.
Here we print the logs of the completed job.
Once we are finished we remove the Job.
And also the secret.
Final remarksThis post has been longer than I expected, but I believe it can be useful for
someone; in any case, next time I ll try to explain something shorter or will
split it into multiple entries.
Rama II
This would be more of a short post about the current book I am reading. Now people who have seen Arrival would probably be more at home. People who have also seen Avatar would also be familiar to the theme or concept I am sharing about. Now before I go into detail, it seems that Arthur C. Clarke wanted to use a powerful god or mythological character for the name and that is somehow the RAMA series started.
Now the first book in the series explores an extraterrestrial spaceship that earth people see/connect with. The spaceship is going somewhere and is doing an Earth flyby so humans don t have much time to explore the spaceship and it is difficult to figure out how the spaceship worked. The spaceship is around 40 km. long. They don t meet any living Ramans but mostly automated systems and something called biots.
As I m still reading it, I can t really say what happens next. Although in Rama or Rama I, the powers that be want to destroy it while in the end last they don t. Whether they could have destroyed it or not would be whole another argument. What people need to realize is that the book is a giant What IF scenario.
Aliens
If there were any intelligent life in the Universe, I don t think they will take the pain of visiting Earth. And the reasons are far more mundane than anything else. Look at how we treat each other. One of the largest democracies on Earth, The U.S. has been so divided. While the progressives have made some good policies, the Republicans are into political stunts, consider the political stunt of sending Refugees to Martha s Vineyard. The ex-president also made a statement that he can declassify anything just by thinking about it. Now understand this, a refugee is a legal migrant whose papers would be looked into by the American Govt. and till the time he/she/their application is approved or declined they can work, have a house, or do whatever to support themselves. There is a huge difference between having refugee status and being an undocumented migrant. And it isn t as if the Republicans don t know this, they did it because they thought they will be able to get away with it.
Both the above episodes don t throw us in a good light. If we treat others like the above, how can we expect to be treated? And refugees always have a hard time, not just in the U.S, , the UK you name it. The UK just some months ago announced a controversial deal where they will send Refugees to Rwanda while their refugee application is accepted or denied, most of them would be denied.
The Indian Government is more of the same. A friend, a casual acquaintance Nishant Shah shared the same issues as I had shared a few weeks back even though he s an NRI. So, it seems we are incapable of helping ourselves as well as helping others. On top of it, we have the temerity of using the word alien for them.
Now, just for a moment, imagine you are an intelligent life form. An intelligent life-form that could coax energy from the stars, why would you come to Earth, where the people at large have already destroyed more than half of the atmosphere and still arguing about it with the other half. On top of it, we see a list of authoritarian figures like Putin, Xi Jinping whose whole idea is to hold on to power for as long as they can, damn the consequences. Mr. Modi is no different, he is the dumbest of the lot and that s saying something. Most of the projects made by him are in disarray, Pune Metro, my city giving an example. And this is when Pune was the first applicant to apply for a Metro. Just like the UK, India too has tanked the economy under his guidance. Every time they come closer to target dates, the targets are put far into the future, for e.g. now they have said 2040 for a good economy. And just like in other countries, he has some following even though he has a record of failure in every sector of the economy, education, and defense, the list is endless. There isn t a single accomplishment by him other than screwing with other religions. Most of my countrymen also don t really care or have a bother to see how the economy grows and how exports play a crucial part otherwise they would be more alert. Also, just like the UK, India too gave tax cuts to the wealthy, most people don t understand how economies function and the PM doesn t care. The media too is subservient and because nobody asks the questions, nobody seems to be accountable :(.
Religion
There is another aspect that also has been to the fore, just like in medieval times, I see a great fervor for religion happening here, especially since the pandemic and people are much more insecure than ever before. Before, I used to think that insecurity and religious appeal only happen in the uneducated, and I was wrong. I have friends who are highly educated and yet still are blinded by religion. In many such cases or situations, I find their faith to be a sham. If you have faith, then there shouldn t be any room for doubt or insecurity. And if you are not in doubt or insecure, you won t need to talk about your religion. The difference between the two is that a person is satiated himself/herself/themselves with thirst and hunger. That person would be in a relaxed mode while the other person would continue to create drama as there is no peace in their heart.
Another fact is none of the major religions, whether it is Christianity, Islam, Buddhism or even Hinduism has allowed for the existence of extraterrestrials. We have already labeled them as aliens even before meeting them & just our imagination. And more often than not, we end up killing them. There are and have been scores of movies that have explored the idea. Independence day, Aliens, Arrival, the list goes on and on. And because our religions have never thought about the idea of ET s and how they will affect us, if ET s do come, all the religions and religious practices would panic and die. That is the possibility why even the 1947 Roswell Incident has been covered up .
If the above was not enough, the bombing of Hiroshima and Nagasaki by the Americans would always be a black mark against humanity. From the alien perspective, if you look at the technology that they have vis-a-vis what we have, they will probably think of us as spoilt babies and they wouldn t be wrong. Spoilt babies with nuclear weapons are not exactly a healthy mix
Earth
To add to our fragile ego, we didn t even leave earth even though we have made sure we exploit it as much as we can. We even made the anthropocentric or homocentric view that makes man the apex animal and to top it we have this weird idea that extraterrestrials come here or will invade for water. A species that knows how to get energy out of stars but cannot make a little of H2O. The idea belies logic and again has been done to death. Why we as humans are so insecure even though we have been given so much I fail to understand. I have shared on numerous times the Kardeshev Scale on this blog itself.
The above are some of the reasons why Arthur C. Clarke s works are so controversial and this is when I haven t even read the whole book. It forces us to ask questions that we normally would never think about. And I have to repeat that when these books were published for the first time, they were new ideas. All the movies, from Stanley Kubrick s 2001: Space Odyssey, Aliens, Arrival, and Avatar, somewhere or the other reference some aspect of this work. It is highly possible that I may read and re-read the book couple of times before beginning the next one. There is also quite a bit of human drama, but then that is to be expected. I have to admit I did have some nice dreams after reading just the first few pages, imagining being given the opportunity to experience an Extraterrestrial spaceship that is beyond our wildest dreams. While the Governments may try to cover up or something, the ones who get to experience that spacecraft would be unimaginable. And if they were able to share the pictures or a Livestream, it would be nothing short of amazing.
For those who want to, there is a lot going on with the New James Webb Telescope. I am sure it would give rise to more questions than answers.
Back in 2018, I made a two part series about terminal emulators
that was actually pretty painful to write. So I'm not going to retry
this here, not at all. Especially since I'm not submitting this to the
excellent LWN editors so I can get away with not being very good
at writing. Phew.
Still, it seems my future self will thank me for collecting my
thoughts on the terminal emulators I have found out about since I
wrote that article. Back then, Wayland was not quite at the level
where it is now, being the default in Fedora (2016), Debian (2019),
RedHat (2019), and Ubuntu (2021). Also, a bunch of folks thought they
would solve everything by using OpenGL for rendering. Let's see how
things stack up.
Recap
In the previous article, I touched on those projects:
After writing those articles, bizarrely, I was still using rxvt even
though it did not come up as shiny as I would have liked. The colors
problems were especially irritating.
I briefly played around with Konsole and xterm, and eventually
switched to XTerm as my default x-terminal-emulator "alternative" in
my Debian system, while writing this.
I quickly noticed why I had stopped using it: clickable links are a
huge limitation. I ended up adding keybindings to open URLs in a
command. There's another keybinding to dump the history into a
command. Neither are as satisfactory as just clicking a damn link.
Requirements
Figuring out my requirements is actually a pretty hard thing to do. In
my last reviews, I just tried a bunch of stuff and collected
everything, but a lot of things (like tab support) I don't actually
care about. So here's a set of things I actually do care about:
latency
resource usage
proper clipboard support, that is:
mouse selection and middle button uses PRIMARY
control-shift-c and control-shift-v for
CLIPBOARD
true color support
no known security issues
active project
paste protection
clickable URLs
scrollback
font resize
non-destructive text-wrapping (ie. resizing a window doesn't drop
scrollback history)
proper unicode support (at least latin-1, ideally "everything")
good emoji support (at least showing them, ideally "nicely"), which
involves font fallback
Kitty
Kitty is a "fast, feature-rich, GPU based", with ligatures,
emojis, hyperlinks, pluggable, scriptable, tabs, layouts, history,
file transfer over SSH, its own graphics system, and probably much
more I'm forgetting. It's packaged in Debian.
So I immediately got two people commenting (on IRC) that they use
Kitty and are pretty happy with it. I've been hesitant in directly
talking about Kitty publicly, but since it's likely there will be a
pile-up of similar comments, I'll just say why it's not the first in
my list, even if it might, considering it's packaged in Debian and
otherwise checks all the boxes.
I don't trust the Kitty code. Kitty was written by the same author as
Calibre, which has a horrible security history and generally really
messy source code. I have tried to do LTS work on Calibre, and have
mostly given up on the idea of making that program secure in any
way. See calibre for the details on that.
Now it's possible Kitty is different: it's quite likely the author has
gotten some experience writing (and maintaining for so long!) Calibre
over the years. But I would be more optimistic if the author's
reaction to the security issues were more open and proactive.
I've also seen the same reaction play out on Kitty's side of
things. As anyone who worked on writing or playing with non-XTerm
terminal emulators, it's quite a struggle to make something
(bug-for-bug) compatible with everything out there. And Kitty is in
that uncomfortable place right now where it diverges from the canon
and needs its own entry in the ncurses database. I don't remember the
specifics, but the author also managed to get into fights with those
people as well, which I don't feel is reassuring for the project going
forward.
If security and compatibility wasn't such big of a deal for me, I
wouldn't mind so much, but I'll need a lot of convincing before I
consider Kitty more seriously at this point.
Next steps
It seems like Arch Linux defaults to foot in Sway, and I keep seeing
it everywhere, so it is probably my next thing to try, if/when I
switch to Wayland.
One major problem with foot is that it's yet another terminfo
entry. They did make it into ncurses (patch 2021-07-31) but only
after Debian bullseye stable was released. So expect some weird
compatibility issues when connecting to any other system that is older
or the same as stable (!).
One question mark with all Wayland terminals, and Foot in particular,
is how much latency they introduce in the rendering pipeline. The
foot performance and benchmarks look excellent, but do not
include latency benchmarks.
No conclusion
So I guess that's all I've got so far, I may try alacritty if it hits
Debian, or foot if I switch to Wayland, but for now I'm hacking in
xterm still. Happy to hear ideas in the comments.
Stay tuned for more happy days.
Fiction
A few days ago somebody asked me and I think it is an often requested to perhaps all fiction readers as to why we like fiction? First of all, reading in itself is told as food for the soul. Because, whenever you write or read anything you don t just read it, you also visualize it. And that visualization is and would be far greater than any attempt in cinema as there are no budget constraints and it takes no more than a minute to visualize a scenario if the writer is any good. You just close your eyes and in a moment you are transported to a different world. This is also what is known as world building . Something fantasy writers are especially gifted in. Also, with the whole parallel Universes being a reality, it is just so much fertile land for imagination that I just cannot believe that it hasn t been worked to death to date. And you do need a lot of patience to make a world, to make characters, to make characters a bit eccentric one way or the other. And you have to know to put into a three, five, or whatever number of acts you want to put in. And then, of course, they have readers like us who dream and add more color to the story than the author did. As we take his, her, or their story and weave countless stories depending on where we are, where we are and who we are.
What people need to understand is that not just readers want escapism but writers too want to escape from the human condition. And they find solace in whatever they write. The well-known example of J.R.R. Tolkien is always there. How he must have felt each day coming after war, to somehow find the strength and just dream away, transport himself to a world of hobbits, elves, and other mysterious beings. It surely must have taken a lot of pain from him that otherwise, he would have felt. There are many others. What also does happen now and then, is authors believe in their own intelligence so much, that they commit crimes, but that s par for the course.
Dean Koontz, Odd Apocalypse
Currently, I am reading the above title. It is perhaps one of the first horror title books that I have read which has so much fun. The hero has a great sense of wit, humor, and sarcasm that you can cut butter with it. Now if you got that, this is par for the wordplay happening every second paragraph and I m just 100 pages in of the 500-page Novel.
Now, while I haven t read the whole book and I m just speculating, what if at the end we realize that the hero all along was or is the villain. Sadly, we don t have many such twisted stories and that too is perhaps because most people used to have black and white rather than grey characters. From all my reading, and even watching web series and whatnot, it is only the Europeans who seem to have a taste for exploring grey characters and giving twists at the end that people cannot anticipate. Even their heroes or heroines are grey characters. and they can really take you for a ride. It is also perhaps how we humans are, neither black nor white but more greyish. Having grey characters also frees the author quite a bit as she doesn t have to use so-called tropes and just led the characters to lead themselves.
Indian Book publishing Industry
I do know Bengali stories do have a lot of grey characters, but sadly most of the good works are still in Bengali and not widely published compared to say European or American authors. While there is huge potential in the Indian publishing market for English books and there is also hunger, getting good and cheap publishers is the issue. Just recently SAGE publishing division shut down and this does not augur well for the Indian market. In the past few years, I and other readers have seen some very good publishing houses quit India for one reason or the other. GST has also made the sector more expensive. The only thing that works now and has been for some time is the seconds and thirds market. For e.g. I just bought today about 15-20 books @INR 125/- a kind of belated present for the self. That would be what, at the most 2 USD or 2 Euros per book. I bet even a burger costs more than that, but again India being a price-sensitive market, at these prices the seconds book sells. And these are all my favorite authors, Lee Child, Tom Clancy, Dean Koontz, and so on and so forth. I also saw a lot of fantasy books but they would have to wait for another day.
Tourism in India for Debconf 23
I had shared a while back that I would write a bit about tourism as Debconf or Annual Debian Conference will happen in India next year around this time. I was supposed to write it in the FAQ but couldn t find a place or a corner where I could write it. There are actually two things that people need to be aware of. The one thing that people need to be very aware of is food poisoning or Delhi Belly. This is a far too common sight that I have witnessed especially with westerners when they come to visit India. I am somewhat shocked that it hasn t been shared in the FAQ but then perhaps we cannot cover all the bases therein. I did find this interesting article and would recommend the suggestions given in it wholeheartedly. I would suggest people coming to India to buy and have purifying water tablets with them if they decide to stay back and explore India.
Now the problem with tourism is, that one can have as much tourism as one wants. One of the unique ways I found some westerners having the time of their life is buying an Indian Rickshaw or Tuk-Tuk and traveling with it. A few years ago, when I was more adventourous-spirited I was able to meet a few of them. There is also the Race with Rickshaws that happens in Rajasthan and you get to see about 10 odd cities in and around Rajasthan state and get to see the vibrancy in the North. If somebody really wants to explore India, then I would suggest getting down to Goa, specifically, South Goa, meeting with the hippie crowd, and getting one of the hippie guidebooks to India. Most people forget that the Hippies came to India in the 1960s and many of them just never left. Tap water in Pune is ok, have seen and experienced the same in Himachal, Garwhal, and Uttarakhand, although it has been a few years since I have been to those places. North-East is a place I have yet to venture into.
India does have a lot of beauty but most people are not clean-conscious so if you go to common tourist destinations, you will find a lot of garbage. Most cities in India do give you an option of homestays and some even offer food, so if you are on a budget as well as wanna experience life with an Indian family, that could be something you could look into. So you can see and share about India with different eyes.
There is casteism, racism, and all that. Generally speaking, you would see it wielded a lot more in your face in North India than in South India where it is there but far more subtle. About food, what has been shared in the India BOF. Have to say, it doesn t even scratch the surface. If you stay with an Indian family, there is probably a much better chance of exploring the variety of food that India has to offer. From the western perspective, we tend to overcook stuff and make food with Masalas but that s the way most people like it. People who have had hot sauces or whatnot would probably find India much easier to adjust to as tastes might be similar to some extent.
If you want to socialize with young people, while discos are an option, meetup.com also is a good place. You can share your passions and many people have taken to it with gusto. We also have been hosting Comiccons in India, but I haven t had the opportunity to attend them so far. India has a rich oral culture reach going back a few thousand years, but many of those who are practicing those reside more in villages rather than in cities. And while there have been attempts in the past to record them, most of those have come to naught as money runs out as there is no commercial viability to such projects, but that probably is for another day.
In the end, what I have shared is barely a drop in the ocean that is India. Come, have fun, explore, enjoy and invigorate yourself and others
In June I caved and bought a Prusa
Mini
3D printer for home. I bought it just before an announced price hike. I went
for a Prusa because of their reputation for "just working", and the Mini mostly
as its the cheapest, although, the print area (7" ) is large enough for most of
the things I am likely to print.
To get started, at the same time I bought some Prusament recycled
PLA to print
with which, unfortunately, I've been a little disappointed with.
I was attracted to the idea of buying a recycled material and Prusa make a lot
about the quality of their filaments.
The description was pretty clear that the colour would be somewhat random and
vary throughout the spool, but I didn't mind that, and I planned to use it for
mainly functional prints where the precise colour didn't matter. The colour
examples from the product page were mostly off-white grey with some tint,
typically green. There are not a lot of reviews of the recycled PLA that
comment on the colour of their spools, but in a couple of youtube videos
(1,
2) the spools have looked a
grey-ish silver, sometimes with a greenish tint, pretty similar to the product
page.
The colour I got is quite unlike those: it's a dull brown, with little flecks
of glitter, presumably originally from recycling something like Galaxy
Black.
That's totally within "spec", of course, but it's a bit boring.
Brown recycled Prusament PLA on the right
In terms of quality, sadly I've ended up with had at least one tangle in the
spool wind so far. There's at least two reviews on their own product page from
people who have had similar difficulties.
Edit:
I realised after I wrote this post that I hadn't actually
written much about the printer. That's because I'm still in the early days of
using it. In short I'd say it's a very high quality machine, very pleasant to
use. Since I also went on a tangent about the recycled Prusament, the tone of
the whole post was more negative than I intended. Watch this space for some
more positive Prusa news soon!
Here are the slides I presented for FRnOG #36 in September 2022.
They are about Akvorado, a tool to collect network flows and
visualize them. It was developped by Free. I didn t get time to
publish a blog post yet, but it should happen soon!
More ICFP-inspired experiments using the rec-def library: In Norman Ramsey s very nice talk about his Functional Pearl Beyond Relooper: Recursive Translation of Unstructured Control Flow to Structured Control Flow , he had the following slide showing the equation for the dominators of a node in a graph:
Norman Ramsey shows a formula
He said it s ICFP and I wanted to say the dominance relation has a beautiful set of equations you can read all these algorithms how to compute this, but the concept is simple .
This made me wonder: If the concept is simple and this formula is beautiful shouldn t this be sufficient for the Haskell programmer to obtain the dominator relation, without reading all those algorithms?
Before we start, we have to clarify the formula a bit: If a node is an entry node (no predecessors) then the big intersection is over the empty set, and that is not a well-defined concept. For these nodes, we need that big intersection to return the empty set, as entry nodes are not dominated by any other node. (Let s assume that the entry nodes are exactly those with no predecessors.)
Let s try, first using plain Haskell data structures. We begin by implementing this big intersection operator on Data.Set, and also a function to find the predecessors of a node in a graph:
At this week s International Conference on Functional Programming I showed my rec-def Haskell library to a few people. As this crowd appreciates writing compilers, and example from the realm of program analysis is quite compelling.
To Throw or not to throw
Here is our little toy language to analyze: It has variables, lambdas and applications, non-recursive (lazy) let bindings and, so that we have something to analyze, a way to throw and to catch exceptions: