diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..6880d49 --- /dev/null +++ b/TODO.md @@ -0,0 +1,9 @@ +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 + diff --git a/doc/pushokku-v3.yml b/doc/pushokku-v3.yml new file mode 100644 index 0000000..9087f1e --- /dev/null +++ b/doc/pushokku-v3.yml @@ -0,0 +1,61 @@ +--- +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 diff --git a/src/config.cr b/src/config.cr index f11d5c9..a95e580 100644 --- a/src/config.cr +++ b/src/config.cr @@ -1,9 +1,13 @@ require "yaml" -require "./config/config" -require "./config/local" -require "./config/remote" -require "./config/deployment" - - +require "./config/*" +class Config + YAML.mapping( + version: String, + hosts: Array(HostConfig), + endpoints: Array(EndpointConfig), + filters: Array(FilterConfig), + deployments: Array(DeploymentConfig) + ) +end diff --git a/src/config/config.cr b/src/config/config.cr deleted file mode 100644 index c6856a0..0000000 --- a/src/config/config.cr +++ /dev/null @@ -1,14 +0,0 @@ - -require "yaml" -require "./local" -require "./remote" -require "./deployment" - -class Config - YAML.mapping( - version: String, - locals: Array(LocalConfig), - remotes: Array(RemoteConfig), - deployments: Array(DeploymentConfig) - ) -end diff --git a/src/config/deployment.cr b/src/config/deployment.cr index 23f0168..469968b 100644 --- a/src/config/deployment.cr +++ b/src/config/deployment.cr @@ -1,37 +1,21 @@ require "yaml" +require "./deployment_settings" -class DokkuMariadbConfig +class RunDeploymentConfig YAML.mapping( - name: String, - options: YAML::Any | Nil + name: String?, + run: RunDeploymentConfigSettings ) end -class DokkuAppConfig +class TransferDeploymentConfig YAML.mapping( - name: String, - 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, + name: String?, + transfer: TransferDeploymentConfigSettings ) end alias DeploymentConfig = - DeploymentMariadbConfig | - DeploymentAppConfig - + TransferDeploymentConfig | + RunDeploymentConfig diff --git a/src/config/deployment_settings.cr b/src/config/deployment_settings.cr new file mode 100644 index 0000000..82fdc46 --- /dev/null +++ b/src/config/deployment_settings.cr @@ -0,0 +1,17 @@ + +require "yaml" + +class TransferDeploymentConfigSettings + YAML.mapping( + src: String, + dest: String, + filters: Array(String)? + ) +end + +class RunDeploymentConfigSettings + YAML.mapping( + src: String, + dest: String, + ) +end diff --git a/src/config/endpoint.cr b/src/config/endpoint.cr new file mode 100644 index 0000000..c7648a9 --- /dev/null +++ b/src/config/endpoint.cr @@ -0,0 +1,52 @@ + +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 + diff --git a/src/config/endpoint_settings.cr b/src/config/endpoint_settings.cr new file mode 100644 index 0000000..27e4309 --- /dev/null +++ b/src/config/endpoint_settings.cr @@ -0,0 +1,37 @@ + +require "yaml" + +class DokkuMariadbEndpointConfigSettings + YAML.mapping( + name: String + ) +end + +class DokkuAppEndpointConfigSettings + YAML.mapping( + name: String + ) +end + +class DockerImageEndpointConfigSettings + YAML.mapping( + tag: { + type: String, + nilable: false, + default: "latest" + } + ) +end + +class MysqlDumpEndpointConfigSettings + YAML.mapping( + path: String + ) +end + +class ScriptEndpointConfigSettings + YAML.mapping( + path: String + ) +end + diff --git a/src/config/filter.cr b/src/config/filter.cr new file mode 100644 index 0000000..cb81622 --- /dev/null +++ b/src/config/filter.cr @@ -0,0 +1,22 @@ + +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 diff --git a/src/config/filter_settings.cr b/src/config/filter_settings.cr new file mode 100644 index 0000000..fc2be9d --- /dev/null +++ b/src/config/filter_settings.cr @@ -0,0 +1,9 @@ + +require "yaml" + +class DualFilterConfigSettings + YAML.mapping( + cmd_in: String, + cmd_out: String, + ) +end diff --git a/src/config/host.cr b/src/config/host.cr new file mode 100644 index 0000000..56de618 --- /dev/null +++ b/src/config/host.cr @@ -0,0 +1,22 @@ + +require "yaml" +require "./host_settings" + +class LocalHostConfig + YAML.mapping( + name: String, + localhost: Hash(String, YAML::Any) + ) +end + + +class SshHostConfig + YAML.mapping( + name: String, + ssh: SshHostConfigSettings + ) +end + +alias HostConfig = + LocalHostConfig | + SshHostConfig diff --git a/src/config/remote.cr b/src/config/host_settings.cr similarity index 66% rename from src/config/remote.cr rename to src/config/host_settings.cr index 8963a7e..703fc9a 100644 --- a/src/config/remote.cr +++ b/src/config/host_settings.cr @@ -1,11 +1,9 @@ require "yaml" -class RemoteConfig +class SshHostConfigSettings YAML.mapping( - name: String, user: String, host: String ) end - diff --git a/src/config/local.cr b/src/config/local.cr deleted file mode 100644 index a5f4856..0000000 --- a/src/config/local.cr +++ /dev/null @@ -1,32 +0,0 @@ - -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 - diff --git a/src/deployment/docker_image_to_dokku_app.cr b/src/deployment/docker_image_to_dokku_app.cr index 808d15c..e684437 100644 --- a/src/deployment/docker_image_to_dokku_app.cr +++ b/src/deployment/docker_image_to_dokku_app.cr @@ -1,8 +1,8 @@ require "colorize" -class DeploymentApp - def initialize(@local : LocalDockerConfig, @remote : RemoteConfig, @deployment : DeploymentAppConfig) +class DockerImageToDokkuAppDeployment + def initialize(@local : DockerImageLocalConfig, @remote : RemoteConfig, @deployment : DokkuAppDeploymentConfig) end def run diff --git a/src/deployment/mysql_dump_to_dokku_mariadb.cr b/src/deployment/mysql_dump_to_dokku_mariadb.cr index 4f6c775..60005f1 100644 --- a/src/deployment/mysql_dump_to_dokku_mariadb.cr +++ b/src/deployment/mysql_dump_to_dokku_mariadb.cr @@ -1,5 +1,5 @@ -class DeploymentMariadb +class MysqlDumpToDokkuMariadbDeployment def initialize(@local : LocalFileConfig, @remote : RemoteConfig, @deployment : DeploymentMariadbConfig) end diff --git a/src/pushokku.cr b/src/pushokku.cr index fd5eed4..c04a723 100644 --- a/src/pushokku.cr +++ b/src/pushokku.cr @@ -75,41 +75,74 @@ module Pushokku end - def self.run(args) - app = Cli.new - opts = app.parse_options(args) - config = app.load_config(opts["config_file"]) - # env_config = App.get_config(config, opts["environment"]) - - config.deployments.each do |deployment_config| + def self.handle_deployment(config : Config, deployment_config : DeploymentConfig) local = config.locals.select { |l| l.name == deployment_config.local }.first 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 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 - exit 2 + + def self.find_filter(config, name) + matches = config.filters.select { |filter| filter.name == name } + if matches.size > 1 + raise "Multiple filters have the same name (unicity)" + end + return matches.first + end + + def self.validate_config!(config) + pp config + #config.deployments.each do |deployment_config| + # handle_deployment(config, deployment_config) + #end + end + + def self.apply_config!(config) + config.deployments.each do |deployment_config| + # handle_deployment(config, deployment_config) + end + end + + def self.run(args) + app = Cli.new + opts = app.parse_options(args) + config = app.load_config(opts["config_file"]) + # env_config = App.get_config(config, opts["environment"]) + + validate_config!(config) + apply_config!(config) + + exit 0 end end end