combust-labs/firebuild

Can a rootfs be built using the mmds type bootstrap?

radekg opened this issue · 3 comments

Work out how a rootfs can be built using mmds type bootstrap.

Advantages over the current solution:

  • no need to install openssh on the machine in baseos
  • no need to create users on the machine in the baseos, vminit can be extended to support creating users, groups and necessary directories
  • rootfs build would not require ssh access anymore, commands from the Dockerfile can be executed without sudo

The next step to investigate is:

  • to start a GRPC server during the bootstrap process
  • configure the server with TLS, allow specifying custom ca cert, cert and key for this server, if nothing specified, generate a full bootstrap only root ca cert, server cert and key, client cert and key - mTLS always on, no option for insecure connections
  • in tests, simulate vminit to establish the connection to the bootstrap server
  • load the commands via the vminit process from the bootstrap server:
    • RUN commands should be executed
    • ADD / COPY resources should be downloaded and placed at expected locations

The MMDS metadata for the rootfs process needs to include a dedicated bootstrap flag indicating that vminit should initiate the connection to the bootstrap endpoint. The bootstrap endpoint definition will be an MMDS metadata property and could look like:

{
  "bootstrap": {
    "grpc-host-port": "...",
    "tls-ca-cert": "...",
    "tls-cert": "...",
    "tls-key": "..."
  }
}

The GRPC server should offer a following API:

  • Commands() returns string: returns JSON serialized array of RUN, ADD and COPY commands; these contain all the environment, build args, workdir, user and shell information
  • ResourceChunk(path) returns Chunk{ data: []byte, checksum: []byte, eof: bool }: returns the next chunk for the requested path, client calls this endpoint repeatedly until the eof: true, when this happens, client writes the final bytes to the target file and progresses to the next step, the server decides how many bytes are sent in a single chunk; keep GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/grpc_types.h#L156 in consideration
  • StdOut(string) returns nothing: accepts the stdout line from the client
  • StdErr(string) returns nothing: accepts the stderr line from the client
  • Abort(error) returns nothing: reports bootstrap failure, bootstrapper should abort and report
  • Success() returns nothing: reports bootstrap process finished, bootstrapper to finalize the process

Commands are executed in order, one at a time. The guest will never make a decision where to connect to and how to authenticate. It will fully obey MMDS metadata.

Closed with #49.