Commit a8204f22 authored by David's avatar David

Doing a bit, but probably not going this path

parent 402c9b95
package is.kow.backupcoordinator.actors
import akka.actor.{Actor, ActorLogging, ActorRef, Props, ReceiveTimeout}
import is.kow.backupcoordinator.actors.HostBackupActor.EstablishSSHSession
import net.schmizz.sshj.SSHClient
import scala.concurrent.duration.Duration
object HostBackupActor {
def props(hostname: String, statusActor: ActorRef): Props = Props(new HostBackupActor(hostname, statusActor))
case object EstablishSSHSession
case class Timeout(kind: String)
}
class HostBackupActor(hostname: String, statusActor: ActorRef) extends Actor with ActorLogging {
/*
stages of backing up a host
1. establish SSH connection
2. make backup directory
3. mount backup directory
4. run backup command
a. Run pre-backup commands
b. Run actual backup commands
c. Run post-backup cleanup commands
5. unmount backup directory
6. close SSH connection
*/
override def preStart(): Unit = {
//send myself a message to start up the SSH command
self ! EstablishSSHSession
}
override def receive: Receive = {
case EstablishSSHSession =>
//Start a tiny actor to do the actual establishment, so it can fail, and we can retry
val connectionActor = context.actorOf(SSHConnectionActor.props)
import scala.concurrent.duration._
context.setReceiveTimeout(3.seconds)
context.become(awaitingConnection)
}
def awaitingConnection: Receive = {
case ReceiveTimeout =>
log.error("Did not receive connection in time! Retrying")
case client:SSHClient =>
context.setReceiveTimeout(Duration.Undefined)
//Have an ssh connection, time to send commands like make backup directory
}
}
package is.kow.backupcoordinator.actors
import java.security.{PrivateKey, PublicKey}
import akka.actor.{Actor, ActorLogging, Props}
import is.kow.backupcoordinator.actors.SSHConnectionActor.Connect
import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.common.KeyType
import net.schmizz.sshj.transport.verification.HostKeyVerifier
import net.schmizz.sshj.userauth.keyprovider.KeyProvider
object SSHConnectionActor {
def props: Props = Props(new SSHConnectionActor())
case class Connect(hostname: String)
}
class SSHConnectionActor extends Actor with ActorLogging {
//TODO: implement key loading from config
class DarkKeyProvider extends KeyProvider {
override def getPrivate: PrivateKey = {
???
}
override def getPublic: PublicKey = {
???
}
override def getType: KeyType = {
???
}
}
class DarkHostKeyVerifier extends HostKeyVerifier {
override def verify(hostname: String, port: Int, key: PublicKey): Boolean = {
//TODO: implement some kind of validation....
// Maybe some kind of last seen or something
log.debug(s"Validating $hostname:$port ...")
true
}
}
override def receive: Receive = {
case Connect(hostname) =>
val keyProvider = new DarkKeyProvider()
val client = new SSHClient()
client.authPublickey("root", keyProvider)
client.addHostKeyVerifier(new DarkHostKeyVerifier)
client.connect(hostname)
context.parent ! client
//I'm all done, this is my only purpose
context.stop(self)
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment