core/internal/consensus: refactor

This refactors the consensus to:
 - use localstorage
 - use the supervisor system
 - have a significantly simpler API for callers (no more
   PrecreateCertificate, etc.)
 - use a watcher for CRLs
 - actually have all bootstrap paths tested
 - keep the CA key in memory (keeping it in etcd only seems like odd
   threat modelling and can posisbly cause issues on quorum losses)

This breaks the build, as is part of a multi-revision refactor of the
core node service code.

Test Plan: adds tests \o/

X-Origin-Diff: phab/D579
GitOrigin-RevId: fadee7785028ef806d8243a770c70cb0fb82c20e
diff --git a/core/internal/launch/launch.go b/core/internal/launch/launch.go
index 774b432..d08117d 100644
--- a/core/internal/launch/launch.go
+++ b/core/internal/launch/launch.go
@@ -39,23 +39,9 @@
 
 	apipb "git.monogon.dev/source/nexantic.git/core/generated/api"
 	"git.monogon.dev/source/nexantic.git/core/internal/common"
+	freeport "git.monogon.dev/source/nexantic.git/golibs/common"
 )
 
-// This is more of a best-effort solution and not guaranteed to give us unused ports (since we're not immediately using
-// them), but AFAIK qemu cannot dynamically select hostfwd ports
-func getFreePort() (uint16, io.Closer, error) {
-	addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
-	if err != nil {
-		return 0, nil, err
-	}
-
-	l, err := net.ListenTCP("tcp", addr)
-	if err != nil {
-		return 0, nil, err
-	}
-	return uint16(l.Addr().(*net.TCPAddr).Port), l, nil
-}
-
 type qemuValue map[string][]string
 
 // toOption encodes structured data into a QEMU option.
@@ -167,7 +153,7 @@
 func ConflictFreePortMap() (PortMap, error) {
 	portMap := make(PortMap)
 	for _, port := range requiredPorts {
-		mappedPort, listenCloser, err := getFreePort()
+		mappedPort, listenCloser, err := freeport.AllocateTCPPort()
 		if err != nil {
 			return portMap, fmt.Errorf("failed to get free host port: %w", err)
 		}