Hacker News new | past | comments | ask | show | jobs | submit | joemccall86's comments login

We followed https://whichjdk.com/ and chose Amazon Corretto


I used Obsidian for a while, but for some reason https://silverbullet.md ended up resonating more with me.


I've used https://github.com/vi/websocat in the past and had very good luck with it.


Similar to this, I recently used https://github.com/websockets/wscat to great success.


Thank you both, will check them out!


Not sure if it's the hug of death, but this search generates a 500: https://search.brave.com/search?q=Spring+Boot


Fixed now! Not a hug of death (yet).


Thanks for the report! :) Fix coming


Weird- spring+boots doesn’t


It sounds like you and I are thinking along the same line: https://github.com/joemccall86/cap5600-project2.

I am also taking AI this semester and was considering expanding upon something like this for my masters' capstone project. The application of machine learning to this type of situation is going to be very interesting to say the least.

Just wanted to say good luck!


This will probably get buried, but this story had me shudder at the possibility of being locked out of my 1password vault in a similar scenario. In case anyone is in the same boat:

* My airplane-mode test passed both on my mobile device and browser (1password X).

* The team is aware of the situation with LP and wrote a very thoughtful response: https://discussions.agilebits.com/discussion/comment/544136/...

* From the response above, 1password is SOC2 certified, so availability is taken very seriously.


Works with my media keys too. Nice work!


If you are on a unix system with vim installed, fire up "vimtutor" and learn basic vim usage. At worst you become at least more productive on the de-facto editor installed on most unix systems. Personally I find myself incredibly more productive using vim over most other text editors.


One thing I'm keeping my eye on is the fargate virtual kubelet [1]. It seems to offer a way to use the familiar kubernetes tooling with a managed "clusterless" offering like fargate.

[1] https://github.com/virtual-kubelet/aws-fargate


Why deal with the complexity of one when you can have both!

(/s...)


Looks like a neat concept. Would anyone here with experience managing this in production care to comment? Seems like it could be interesting if you need to reproduce the exact same software/OS on several machines as deliverables.


I've been using Guix in production since 2014 at a research institute to support reproducible bioinformatics workflows. It has come a long way since then.

Guix takes reproducibility and "bootstrappability" very seriously. Its design as an extension to Guile Scheme enabled the development of software built around Guix, such as a workflow language, alternative user interfaces (e.g. an Emacs interface or a web interface), etc.

The `guix system` family of commands is awesome because it can build reproducible containers, disk images, virtual machines, or bare-metal systems all from the same specifications.

What's still missing, in my opinion, is a tool to manage systems that have been generated with Guix, e.g. to check on their state, build new configurations and swap them out for old ones, etc. Some work has been done towards this goal, but there's still some way to go there.

Other than that I'm very happy with it and use Guix systems and Guix as a package manager on all my machines.


How does writing Guix Lisp expressions compare to writing Nix? Is it pretty succinct and intuitive? Do patterns make a little bit better sense?

It took me a long time to get the hang of the Nix design patterns like the three different kinds of overrides and the module system. Curious if it plays better in Lisp.


"succinct" is hard to answer. It depends a lot on the upstream package. For most packages the package expression looks like data:

    (define-public r-valr
      (package
        (name "r-valr")
        (version "0.5.0")
        (source
         (origin
           (method url-fetch)
           (uri (cran-uri "valr" version))
           (sha256
            (base32
             "14jhrwkiwmha3vlmm7b50n2xxyizj6ddmy89gb20mpzq7qhz1ika"))))
        (build-system r-build-system)
        (propagated-inputs
         `(("r-broom" ,r-broom)
           ("r-dplyr" ,r-dplyr)
           ("r-ggplot2" ,r-ggplot2)
           ("r-rcpp" ,r-rcpp)
           ("r-readr" ,r-readr)
           ("r-rlang" ,r-rlang)
           ("r-stringr" ,r-stringr)
           ("r-tibble" ,r-tibble)))
        (home-page "https://github.com/rnabioco/valr")
        (synopsis "Genome interval arithmetic in R")
        (description
         "This package enables you to read and manipulate genome intervals and
    signals.  It provides functionality similar to command-line tool suites within
    R, enabling interactive analysis and visualization of genome-scale data.")
        (license license:expat)))
This defines the name "r-valr" to be a "package" value with the given fields. The "source" field describes how Guix should obtain the source tarball ("url-fetch" is a procedure that implements a URL downloader, but there are others like "git-fetch", "hg-fetch", etc) and what the hash of that data is supposed to be. The "build-system" field tells Guix how to build the thing. "r-build-system" is a very succinct way to say "do with this package as you do for all other R packages: unpack the tarball, run `R CMD bla`, then run the tests, etc". We've got quite a few such build systems: "gnu-build-system", "cmake-build-system", "python-build-system", "ant-build-system", ... All of these can be further configured via the "arguments" package field, which isn't used here, because this is a boring package.

The "propagated-inputs" field is an association list of arbitrary labels to actual package values --- the things on the right hand side are variable names that are bound to package values, which are unquoted here, so this field really contains actual references to these other package values. The result is a lazily constructed graph of package values.

Some packages can be really nasty, though, when the developers decided to ignore conventions and implement their very own way to build their very special software. We can usually accommodate those packages by starting out with e.g. the gnu-build-system and then modifying the build phases: deleting the "configure" phase, adding a custom phase before the "build", replacing the "install" phase, etc. The system is flexible enough for all of this, but for really ... special software I would no longer call this "succinct" or "intuitive".

That said, most packages are easy. Almost all R packages, for example, look like the one above. But there are some really frustrating ones like Tensorflow (due to the fact that we use CMake instead of Bazel because Bazel hasn't been bootstrapped yet) or the old JDKs (that we use as part of a longer bootstrap chain) that are plain ugly. You just need to know when to give up, I suppose :)


> You just need to know when to give up, I suppose :)

Oh gosh I relate to this. I tried to package 3DSlicer for NixOS, which uses a cmake superbuild of dozens of dependent projects, which it fetched during compile and required a very special GCC. I had to give up; it was making me too depressed.

Thank you for sharing how Guix derivations work. It seems very similar semantically to Nix, but I like the build-system method. In nix we have e.g. buildDotnetPackage, buildBazelPackage functions which are overridden, but there's not a clean interface for build systems. I like it.

Is the module system similar to Nix's? Nix modules define imports, config schema and config values, which are merged together to produce an expression for the state of the whole system, e.g. configuration.nix. How's that work in GuixSD?


> Is the module system similar to Nix's? Nix modules define imports, config schema and config values, which are merged together to produce an expression for the state of the whole system, e.g. configuration.nix. How's that work in GuixSD?

The way the Guix system is configured differs a lot from how it's done in NixOS. (Note, though, that I've never used NixOS, so I'll just talk about how it works in Guix.)

First about the term "modules" to avoid confusion: Guix code is organized in Guile modules. A Guile module is a file containing definitions. A module can export variable names. Other modules can use those variable names. That's just like how you'd do "import foo" in Python --- in Guile you do "(use-modules (where foo is))".

This is nothing to do with system configuration, of course; it's just a language feature.

The way a system is configured is through the `operating-system` record. Much like the `package` record for defining first class package values the `operating-system` record is used to declare operating systems. Here's an example straight from the manual:

    (use-modules (gnu))
    (use-service-modules networking ssh)
    (use-package-modules screen)

    (operating-system
      (host-name "komputilo")
      (timezone "Europe/Berlin")
      (locale "en_US.utf8")

      ;; Boot in "legacy" BIOS mode, assuming /dev/sdX is the
      ;; target hard disk, and "my-root" is the label of the target
      ;; root file system.
      (bootloader (bootloader-configuration
                    (bootloader grub-bootloader)
                    (target "/dev/sdX")))
      (file-systems (cons (file-system
                            (device (file-system-label "my-root"))
                            (mount-point "/")
                            (type "ext4"))
                          %base-file-systems))

      ;; This is where user accounts are specified.  The "root"
      ;; account is implicit, and is initially created with the
      ;; empty password.
      (users (cons (user-account
                    (name "alice")
                    (comment "Bob's sister")
                    (group "users")

                    ;; Adding the account to the "wheel" group
                    ;; makes it a sudoer.  Adding it to "audio"
                    ;; and "video" allows the user to play sound
                    ;; and access the webcam.
                    (supplementary-groups '("wheel"
                                            "audio" "video")))
                   %base-user-accounts))

      ;; Globally-installed packages.
      (packages (cons screen %base-packages))

      ;; Add services to the baseline: a DHCP client and
      ;; an SSH server.
      (services (append (list (service dhcp-client-service-type)
                              (service openssh-service-type
                                       (openssh-configuration
                                        (port-number 2222))))
                        %base-services)))
The "packages" field is for declaring globally available packages, nothing special. What's interesting, though, is the "services" field. This is not just about services in the sense of daemons (i.e. Shepherd services that can be started and stopped), but about anything really to extend the system.

System services can be composed and may extend one another, see <https://www.gnu.org/software/guix/manual/en/html_node/Servic.... This can be used for complex system setup like web applications that require a web server configuration (e.g. by adding an nginx server block), a database, and so on. An example is the Zabbix system service. We also use the service framework for generating PAM policies, creating files in /etc, for udev rules, etc.

This framework was described also in comparison with NixOS in a 2015 blog post: https://www.gnu.org/software/guix/blog/2015/service-composit...

"guix system" operates on an "operating-system" value (read from a file or read as a Scheme expression) to instantiate a VM, a container image, or a bare-metal system.


Thank you for the helpful explanation of guix packaging.


I use nix in production, and it is amazing. It's super config management on steroids with the ability to roll back in a literal instant.

Guix is based off nix, I have looked at it a few times, but it seems much more complicated and less developed than nix. It's only selling point over nix if that everything is written in guile, which does not matter to me.


When you say "based off of", you mean spiritually, not codewise, right?


It's a bit of both, though much more spiritually. A low-level component (the daemon) is taken from Nix. The daemon takes so-called derivations (text files listing the expected outputs and inputs, as well as the file name of the builder script), sets up a chroot where the inputs are available, and runs the builder script. Everything above that level of abstraction is different. (Guix has first-class package values and build system abstractions, for example, and is generally implemented as an extension to Guile Scheme, i.e. as an embedded DSL.)

Even at that level there are differences: our build scripts are not glued together shell snippets but Guile scripts that are generated from the upper layers.

We're in the process of replacing the daemon with something written in Guile, because a lot of the daemon's functionality has already been implemented in Guile for other features of Guix (e.g. the container features), but we're in no hurry as the modified nix daemon works fine in practice. We'd love to reuse more Guile code, though, and lower the barrier to hacking on the daemon (which is currently written in C++), so eventually the only thing that connects Guix and Nix is the format of the derivation files and the idea of functional package management.


Many people run Nix in production — a similarly structured OS. Nix works fine. GUIX is relatively new; I played with it, but didn’t use in production yet.


Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: