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

initial kubernetes context stub #104

Merged
merged 2 commits into from
Nov 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/main/kotlin/io/titandata/titan/Cli.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ object Cli {

override fun run() {
val providerFactory = ProviderFactory()
val provider = providerFactory.getFactory("Local")
val type = System.getenv("TITAN_CONTEXT") ?: "local"
val provider = providerFactory.getFactory(type)
context.obj = Dependencies(provider)
if (context.invokedSubcommand?.commandName != "install") {
provider.checkInstall()
Expand Down
38 changes: 28 additions & 10 deletions src/main/kotlin/io/titandata/titan/clients/Docker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.json.JSONObject
import org.kohsuke.randname.RandomNameGenerator
import kotlin.random.Random

class Docker(private val executor: CommandExecutor) {
class Docker(private val executor: CommandExecutor, val identity: String = "titan") {

val logs = mutableMapOf<String, Boolean>()

Expand All @@ -22,14 +22,25 @@ class Docker(private val executor: CommandExecutor) {
"--network=host",
"-d",
"--restart","always",
"--name=titan-launch",
"--name=$identity-launch",
"-v", "/var/lib:/var/lib",
"-v", "/run/docker:/run/docker",
"-v", "/lib:/var/lib/titan/system",
"-v", "titan-data:/var/lib/titan/data",
"-v", "/lib:/var/lib/$identity/system",
"-v", "$identity-data:/var/lib/$identity/data",
"-v", "/var/run/docker.sock:/var/run/docker.sock"
)

private val titanLaunchKubernetesArgs = mutableListOf(
"-d",
"--restart", "always",
"--name=$identity-server",
"-v", "${System.getProperty("user.home")}/.kube:/root/.kube",
"-v", "$identity-data:/var/lib/$identity",
"-e", "TITAN_CONTEXT=kubernetes-csi",
"-e", "TITAN_DATA=$identity",
"-p", "5002:5001"
)

fun version(): String {
return executor.exec(listOf("docker", "-v")).trim()
}
Expand Down Expand Up @@ -63,35 +74,42 @@ class Docker(private val executor: CommandExecutor) {
}

fun titanLaunchIsAvailable():Boolean {
return containerIsRunning("titan-launch")
return containerIsRunning("$identity-launch")
}

fun titanLaunchIsStopped(): Boolean {
return containerIsStopped("titan-launch")
return containerIsStopped("$identity-launch")
}

fun titanServerIsAvailable(): Boolean {
return containerIsRunning("titan-server")
return containerIsRunning("$identity-server")
}

fun titanServerIsStopped(): Boolean {
return containerIsStopped("titan-server")
return containerIsStopped("$identity-server")
}

fun launchTitanServers(): String {
titanLaunchArgs.add("-e")
titanLaunchArgs.add("TITAN_IMAGE=titan:latest")
titanLaunchArgs.add("-e")
titanLaunchArgs.add("TITAN_IDENTITY=$identity")
return run("titan:latest", "/bin/bash /titan/launch", titanLaunchArgs)
}

fun teardownTitanServers(): String {
titanLaunchArgs.removeAt(titanLaunchArgs.indexOf("-d"))
titanLaunchArgs.removeAt(titanLaunchArgs.indexOf("--restart"))
titanLaunchArgs.removeAt(titanLaunchArgs.indexOf("always"))
titanLaunchArgs.removeAt(titanLaunchArgs.indexOf("--name=titan-launch"))
titanLaunchArgs.removeAt(titanLaunchArgs.indexOf("--name=$identity-launch"))
titanLaunchArgs.add("--rm")
return run("titan:latest", "/bin/bash /titan/teardown", titanLaunchArgs)
}

fun launchTitanKubernetesServers(): String {
return run("titan:latest", "/bin/bash /titan/run", titanLaunchKubernetesArgs)
}

fun pull(image: String): String {
return executor.exec(listOf("docker", "pull", image)).trim()
}
Expand Down Expand Up @@ -162,7 +180,7 @@ class Docker(private val executor: CommandExecutor) {
}

fun cp(source: String, target: String): String {
return executor.exec(listOf("docker", "cp", "-a", "$source/.", "titan-server:/var/lib/titan/mnt/$target"))
return executor.exec(listOf("docker", "cp", "-a", "$source/.", "$identity-server:/var/lib/titan/mnt/$target"))
}

fun stop(container: String): String {
Expand Down
161 changes: 161 additions & 0 deletions src/main/kotlin/io/titandata/titan/providers/Kubernetes.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2019 by Delphix. All rights reserved.
*/

package io.titandata.titan.providers

import io.titandata.client.apis.RepositoriesApi
import kotlin.system.exitProcess
import io.titandata.titan.clients.Docker
import io.titandata.titan.exceptions.CommandException
import io.titandata.titan.utils.CommandExecutor
import io.titandata.titan.providers.kubernetes.*

class Kubernetes: Provider {
private val titanServerVersion = "0.6.3"
private val dockerRegistryUrl = "titandata"

private val commandExecutor = CommandExecutor()
private val docker = Docker(commandExecutor, Identity)
private val repositoriesApi = RepositoriesApi("http://localhost:${Port}")

private val n = System.lineSeparator()

companion object {
val Identity = "titan-k8s"
val Port = 5002
}

private fun exit(message:String, code: Int = 1) {
if (message != "") {
println(message)
}
exitProcess(code)
}

private fun getContainersStatus(): List<Container> {
val returnList = mutableListOf<Container>()
val repositories = repositoriesApi.listRepositories()
for (repo in repositories) {
val container = repo.name
var status = "detached"
try {
val containerInfo = docker.inspectContainer(container)!!
status = containerInfo.getJSONObject("State").getString("Status")
} catch (e: CommandException) {}
returnList.add(Container(container, status))
}
return returnList
}

override fun checkInstall() {
val checkInstallCommand = CheckInstall(::exit, commandExecutor, docker)
return checkInstallCommand.checkInstall()
}

override fun pull(container: String, commit: String?, remoteName: String?, tags: List<String>, metadataOnly: Boolean) {
TODO("not implemented")
}

override fun push(container: String, commit: String?, remoteName: String?, tags: List<String>, metadataOnly: Boolean) {
TODO("not implemented")
}

override fun commit(container: String, message: String, tags: List<String>) {
TODO("not implemented")
}

override fun install(registry: String?, verbose: Boolean) {
val regVal = if (registry.isNullOrEmpty()) {
dockerRegistryUrl
} else {
registry
}
val installCommand = Install(titanServerVersion, regVal, verbose, commandExecutor, docker)
return installCommand.install()
}

override fun abort(container: String) {
TODO("not implemented")
}

override fun status(container: String) {
TODO("not implemented")
}

override fun remoteAdd(container: String, uri: String, remoteName: String?, params: Map<String, String>) {
TODO("not implemented")
}

override fun remoteLog(container: String, remoteName: String?, tags: List<String>) {
TODO("not implemented")
}

override fun remoteList(container: String) {
TODO("not implemented")
}

override fun remoteRemove(container: String, remote: String) {
TODO("not implemented")
}

override fun migrate(container: String, name: String) {
TODO("not implemented")
}

override fun run(arguments: List<String>) {
TODO("not implemented")
}

override fun uninstall(force: Boolean) {
val uninstallCommand = Uninstall(titanServerVersion, ::exit, ::remove, commandExecutor, docker)
return uninstallCommand.uninstall(force)
}

override fun upgrade(force: Boolean, version: String, finalize: Boolean, path: String?) {
TODO("not implemented")
}

override fun checkout(container: String, guid: String?, tags: List<String>) {
TODO("not implemented")
}

override fun delete(repository: String, commit: String?, tags: List<String>) {
TODO("not implemented")
}

override fun tag(repository: String, commit: String, tags: List<String>) {
TODO("not implemented")
}

override fun list() {
System.out.printf("%-20s %s${n}", "REPOSITORY", "STATUS")
for (container in getContainersStatus()) {
System.out.printf("%-20s %s${n}", container.name, container.status)
}
}

override fun log(container: String, tags: List<String>) {
TODO("not implemented")
}

override fun stop(container: String) {
TODO("not implemented")
}

override fun start(container: String) {
TODO("not implemented")
}

override fun remove(container: String, force: Boolean) {
TODO("not implemented")
}

override fun cp(container: String, driver: String, source: String, path: String) {
TODO("not implemented")
}

override fun clone(uri: String, container: String?, commit: String?, params: Map<String, String>) {
TODO("not implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package io.titandata.titan.providers
class ProviderFactory {
fun getFactory(name: String): Provider {
return when(name) {
"Local" -> Local()
"local" -> Local()
"kubernetes" -> Kubernetes()
else -> Mock()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2019 by Delphix. All rights reserved.
*/

package io.titandata.titan.providers.kubernetes

import io.titandata.titan.clients.Docker
import io.titandata.titan.providers.Kubernetes
import io.titandata.titan.utils.CommandExecutor

class CheckInstall (
private val exit: (message: String, code: Int) -> Unit,
private val commandExecutor: CommandExecutor = CommandExecutor(),
private val docker: Docker = Docker(commandExecutor, Kubernetes.Identity)
) {

fun checkInstall() {
try {
docker.version()
} catch (e: Exception) {
exit("Docker not found, install docker and run 'install' to configured required infrastructure", 1)
}
if (!docker.titanIsDownloaded()) {
exit("Titan is not configured, run 'install' to configure required infrastructure", 1)
}
if (!docker.titanServerIsAvailable()) {
exit("Titan is not configured, run 'install' to configure required infrastructure", 1)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019 by Delphix. All rights reserved.
*/

package io.titandata.titan.providers.kubernetes

import io.titandata.titan.Version
import io.titandata.titan.clients.Docker
import io.titandata.titan.providers.Kubernetes
import io.titandata.titan.utils.CommandExecutor
import io.titandata.titan.utils.ProgressTracker

class Install (
private val titanServerVersion: String,
private val dockerRegistryUrl: String,
private val verbose: Boolean = false,
private val commandExecutor: CommandExecutor = CommandExecutor(),
private val docker: Docker = Docker(commandExecutor, Kubernetes.Identity),
private val track: (title: String, function: () -> Any) -> Unit = ProgressTracker()::track
) {
fun install() {
println("Initializing titan infrastructure ...")
track("Checking docker installation") { docker.version() }
if (!docker.titanLatestIsDownloaded(Version.fromString(titanServerVersion))) {
track("Pulling titan docker image (may take a while)") {
docker.pull("${dockerRegistryUrl}/titan:$titanServerVersion")
}
docker.tag("${dockerRegistryUrl}/titan:$titanServerVersion", "titan:$titanServerVersion")
docker.tag("${dockerRegistryUrl}/titan:$titanServerVersion", "titan")
}
if (docker.titanServerIsAvailable()) {
track("Removing stale titan-server container") {
docker.rm("${docker.identity}-server", true)
}
}
track("Starting titan server docker containers") {
docker.launchTitanKubernetesServers()
}

println("Titan cli successfully installed, happy data versioning :)")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2019 by Delphix. All rights reserved.
*/

package io.titandata.titan.providers.kubernetes

import io.titandata.client.apis.RepositoriesApi
import io.titandata.titan.clients.Docker
import io.titandata.titan.providers.Kubernetes
import io.titandata.titan.utils.CommandExecutor
import io.titandata.titan.utils.ProgressTracker

class Uninstall (
private val titanServerVersion: String,
private val exit: (message: String, code: Int) -> Unit,
private val remove: (container: String, force: Boolean) -> Unit,
private val commandExecutor: CommandExecutor = CommandExecutor(),
private val docker: Docker = Docker(commandExecutor, Kubernetes.Identity),
private val repositoriesApi: RepositoriesApi = RepositoriesApi(),
private val track: (title: String, function: () -> Any) -> Unit = ProgressTracker()::track
) {
fun uninstall(force: Boolean) {
if (docker.titanServerIsAvailable()) {
val repositories = repositoriesApi.listRepositories()
for (repo in repositories) {
if (!force) {
exit("repository ${repo.name} exists, remove first or use '-f'", 1)
}
remove(repo.name, true)
}
}
if (docker.titanServerIsAvailable()) docker.rm("${docker.identity}-server", true)
track ("Removing titan-data Docker volume") {
docker.removeVolume("titan-data")
}
track ("Removing Titan Docker image") {
docker.removeTitanImages(titanServerVersion)
}
println("Uninstalled titan infrastructure")
}
}
Loading