Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for additional docker commands #48

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

drdozer
Copy link

@drdozer drdozer commented May 30, 2016

I've started work on adding support for other docker commands for controlling containers. This is a pull request to let you see what I'm doing. Not expecting it to be merged in at this time.

@drdozer
Copy link
Author

drdozer commented May 30, 2016

So it supports syntax like this for configuring container creation:

  createOptions in docker := new CreateOptions {
    image("mysql")
    expose(22)
    port("0.0.0.0", 3306, 3306)
    port("0.0.0.0:9022:22")
  }

@drdozer
Copy link
Author

drdozer commented May 30, 2016

Start is now implemented. Create and start can be chained like this:

  startOptions in docker := new StartOptions {
    val containerId = (dockerCreate in docker).value
    container(containerId)
  }

@drdozer
Copy link
Author

drdozer commented May 30, 2016

Here's an example, not very exciting workflow:

  createOptions in docker := new CreateOptions {
    image("mysql")
    expose(22)
    port("0.0.0.0", 3306, 3306)
    port("0.0.0.0:9022:22")
    env("MYSQL_RANDOM_ROOT_PASSWORD" -> "true")
  },

  startOptions in docker := new StartOptions {
    val containerId = (dockerCreate in docker).value
    container(containerId)
  },

  stopOptions in docker := new StopOptions {
    val containerId = (dockerStart in docker).value
    container(containerId)
  },

  rmOptions in docker := new RmOptions {
    val containerId = (dockerStop in docker).value
    container(containerId)
  }

@drdozer
Copy link
Author

drdozer commented Jun 1, 2016

OK, the issue I've hit is that MySQL encodes usnernames and passwords into the URL and calls

scala.slick.codegen.SourceCodeGenerator.main(
  Array(slickDriver, jdbcDriver, url, outputFolder, pkg)

Postgres seems to want to have the username and password passed in separately and requires the call

scala.slick.codegen.SourceCodeGenerator.main(
  Array(slickDriver, jdbcDriver, url, outputFolder, pkg, usr, pwd)

I can put some special case code in slickGenTables to switch on mysql/postgres but that seems a bit icky to me. Or I could pull the logic for generating that Array() into the database-dependent codegen object?

@marcus-drake
Copy link
Owner

This looks interesting.
The configuration DSL looks cool at first sight :)

I'm a bit curious of your use cases for it.
Are there cases when you want to start several containers?

@drdozer
Copy link
Author

drdozer commented Jun 1, 2016

My immediate use is to spin up/down databases with schemas for slick table generation. But we have a whole host of builds that require some tools or infrastructure to build against and we're moving towards dockerising all these. So dockerising making these tools available to the builds is a logical next step.

@drdozer
Copy link
Author

drdozer commented Jun 1, 2016

So in another project, we generate code against an RDF schema stored in a triple store. The build requires the populated triplestore to be available. Spinning up the populated triplestore when we need it during the build would let us build anywhere, rather than on a specially configured host.

@drdozer
Copy link
Author

drdozer commented Jun 8, 2016

@marcuslonnberg what do you think to adding logic to alternatively only run a docker build if something has changed?

@marcus-drake
Copy link
Owner

Sorry I haven't had time to follow up on this. My company have moved to a new office and such.

I'm thinking about the complexity of this configuration and how often it will be used.
I would like to know if this could be supported by giving the users access to a Docker client where they can run whatever docker commands they want by defining their own tasks.
For example if you want to start a database for Slick table generation then you can define a task which starts the container:

val startDatabase = taskKey[ContainerId]("...")
startDatabase := {
    dockerClient.run(port = 1234, image = "postgres", name = "db")
}

val stopDatabase = taskKey[ContainerId]("...")
stopDatabase := {
    dockerClient.stop(name = "db")
}

I feel like the configuration DSL is both powerful but at the same time limited by how tasks and settings work in sbt.

@drdozer
Copy link
Author

drdozer commented Jun 15, 2016

I've actually been thinking about this also. One alternative I'd come up with was to wrap an existing command in a docker spin-up-tear-down cycle. So:

withDockerInstance(someTask) { configurationDSLCommands }

That would spin up the instance, then run someTask, then tear it down. That would let you spin up one instance for code generation, another instance for testing, and so on.

@13h3r
Copy link

13h3r commented Jun 29, 2016

I like the idea. What about supporting tag and push command?

@13h3r
Copy link

13h3r commented Jun 29, 2016

Ignore my comment. I read the docs carefully and found all I need. Sorry

@vishalovercome
Copy link

Are there any plans to merge this PR? The ability to remove an image would allow us to drive our CI using sbt alone. If this pull request is very extensive, then I can implement just that feature alone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants