philcali / sbt-aws-plugin

A simple AWS EC2 IO inside of an sbt console
MIT License
8 stars 0 forks source link

How to use sbt-assembly and sbt-aws-plugin together? (jarName setting vs task conflict) #1

Open newhoggy opened 10 years ago

newhoggy commented 10 years ago

Question also asked on Stack Overflow:

http://stackoverflow.com/q/21138537/3180279

The example given at https://github.com/philcali/sbt-aws-plugin is as follows:

awsSsh.scripts += NamedSshScript("deploy", execute = {
  sshClient =>
  val jar = "~/" + (jarName in assembly).value
  val assemblyJar = (outputPath in assembly).value.getAbsolutePath

  sshClient.upload(assemblyJar, jar).right.map {
    _.exec("java -jar " + jar)
  }
})

When I try this, I get the error:

/Users/joky/GoCatch/go/build.sbt:20: error: A setting cannot depend on a task
  val jar = "~/" + (jarName in assembly).value

In sbt-assembly, jarName is defined as a task. I checked the git logs for sbt-assembly and found that at one stage (about a year ago) it was changed from a setting to a task.

How can I consume the name of the jar produced by sbt-assembly from a script described in sbt-aws-plugin?

Thanks!

philcali commented 10 years ago

I need to update the README, or change the scripts to a task (which it really should be). Basically, you'd have to use the awsEc2.running as a workaround, or define an awsEc2 action that does the same:

awsEc2.running := {
  instance =>
  awsSsh.retry() {
    awsSsh.connect(instance, awsSsh.config.value) {
      val jar = "~/" + (jarName in assembly).value
      val assemblyJar = (outputPath in assembly).value.getAbsolutePath
      sshClient.upload(assemblyJar, jar).right.map {
        _.exec("java -jar " + jar)
      }
    }
  }
}

Or the aws action:

awsEc2.actions += NamedAwsAction("deployJar", "Deploys assembled jar", (input => {
  awsMongo.collection.value.find(MongoDBObject("group" -> input)).foreach {
    instance =>
      awsSsh.retry() {
      awsSsh.connect(instance, awsSsh.config.value) {
        sshClient =>
        val jar = "~/" + (jarName in assembly).value
        val assemblyJar = (outputPath in assembly).value
        sshClient.upload(assemblyJar, jar).right.map {
          _.exec("java -jar " + jar)
        }
      }
    }
  }
}))

Using this action would look like:

> awsEc2Run deployJar dev

You could just as easily hit amazon again in the action with:

(input => awsEc2.spread(input, awsEc2.requests.value) {
   sRequest =>
   val request = awsEc2.groupRequest(sRequest.name, awsMongo.collection.value)
   awsEc2.client.value.describeInstances(request).getReservations().getInstances().foreach {
   awsInstance =>
   val instance = awsMongo.collection.value.findOne("instanceId" -> awsInstance.getInstanceId()).get()
   // same ssh block
})

If you use the action route, make sure the publicDNS is assigned and the instance is running via alert.