Compare commits
No commits in common. "develop" and "master" have entirely different histories.
20 changed files with 223 additions and 532 deletions
9
TODO.md
9
TODO.md
|
@ -1,9 +0,0 @@
|
||||||
cat database.sql.gz |ssh shiva-ratri.infra.boldcode.io 'docker exec -i customer-sans-a-site.web.1 sh -c "cat > adminer.sql.gz"'
|
|
||||||
|
|
||||||
cat database.sql |ssh shiva-ratri.infra.boldcode.io 'dokku mariadb:import customer-sans-a-wpsandbox'
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
|
|
||||||
* verify target app exist
|
|
||||||
* verify target database exist
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
---
|
|
||||||
version: "3"
|
|
||||||
|
|
||||||
hosts:
|
|
||||||
- name: local
|
|
||||||
localhost: {}
|
|
||||||
|
|
||||||
- name: testing
|
|
||||||
ssh:
|
|
||||||
user: debian
|
|
||||||
host: shiva-ratri.infra.boldcode.io
|
|
||||||
|
|
||||||
|
|
||||||
endpoints:
|
|
||||||
# Local endpoints
|
|
||||||
- name: local-wp-image
|
|
||||||
host: local
|
|
||||||
docker_image:
|
|
||||||
name: sans-a-site-v2-wordpress_wordpress
|
|
||||||
|
|
||||||
- name: local-db-dump
|
|
||||||
host: local
|
|
||||||
mysql_dump:
|
|
||||||
path: database.sql
|
|
||||||
|
|
||||||
- name: local-db-script
|
|
||||||
host: local
|
|
||||||
script:
|
|
||||||
path: .pushokku/post-update.sh
|
|
||||||
|
|
||||||
# Remote endpoints
|
|
||||||
- name: remote-wp-app
|
|
||||||
host: testing
|
|
||||||
dokku_app:
|
|
||||||
name: customer-sans-a-site
|
|
||||||
|
|
||||||
- name: remote-wp-db
|
|
||||||
host: testing
|
|
||||||
dokku_mariadb:
|
|
||||||
name: customer-sans-a-wpsandbox
|
|
||||||
|
|
||||||
|
|
||||||
filters:
|
|
||||||
- name: compress
|
|
||||||
dual:
|
|
||||||
cmd_in: gzip -
|
|
||||||
cmd_out: gunzip -
|
|
||||||
|
|
||||||
|
|
||||||
deployments:
|
|
||||||
- transfer:
|
|
||||||
src: local-wp-image
|
|
||||||
dest: remote-wp-app
|
|
||||||
|
|
||||||
- transfer:
|
|
||||||
src: local-db-dump
|
|
||||||
dest: remote-wp-db
|
|
||||||
|
|
||||||
- run:
|
|
||||||
src: local-db-script
|
|
||||||
dest: remote-wp-app
|
|
|
@ -1,52 +1,9 @@
|
||||||
|
|
||||||
require "yaml"
|
require "yaml"
|
||||||
require "./config/*"
|
require "./config/config"
|
||||||
|
require "./config/local"
|
||||||
|
require "./config/remote"
|
||||||
|
require "./config/deployment"
|
||||||
|
|
||||||
class Config
|
|
||||||
YAML.mapping(
|
|
||||||
version: String,
|
|
||||||
hosts: Array(HostConfig),
|
|
||||||
endpoints: Array(EndpointConfig),
|
|
||||||
filters: Array(FilterConfig),
|
|
||||||
deployments: Array(DeploymentConfig)
|
|
||||||
)
|
|
||||||
|
|
||||||
alias FindableConfig =
|
|
||||||
Array(HostConfig) |
|
|
||||||
Array(EndpointConfig) |
|
|
||||||
Array(FilterConfig) |
|
|
||||||
Array(DeploymentConfig)
|
|
||||||
|
|
||||||
class MissingItemError < Exception
|
|
||||||
end
|
|
||||||
|
|
||||||
class MultipleItemsError < Exception
|
|
||||||
end
|
|
||||||
|
|
||||||
def find(list : FindableConfig, name : String, str : String)
|
|
||||||
matches = list.select { |item| item.name == name }
|
|
||||||
if matches.size > 1
|
|
||||||
raise MultipleItemsError.new "Multiple #{str} have the name #{str}"
|
|
||||||
end
|
|
||||||
if matches.size < 1
|
|
||||||
raise MissingItemError.new "No #{str} found for name #{name}"
|
|
||||||
end
|
|
||||||
return matches.first
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_host(name : String) : HostConfig
|
|
||||||
find(self.hosts, name, "hosts")
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_endpoint(name : String) : EndpointConfig
|
|
||||||
find(self.endpoints, name, "endpoints")
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_filter(name : String) : FilterConfig
|
|
||||||
find(self.filters, name, "filters")
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_deployment(name : String) : DeploymentConfig
|
|
||||||
find(self.deployments, name, "deployments")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
14
src/config/config.cr
Normal file
14
src/config/config.cr
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
require "yaml"
|
||||||
|
require "./local"
|
||||||
|
require "./remote"
|
||||||
|
require "./deployment"
|
||||||
|
|
||||||
|
class Config
|
||||||
|
YAML.mapping(
|
||||||
|
version: String,
|
||||||
|
locals: Array(LocalConfig),
|
||||||
|
remotes: Array(RemoteConfig),
|
||||||
|
deployments: Array(DeploymentConfig)
|
||||||
|
)
|
||||||
|
end
|
|
@ -1,21 +1,37 @@
|
||||||
|
|
||||||
require "yaml"
|
require "yaml"
|
||||||
require "./deployment_settings"
|
|
||||||
|
|
||||||
class RunDeploymentConfig
|
class DokkuMariadbConfig
|
||||||
YAML.mapping(
|
YAML.mapping(
|
||||||
name: String?,
|
name: String,
|
||||||
run: RunDeploymentConfigSettings
|
options: YAML::Any | Nil
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
class TransferDeploymentConfig
|
class DokkuAppConfig
|
||||||
YAML.mapping(
|
YAML.mapping(
|
||||||
name: String?,
|
name: String,
|
||||||
transfer: TransferDeploymentConfigSettings
|
options: YAML::Any | Nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
class DeploymentMariadbConfig
|
||||||
|
YAML.mapping(
|
||||||
|
local: String,
|
||||||
|
remote: String,
|
||||||
|
dokku_mariadb: DokkuMariadbConfig,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
class DeploymentAppConfig
|
||||||
|
YAML.mapping(
|
||||||
|
local: String,
|
||||||
|
remote: String,
|
||||||
|
dokku_app: DokkuAppConfig,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias DeploymentConfig =
|
alias DeploymentConfig =
|
||||||
TransferDeploymentConfig |
|
DeploymentMariadbConfig |
|
||||||
RunDeploymentConfig
|
DeploymentAppConfig
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
|
|
||||||
class TransferDeploymentConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
src: String,
|
|
||||||
dest: String,
|
|
||||||
filters: Array(String)?
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class RunDeploymentConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
src: String,
|
|
||||||
dest: String,
|
|
||||||
)
|
|
||||||
end
|
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
require "./endpoint_settings"
|
|
||||||
|
|
||||||
|
|
||||||
class DokkuMariadbEndpointConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
host: String,
|
|
||||||
dokku_mariadb: DokkuMariadbEndpointConfigSettings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class DokkuAppEndpointConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
host: String,
|
|
||||||
dokku_app: DokkuAppEndpointConfigSettings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class ScriptEndpointConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
host: String,
|
|
||||||
script: ScriptEndpointConfigSettings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class MysqlDumpEndpointConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
host: String,
|
|
||||||
mysql_dump: MysqlDumpEndpointConfigSettings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class DockerImageEndpointConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
host: String,
|
|
||||||
docker_image: DockerImageEndpointConfigSettings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
alias EndpointConfig =
|
|
||||||
DockerImageEndpointConfig |
|
|
||||||
MysqlDumpEndpointConfig |
|
|
||||||
ScriptEndpointConfig |
|
|
||||||
DokkuAppEndpointConfig |
|
|
||||||
DokkuMariadbEndpointConfig
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
|
|
||||||
class DokkuMariadbEndpointConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
name: String
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class DokkuAppEndpointConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
name: String
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class DockerImageEndpointConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
tag: {
|
|
||||||
type: String,
|
|
||||||
nilable: false,
|
|
||||||
default: "latest"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def initialize(@name : String, @tag : String)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{name}:#{tag}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class MysqlDumpEndpointConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
path: String
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class ScriptEndpointConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
path: String
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
require "./filter_settings"
|
|
||||||
|
|
||||||
|
|
||||||
class DualFilterConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
dual: DualFilterConfigSettings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
class MonoFilterConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
cmd: String
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
alias FilterConfig =
|
|
||||||
MonoFilterConfig |
|
|
||||||
DualFilterConfig
|
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
|
|
||||||
class DualFilterConfigSettings
|
|
||||||
YAML.mapping(
|
|
||||||
cmd_in: String,
|
|
||||||
cmd_out: String,
|
|
||||||
)
|
|
||||||
end
|
|
|
@ -1,29 +0,0 @@
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
require "./host_settings"
|
|
||||||
|
|
||||||
class LocalHostConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
localhost: Hash(String, YAML::Any)
|
|
||||||
)
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"LocalHost[#{name}]"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
class SshHostConfig
|
|
||||||
YAML.mapping(
|
|
||||||
name: String,
|
|
||||||
ssh: SshHostConfigSettings
|
|
||||||
)
|
|
||||||
def to_s
|
|
||||||
"SshHost[#{name}]"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
alias HostConfig =
|
|
||||||
LocalHostConfig |
|
|
||||||
SshHostConfig
|
|
32
src/config/local.cr
Normal file
32
src/config/local.cr
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
require "yaml"
|
||||||
|
|
||||||
|
enum LocalType
|
||||||
|
DOCKER_IMAGE = 1
|
||||||
|
MYSQL_DUMP = 2
|
||||||
|
|
||||||
|
def to_yaml(io)
|
||||||
|
to_s(io)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class LocalFileConfig
|
||||||
|
YAML.mapping(
|
||||||
|
name: String,
|
||||||
|
type: LocalType, # enum ?
|
||||||
|
path: String
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
class LocalDockerConfig
|
||||||
|
YAML.mapping(
|
||||||
|
name: String,
|
||||||
|
type: LocalType, # enum ?
|
||||||
|
docker_image: String
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
alias LocalConfig =
|
||||||
|
LocalFileConfig |
|
||||||
|
LocalDockerConfig
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
|
|
||||||
require "yaml"
|
require "yaml"
|
||||||
|
|
||||||
class SshHostConfigSettings
|
class RemoteConfig
|
||||||
YAML.mapping(
|
YAML.mapping(
|
||||||
|
name: String,
|
||||||
user: String,
|
user: String,
|
||||||
host: String
|
host: String
|
||||||
)
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{user}@#{host}"
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,62 +1,4 @@
|
||||||
|
|
||||||
require "./deployment/*"
|
require "./deployment/docker_image_to_dokku_app"
|
||||||
# run_script_to_dokku_app"
|
require "./deployment/mysql_dump_to_dokku_mariadb"
|
||||||
# require "./deployment/transfer_docker_image_to_dokku_app"
|
|
||||||
# require "./deployment/transfer_mysql_dump_to_dokku_mariadb"
|
|
||||||
|
|
||||||
|
|
||||||
class Deployment
|
|
||||||
def self.apply_config!(config)
|
|
||||||
config.deployments.each do |deployment_config|
|
|
||||||
Deployment.apply_deployment!(config, deployment_config)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.apply_deployment!(config : Config, deployment_config : TransferDeploymentConfig)
|
|
||||||
src = config.find_endpoint(deployment_config.transfer.src)
|
|
||||||
dest = config.find_endpoint(deployment_config.transfer.dest)
|
|
||||||
|
|
||||||
puts "Trying TransferDeploymentConfig: #{src.class} --> #{dest.class}..."
|
|
||||||
self.apply_transfer!(config, src, dest)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.apply_deployment!(config : Config, deployment_config : RunDeploymentConfig)
|
|
||||||
src = config.find_endpoint(deployment_config.run.src)
|
|
||||||
dest = config.find_endpoint(deployment_config.run.dest)
|
|
||||||
puts "Trying RunDeploymentConfig: #{src.class} --> #{dest.class}..."
|
|
||||||
|
|
||||||
self.apply_run!(config, src, dest)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.apply_run!(config, src, dest)
|
|
||||||
puts "WARNING: run #{src.class} --> #{dest.class} missing!".colorize(:yellow)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.apply_transfer!(config, src, dest)
|
|
||||||
puts "WARNING: transfer #{src.class} --> #{dest.class} missing!".colorize(:yellow)
|
|
||||||
end
|
|
||||||
|
|
||||||
def something
|
|
||||||
deployment =
|
|
||||||
case deployment_config
|
|
||||||
when DokkuAppDeploymentConfig then
|
|
||||||
DockerImageToDokkuAppDeployment.new(
|
|
||||||
local.as(DockerImageLocalConfig),
|
|
||||||
remote,
|
|
||||||
deployment_config.as(DokkuAppDeploymentConfig)
|
|
||||||
)
|
|
||||||
when MysqlDumpToDokkuMariadbDeployment then
|
|
||||||
DeploymentMariadb.new(
|
|
||||||
local.as(MysqlDumpLocalConfig),
|
|
||||||
remote,
|
|
||||||
deployment_config.as(DokkuMariadbDeploymentConfig)
|
|
||||||
)
|
|
||||||
when Nil
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
next if deployment.nil?
|
|
||||||
deployment.run
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
107
src/deployment/docker_image_to_dokku_app.cr
Normal file
107
src/deployment/docker_image_to_dokku_app.cr
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
|
||||||
|
require "colorize"
|
||||||
|
|
||||||
|
class DeploymentApp
|
||||||
|
def initialize(@local : LocalDockerConfig, @remote : RemoteConfig, @deployment : DeploymentAppConfig)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
dokku_app = @deployment.as(DeploymentAppConfig).dokku_app
|
||||||
|
app = dokku_app.name
|
||||||
|
image_meta = image_tag(@local.docker_image, app)
|
||||||
|
image_push(@remote.host, image_meta["tag_name_version"])
|
||||||
|
image_deploy(@remote.host, image_meta["app"], image_meta["version"])
|
||||||
|
end
|
||||||
|
|
||||||
|
# private def image_tag(docker_compose_yml : String, service : String, app : String)
|
||||||
|
# version = `date +"v%Y%m%d_%H%M"`.strip
|
||||||
|
# tag_name = "dokku/#{app}"
|
||||||
|
# tag_name_version = "#{tag_name}:#{version}"
|
||||||
|
# image = `docker-compose -f #{docker_compose_yml} images -q #{service} `.strip
|
||||||
|
# Process.run "docker", ["tag", image, tag_name_version]
|
||||||
|
|
||||||
|
# res = {
|
||||||
|
# app: app,
|
||||||
|
# version: version,
|
||||||
|
# tag_name_version: tag_name_version
|
||||||
|
# }
|
||||||
|
# puts YAML.dump({ image_tag: res })
|
||||||
|
# puts "---"
|
||||||
|
# return res
|
||||||
|
# end
|
||||||
|
|
||||||
|
private def image_tag(docker_image : String, app : String)
|
||||||
|
version = `date +"v%Y%m%d_%H%M"`.strip
|
||||||
|
tag_name = "dokku/#{app}"
|
||||||
|
tag_name_version = "#{tag_name}:#{version}"
|
||||||
|
Process.run "docker", ["tag", docker_image, tag_name_version]
|
||||||
|
|
||||||
|
res = {
|
||||||
|
app: app,
|
||||||
|
version: version,
|
||||||
|
tag_name_version: tag_name_version
|
||||||
|
}
|
||||||
|
puts YAML.dump({ image_tag: res })
|
||||||
|
puts "---"
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
private def image_push(host, tag_name_version)
|
||||||
|
# docker save "$TAG_NAME_VERSION" \
|
||||||
|
# | gzip \
|
||||||
|
# | ssh "$HOST_REMOTE" "gunzip | docker load"
|
||||||
|
|
||||||
|
pipe1_reader, pipe1_writer = IO.pipe(true)
|
||||||
|
pipe2_reader, pipe2_writer = IO.pipe(true)
|
||||||
|
|
||||||
|
p3_out = IO::Memory.new
|
||||||
|
puts "Pushing image...".colorize(:yellow)
|
||||||
|
p3 = Process.new "ssh", [host, "gunzip | docker load"],
|
||||||
|
input: pipe2_reader, output: p3_out, error: STDERR
|
||||||
|
|
||||||
|
p2 = Process.new "gzip",
|
||||||
|
input: pipe1_reader,
|
||||||
|
output: pipe2_writer,
|
||||||
|
error: STDERR
|
||||||
|
|
||||||
|
p1 = Process.new "docker", ["save", tag_name_version],
|
||||||
|
output: pipe1_writer,
|
||||||
|
error: STDERR
|
||||||
|
|
||||||
|
status = p1.wait
|
||||||
|
pipe1_writer.close
|
||||||
|
if status.success?
|
||||||
|
puts "-----> Docker image successfully exported"
|
||||||
|
else
|
||||||
|
STDERR.puts "Error (code #{status.exit_status}) when exporting docker image!"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
status = p2.wait
|
||||||
|
pipe1_reader.close
|
||||||
|
pipe2_writer.close
|
||||||
|
if ! status.success?
|
||||||
|
STDERR.puts "Error (code #{status.exit_status}) when gzipping image!"
|
||||||
|
end
|
||||||
|
|
||||||
|
status = p3.wait
|
||||||
|
pipe2_reader.close
|
||||||
|
if status.success?
|
||||||
|
puts "-----> Docker image successfully imported on #{host}"
|
||||||
|
else
|
||||||
|
STDERR.puts "Error (code #{status.exit_status}) when importing docker image!"
|
||||||
|
end
|
||||||
|
puts "Image pushed successfully!".colorize(:green)
|
||||||
|
end
|
||||||
|
|
||||||
|
private def image_deploy(host, app, version)
|
||||||
|
puts "Deploying image #{app}:#{version}...".colorize(:yellow)
|
||||||
|
status = Process.run "ssh", [host, "dokku tags:deploy #{app} #{version}"],
|
||||||
|
output: STDOUT, error: STDOUT
|
||||||
|
if status.success?
|
||||||
|
puts "Image deployed successfully!".colorize(:green)
|
||||||
|
else
|
||||||
|
STDERR.puts "Error (code #{status.exit_status}) when deploying image!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,15 +1,13 @@
|
||||||
|
|
||||||
class Deployment
|
class DeploymentMariadb
|
||||||
|
def initialize(@local : LocalFileConfig, @remote : RemoteConfig, @deployment : DeploymentMariadbConfig)
|
||||||
|
end
|
||||||
|
|
||||||
def self.apply_transfer!(
|
def run
|
||||||
config : Config,
|
dokku_mariadb = @deployment.dokku_mariadb.as(DokkuMariadbConfig)
|
||||||
src : MysqlDumpEndpointConfig,
|
local_path = @local.path
|
||||||
dest : DokkuMariadbEndpointConfig
|
|
||||||
)
|
|
||||||
dokku_mariadb = dest.name
|
|
||||||
# local_path = @local.path
|
|
||||||
# puts @local.inspect
|
# puts @local.inspect
|
||||||
# file_push(@remote.host, local_path, dokku_mariadb.name)
|
file_push(@remote.host, local_path, dokku_mariadb.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def file_push(host, local_path, dokku_mariadb_name)
|
private def file_push(host, local_path, dokku_mariadb_name)
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
require "colorize"
|
|
||||||
|
|
||||||
class Deployment
|
|
||||||
def self.apply_run!(
|
|
||||||
config : Config,
|
|
||||||
src : ScriptEndpointConfig,
|
|
||||||
dest : DokkuAppEndpointConfig
|
|
||||||
)
|
|
||||||
dokku_app = dest.name
|
|
||||||
# image_meta = image_tag(@local.docker_image, dokku_app)
|
|
||||||
# image_push(@remote.host, image_meta["tag_name_version"])
|
|
||||||
# image_deploy(@remote.host, image_meta["app"], image_meta["version"])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,125 +0,0 @@
|
||||||
|
|
||||||
require "colorize"
|
|
||||||
|
|
||||||
class Deployment
|
|
||||||
# puts YAML.dump({ image_tag: res })
|
|
||||||
# puts "---"
|
|
||||||
|
|
||||||
def self.apply_transfer!(
|
|
||||||
config : Config,
|
|
||||||
src : DockerImageEndpointConfig,
|
|
||||||
dest : DokkuAppEndpointConfig
|
|
||||||
)
|
|
||||||
src_host = config.find_host(src.host)
|
|
||||||
dest_host = config.find_host(dest.host)
|
|
||||||
|
|
||||||
pp src
|
|
||||||
dest_docker_image = build_docker_image_ref_timestamp(dest.name)
|
|
||||||
docker_image_tag!(src, dest_docker_image)
|
|
||||||
docker_image_push!(dest, src, dest_docker_image, dest_host)
|
|
||||||
# docker_image_deploy!(dest_host, dest_docker_image, dest_host)
|
|
||||||
end
|
|
||||||
|
|
||||||
private def self.build_docker_image_ref_timestamp(
|
|
||||||
dokku_app : String
|
|
||||||
)
|
|
||||||
dest_ref = DockerImageEndpointConfigSettings.new(
|
|
||||||
name: "dokku/#{dokku_app}",
|
|
||||||
tag: `TZ=UTC date +"v%Y%m%d_%H%M"`.strip
|
|
||||||
)
|
|
||||||
return dest_ref
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# private def self.docker_image_push!(
|
|
||||||
# )
|
|
||||||
# STDERR.puts "ERROR: pushing docker images to local host is not implemented"
|
|
||||||
# exit 2
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
private def self.docker_image_tag!(
|
|
||||||
src : DockerImageEndpointConfig,
|
|
||||||
dest_docker_image : DockerImageEndpointConfigSettings,
|
|
||||||
)
|
|
||||||
puts "Tagging image...".colorize(:yellow)
|
|
||||||
puts YAML.dump({
|
|
||||||
src: src.docker_image.to_s,
|
|
||||||
dest: dest_docker_image.to_s
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
# docker tag ... dokku/...:tag
|
|
||||||
# docker save "$TAG_NAME_VERSION" \
|
|
||||||
# | gzip \
|
|
||||||
# | ssh "$HOST_REMOTE" "gunzip | docker load"
|
|
||||||
private def self.docker_image_push!(
|
|
||||||
dest : DokkuAppEndpointConfig,
|
|
||||||
src : DockerImageEndpointConfig,
|
|
||||||
dest_docker_image : DockerImageEndpointConfigSettings,
|
|
||||||
dest_host : HostConfig,
|
|
||||||
)
|
|
||||||
if dest_host.is_a? LocalHostConfig
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
Process.run "docker", ["tag", src.docker_image.to_s, dest_docker_image.to_s]
|
|
||||||
|
|
||||||
pipe1_reader, pipe1_writer = IO.pipe(true)
|
|
||||||
pipe2_reader, pipe2_writer = IO.pipe(true)
|
|
||||||
|
|
||||||
p3_out = IO::Memory.new
|
|
||||||
puts "Pushing image...".colorize(:yellow)
|
|
||||||
p3 = Process.new "ssh", [dest_host.ssh.to_s, "gunzip | docker load"],
|
|
||||||
input: pipe2_reader, output: p3_out, error: STDERR
|
|
||||||
|
|
||||||
p2 = Process.new "gzip",
|
|
||||||
input: pipe1_reader,
|
|
||||||
output: pipe2_writer,
|
|
||||||
error: STDERR
|
|
||||||
|
|
||||||
p1 = Process.new "docker", ["save", src.docker_image.to_s],
|
|
||||||
output: pipe1_writer,
|
|
||||||
error: STDERR
|
|
||||||
|
|
||||||
status = p1.wait
|
|
||||||
pipe1_writer.close
|
|
||||||
if status.success?
|
|
||||||
puts "-----> Docker image successfully exported"
|
|
||||||
else
|
|
||||||
STDERR.puts "Error (code #{status.exit_status}) when exporting docker image!"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
status = p2.wait
|
|
||||||
pipe1_reader.close
|
|
||||||
pipe2_writer.close
|
|
||||||
if ! status.success?
|
|
||||||
STDERR.puts "Error (code #{status.exit_status}) when gzipping image!"
|
|
||||||
end
|
|
||||||
|
|
||||||
status = p3.wait
|
|
||||||
pipe2_reader.close
|
|
||||||
if status.success?
|
|
||||||
puts "-----> Docker image successfully imported on #{dest_host.ssh.to_s}"
|
|
||||||
else
|
|
||||||
STDERR.puts "Error (code #{status.exit_status}) when importing docker image!"
|
|
||||||
end
|
|
||||||
puts "Image pushed successfully!".colorize(:green)
|
|
||||||
end
|
|
||||||
|
|
||||||
private def self.docker_image_deploy!(
|
|
||||||
src : DockerImageEndpointConfig,
|
|
||||||
dest : DockerImageEndpointConfig,
|
|
||||||
dest_docker_image : DockerImageEndpointConfigSettings,
|
|
||||||
)
|
|
||||||
puts "Deploying image #{app}:#{version}...".colorize(:yellow)
|
|
||||||
status = Process.run "ssh", [dest.host.to_s, "dokku tags:deploy #{app} #{version}"],
|
|
||||||
output: STDOUT, error: STDOUT
|
|
||||||
if status.success?
|
|
||||||
puts "Image deployed successfully!".colorize(:green)
|
|
||||||
else
|
|
||||||
STDERR.puts "Error (code #{status.exit_status}) when deploying image!"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -4,7 +4,6 @@ require "yaml"
|
||||||
require "colorize"
|
require "colorize"
|
||||||
|
|
||||||
require "./config"
|
require "./config"
|
||||||
require "./validation"
|
|
||||||
require "./deployment"
|
require "./deployment"
|
||||||
|
|
||||||
module Pushokku
|
module Pushokku
|
||||||
|
@ -82,9 +81,35 @@ module Pushokku
|
||||||
config = app.load_config(opts["config_file"])
|
config = app.load_config(opts["config_file"])
|
||||||
# env_config = App.get_config(config, opts["environment"])
|
# env_config = App.get_config(config, opts["environment"])
|
||||||
|
|
||||||
Validation.validate_config!(config)
|
config.deployments.each do |deployment_config|
|
||||||
Deployment.apply_config!(config)
|
local = config.locals.select { |l| l.name == deployment_config.local }.first
|
||||||
exit 0
|
remote = config.remotes.select { |r| r.name == deployment_config.remote }.first
|
||||||
|
if local.nil?
|
||||||
|
puts "Unknown local #{deployment_config.local}. Exiting."
|
||||||
|
exit 2
|
||||||
|
end
|
||||||
|
if remote.nil?
|
||||||
|
puts "Unknown remote #{deployment_config.remote}. Exiting."
|
||||||
|
exit 2
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
deployment =
|
||||||
|
case deployment_config
|
||||||
|
when DeploymentAppConfig then
|
||||||
|
|
||||||
|
DeploymentApp.new(local.as(LocalDockerConfig), remote, deployment_config.as(DeploymentAppConfig))
|
||||||
|
when DeploymentMariadbConfig then
|
||||||
|
DeploymentMariadb.new(local.as(LocalFileConfig), remote, deployment_config.as(DeploymentMariadbConfig))
|
||||||
|
when Nil
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
next if deployment.nil?
|
||||||
|
deployment.run
|
||||||
|
end
|
||||||
|
|
||||||
|
exit 2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
|
|
||||||
class Validation
|
|
||||||
def self.validate_config!(config)
|
|
||||||
pp config
|
|
||||||
config.deployments.each do |deployment_config|
|
|
||||||
Validation.validate_deployment!(config, deployment_config)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.validate_deployment!(config : Config, deployment : DeploymentConfig)
|
|
||||||
STDERR.puts "WARNING: validation for #{deployment.class} not yet implemented".colorize(:yellow)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue