This allows our Concourse CI to pull the new multi-platform OCI Docker
images instead of pulling very stale, old Docker images.
Fixes, from <https://ci.nono.io/teams/main/pipelines/sslip.io/jobs/unit/builds/97>:
```
Ginkgo detected a version mismatch between the Ginkgo CLI and the version of Ginkgo imported by your packages:
Ginkgo CLI Version:
2.5.0
Mismatched package versions found:
2.8.4 used by sslip.io-dns-server, xip
```
...instead of latest release. This happens, for example, if I didn't fix
the specs before rolling out a new release. I may change this back in
the future.
We are no longer doing key-value-over-DNS.
Fixes <https://ci.nono.io/teams/main/pipelines/sslip.io/jobs/dns-servers/builds/1097>
```
rspec './spec/check-dns_spec.rb[1:17:1]' # sslip.io k-v.io tested on the ns-aws.sslip.io. nameserver sets a value, 1678804743, on the key sslipio-spec.k-v.io
rspec './spec/check-dns_spec.rb[1:17:2]' # sslip.io k-v.io tested on the ns-aws.sslip.io. nameserver gets the newly-set value, 1678804743, from the key, sslipio-spec.k-v.io
rspec './spec/check-dns_spec.rb[1:33:1]' # sslip.io k-v.io tested on the ns-azure.sslip.io. nameserver sets a value, 1678804743, on the key sslipio-spec.k-v.io
rspec './spec/check-dns_spec.rb[1:33:2]' # sslip.io k-v.io tested on the ns-azure.sslip.io. nameserver gets the newly-set value, 1678804743, from the key, sslipio-spec.k-v.io
rspec './spec/check-dns_spec.rb[1:49:1]' # sslip.io k-v.io tested on the ns-gce.sslip.io. nameserver sets a value, 1678804743, on the key sslipio-spec.k-v.io
rspec './spec/check-dns_spec.rb[1:49:2]' # sslip.io k-v.io tested on the ns-gce.sslip.io. nameserver gets the newly-set value, 1678804743, from the key, sslipio-spec.k-v.io
```
Fixes, `fly trigger-job ...`:
```
error: resource not found
```
Fixes, `kubectl logs ...`:
```
flag provided but not defined: -etcdHost
Usage of /usr/sbin/sslip.io-dns-server:
```
I'm disabling the key-value store because no one was using it.
There are other reasons, too:
- The removal of the `etcd` library dropped the executable size by over
half from 17MB to 7MB
- I didn't want users who've deployed it internally to be "surprised" by
unexpected key-value features
- Key-value-over-DNS has a seamy side to it: "data exfiltration". I know
there are legitimate uses for it, but I've come to believe that a
Key-value-over-HTTP solution is preferable because it's not only more
legitimate but also because it eliminates the DNS caching problem.
From
<https://support.google.com/analytics/answer/10759417>:
> Google Analytics 4 is replacing Universal Analytics. On July 1, 2023
all standard Universal Analytics properties will stop processing new
hits.
I wonder if Google Analytics is worth the trouble.
Our CI sometimes builds "broken" docker images because it fails
downloading the proper executable (because I haven't populated the
GitHub release yet).
I'd like it to fail rather than publish broken images.
Fixes, during `docker run -it --rm cunnie/sslip.io-dns-server`:
```
exec /usr/sbin/sslip.io-dns-server: exec format error
```
In spite of good intentions, I never used Max Brunsfeld's Counterfeiter;
Counterfeiter is good for unit tests, but I've pivoted to using mostly
integration tests.
I took the opportunity to update `go.mod`:
```bash
rm go.mod go.sum
go mod init xip
go mod tidy
```
`ENTRYPOINT` [is more appropriate](https://codewithyury.com/docker-run-vs-cmd-vs-entrypoint/):
> ENTRYPOINT configures a container that will run as an executable
Which is exactly how I think the container should work for new people.
Yes, I'm screwing over the existing users. Sorry.
Google Cloud Plaatform (GCP) charged me $17.69 last month for "Cloud
Logging" which consumed 84.74 GiB.
At an average of 51.2 queries/second, and each log line
averaging 192 bytes, and 60*60*24*30 seconds/month, this works out to
25,480,396,800 bytes (23.73 GiB), which works out to a monthly savings of
$4.95 if I use the `-quiet` flag.
However, it seems that my saving would be even more because when I
visually browse the logs, at least ⅔ are from sslip.io logging.
I have *no* idea where all the other logs are coming from.
- Move "Directory Structure" lower down--it's not terribly useful,
certainly less useful than the "DNS Server" section.
- Remove the "tidy" turd at the bottom of the page. It adds no value,
and I'm not sure how it got there in the first place.
- A specific sections for flags such as `-nameservers`
- Add a section about running official Docker containers.
- get rid of the old, deprecated "faq" and "about" pages
[#21]
This change allows me to build new versions of the Docker images without
forcing me to create a gratuitous release merely for that purpose.
In this specific case, I had neglected to have `curl` follow redirects
(`-L`), thus the Docker images created were missing the sslip.io DNS
server.
On the downside, it's possible that the *nginx* Docker containers are
built with content/features that haven't been released yet, but I'm
willing to run that risk.
I had neglected to account for the 302 redirect.
Fixes, during `docker run -it --rm cunnie/sslip.io-dns-server`:
```
exec /usr/sbin/sslip.io-dns-server: exec format error
```
Drive-by: removed a Dockerfile left over from testing the creation of
multi-platform (x86_64, ARM64) Docker images.
Integration tests would fail approximately 11% of the time (4/35) when
run in parallel (on my 8-core MacBook Air). The fix was to lengthen the
amount of time (1ms → 2ms) a port was held to make sure it was really,
truly free. After change, the tests ran 32 times without a failure.
Fixes, during `ginkgo -r -p --until-it-fails .`
```
I couldn't bind to any IPs on port 1974, so I'm exiting
...
Waiting for:
Ready to answer queries
In [JustBeforeEach] at: /Volumes/workspace/sslip.io/src/sslip.io-dns-server/integration_flags_test.go:28 @ 11/11/22 10:38:02.045
```
Previously, when binding to individual IP addrs, the last address bound
is a failure. In that case, it exposes a bug in the code which attempts
to read from a non-functional *UDPConn.
This commit fixes that by only attempting to read after a successful
bind.
Fixes, during start-up:
```
2022/11/11 07:32:44 I couldn't bind to "0.0.0.0:53" (INADDR_ANY, all interfaces), so I'll try to bind to each address individually.
2022/11/11 07:32:44 I bound to the following IPs: "127.0.0.1:53", "[::1]:53", "10.11.0.4:53", "[fc00:11::4]:53"
2022/11/11 07:32:44 I couldn't bind to the following IPs: "fe80::20d:3aff:fec7:4a3"
2022/11/11 07:32:44 Ready to answer queries
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x52e1bd]
goroutine 1 [running]:
net.(*UDPConn).readFromUDP(0x104a880?, {0xc000364800?, 0x0?, 0x4eff80?}, 0xc000080050?)
/opt/homebrew/Cellar/go/1.19.3/libexec/src/net/udpsock.go:146 +0x1d
net.(*UDPConn).ReadFromUDP(...)
/opt/homebrew/Cellar/go/1.19.3/libexec/src/net/udpsock.go:141
main.readFrom(0x0, 0x17?, 0xc00023c200)
/Users/cunnie/workspace/sslip.io/src/sslip.io-dns-server/main.go:94 +0x9f
main.main()
/Users/cunnie/workspace/sslip.io/src/sslip.io-dns-server/main.go:86 +0x645
```
Previously if you wanted to customize the IP addresses, you had to
modify the code. This commit allows you to pass the IP addresses on the
command line, comma-separated, "host=ip", e.g.
```
go run main.go -addresses ns-aws.sslip.io.=52.0.56.137,ns-aws.sslip.io.=2600:1f18:aaf:6900::a,ns-gce.sslip.io.=104.155.144.4
```
This works well in conjunction with the `-nameservers` flag. Indeed, you
could say that this is a pre-requisite of the `-nameservers` flag, for
what is the point of setting a nameserver if you can't set its IP
address?
- The default values for `-addresses` are the originally-hardcoded
values (e.g. sslip.io, ns-aws.sslip.io, k-v.io, etc.)
- Both IPv4 & IPv6 addresses work
- This is mostly tested through integration tests rather than unit
tests; I prefer integration tests in general. They are very assuring.
- A few of the unit tests depended on the hard-coded addresses; I have
removed/modified the tests to accommodate the new behavior
- Today I learned that IPv4 addresses are in the last 4 bytes, not the
first four. Also that IPv4 addresses qualify as IPv6 addresses, so
adjust your code accordingly.
- bump dependencies
- finer-grained testing:
- unit tests are always run against main branch's HEAD
- Docker files, DNS server test are run against the latest tagged
release (which is what's deployed on the production servers)
```shell
go get -u -t
```
Helps address
<https://ci.nono.io/teams/main/pipelines/sslip.io/jobs/unit/builds/39>:
```
Ginkgo detected a version mismatch between the Ginkgo CLI and the version of Ginkgo imported by your packages:
Ginkgo CLI Version:
2.4.0
Mismatched package versions found:
2.1.4 used by sslip.io-dns-server, xip
...
Output from proc 1:
flag provided but not defined: -ginkgo.grace-period
```
...because, hey, I have a Mac, and native is about 10x faster than amd64
emulation. Also because it's cool.
I had to compile my own version of Concourse's
[`registry-image`](https://github.com/concourse/registry-image-resource)
container image because the one shipped with Concourse 7.8.3 is old and
doesn't have the multi-platform feature:
```
docker build --build-arg base_image=ubuntu -t cunnie/registry-image -f dockerfiles/ubuntu/Dockerfile
```
Switch Alpine → Fedora to address weird connection issue:
```
> [linux/arm64 3/3] RUN wget https://github.com/cunnie/sslip.io/releases/download/2.6.0/sslip.io-dns-server-linux-arm64 -O /usr/sbin/sslip.io-dns-server; chmod 755 /usr/sbin/sslip.io-dns-server:
Connecting to github.com (192.30.255.113:443)
wget: error getting response: Connection reset by peer
```
[#21]
If the commit is tagged, then the release is solid, and we can build our
Dockerfiles.
Previously the Dockerfiles were built with every change. Now that I'm
making Dockerfiles first-class citizens ("Official Docker Images"), we
need discipline when building them.
[#21]
This is an admittedly gratuitous commit. I like being on the latest, and
instead of using the builtin Ruby 2.6.8 on macOS, I'd prefer to use the
much newer & sexier Ruby 3.1.2 available from `chruby`.
People may not want my name servers (`ns-gce.sslip.io` et al.), esp. in
an internetless environment where my name servers are unreachable.
This commit addresses this shortcoming by allowing the nameservers to be
set via a new commandline flag (`-nameservers`). We no longer hardcode
our name servers; instead, we make them the default value for the new
flag.
Drive-by: removed an errant `fmt.Println()` in the IPv6 `ip6.arpa` PTR
records.
Finding a free port to bind has always been a thorny problem,
particularly when running parallel tests: parallelism introduces a race
condition where two processes think the same port is free.
This commit improves the behavior by picking the port based on the
millisecond, and furthermore binds to that port for a millisecond to
make sure it's really, truly available.
It also allows a reduction of a 50-millisecond sleep to a 1 millisecond
sleep.
I'm quite proud of this algorithm.
Confession: I have no idea why I didn't use the global variable `port`
instead of deciding to thread `port` as a parameter.
But for some reason I felt that it was a good idea. Oh well. Committing
these changes before they're lost.