riboseinc / riffol

Initialization system in Rust
26 stars 4 forks source link

Riffol outside containers: starting services as containers #18

Open ronaldtse opened 6 years ago

ronaldtse commented 6 years ago

As raised here by @erikbor https://github.com/riboseinc/riffol/issues/10#issuecomment-398297014 Riffol (on the host) should be able to configure containers as services, and how to pass configuration between them.

Jenkins has a similar syntax (https://github.com/riboseinc/packaging/blob/jenkinsfile/Jenkinsfile):

packages.each {
  this_package = it
  docker.image('centos:7').withRun(
    "--rm " +
    "-v ${pwd}:/usr/local/packaging " +
    "--workdir /usr/local/packaging " +
    "-e REPO_USERNAME=\"${env.REPO_USERNAME}\" " +
    "-e REPO_PASSWORD=\"${env.REPO_PASSWORD}\" "
  ) {
    sh "./build.sh ${this_package}"
  }

  println "Done."
}

For example:

# This is a service on the host, to run the docker container which runs the openvpn service
service "host-openvpn" {
  type = "container"
  healthcheck = {
    ...
  }

  # We pass in a "context" to the docker container
  configuration = "${context.openvpn-container}"
}

# This gets passed into the container
context "openvpn-container" {
  bundle {
    openvpn = "${service.conatiner-openvpn}",
    dhkey = "${command.openvpn-dh-key.stdout}"
  ]
}

# This is the service definition of openvpn within container
service "container-openvpn" {
  exec = "/usr/bin/openvpn"
  ...
}

# This is a file created in the container
file "container-dh-file" {
  path = "/etc/openvpn/dh.pem"
  mode = "0400"
  user = "${user.openvpn.name}"
  group = "${group.openvpn.name}"
  contents = "${context.openvpn-container.dhkey}"
}

# This is a command run on the host
command "openvpn-dh-key" {
  exec = "openssl dHParam -outform PEM"
  # output to stdout
}

Thoughts?

drystone commented 6 years ago

Yes, absolutely Riffol should be able to start containers but my immediate impulse would be to use a script. ie, get nereond to install a script as per usual file and have an application in riffol.conf that runs the script. There's a lot we can do with scripts and environment variables without needing to maintain a DSL for docker, a DSL for xen ... I'm so keen on the scripting idea that I've previously considered using a script for installing dependencies, as opposed to package names. If we were to support sciptlets in a similar fashion to RUN in a Dockerfile:


dependencies www {
    run [
        apt-get install -y apache
        git clone https://somesite.git
        cp somesite/apache.conf /etc/apache/sites-availale/somesite.conf
        a2ensite somesite
    ]
}
ronaldtse commented 6 years ago

The point of the docker / xen example is really to provide the user with a uniform interface that they don't need to worry about implementation details.

I don't mind having a shell script functionality, but there is a strong aversion to actually doing things in them -- this is eerily close to duplicating Dockerfile functionality, and if we're not careful this will just be considered another Anisible or Chef, and this is not what we want. The first two lines with apt-get and git clone are examples on why packages shouldn't be handled here -- if the apt repo returns an error, the entire dependency will fail.

We want to stick with a universal configuration management tool (deterministic), not another provisioning tool (indeterministic).

drystone commented 6 years ago

Ok, thanks @ronaldtse. I thought we were writing a provisioning system with an init process and configuration management.

I don't know how but I was under the impression that fundamental to this was the ability to recreate the container/machine that this particular configuration set is tied to.

But I think you're implying a precondition that the target is guaranteed to support this particular configuration and therefore not the responsibility of Riffol/Nereond to ensure this.

The above configuration makes more sense to me now, as does your reluctance to script and need for command. Apologies for my confusion :-)