ddsl 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f71118bf1db75829c800cdc9a8f8be55a563f22b
4
+ data.tar.gz: 4009fa8ce03a9c76b085e8b5fdc01ad5f37a27b1
5
+ SHA512:
6
+ metadata.gz: c5994bb90f41a8f49358f9ef9f1b76c1bbb40d6693c933d390d89f6b7b118bc4f4c59f917f341fc273441895f889343307ca955b596ae3e2f957a447499d7890
7
+ data.tar.gz: 8399bd7b709813fe7fafba8fe51a1bf9ee2b256be72a49fc417c22f2097bd80d765a3e238a51bac20bed710db1db4e16c8abd328cfe74d9dee62bcec6a79a34d
@@ -0,0 +1,56 @@
1
+ version: 2
2
+
3
+ docker_options: &docker_options
4
+ working_directory: ~/ddsl
5
+ docker:
6
+ - image: bilby91/ddsl:latest
7
+ auth:
8
+ username: $DOCKER_REGISTRY_USERNAME
9
+ password: $DOCKER_REGISTRY_PASSWORD
10
+
11
+ workflows:
12
+ version: 2
13
+ build-deploy:
14
+ jobs:
15
+ - build
16
+ - test:
17
+ requires:
18
+ - build
19
+ - lint:
20
+ requires:
21
+ - build
22
+
23
+ jobs:
24
+ build:
25
+ <<: *docker_options
26
+ steps:
27
+ - checkout
28
+ - setup_remote_docker
29
+ - run:
30
+ command: echo "$DOCKER_REGISTRY_PASSWORD" | docker login --username $DOCKER_REGISTRY_USERNAME --password-stdin
31
+ - run:
32
+ command: |
33
+ export CI_SHA1=$CIRCLE_SHA1
34
+ ddsl build feature-branch
35
+ test:
36
+ <<: *docker_options
37
+ steps:
38
+ - checkout
39
+ - setup_remote_docker
40
+ - run:
41
+ command: echo "$DOCKER_REGISTRY_PASSWORD" | docker login --username $DOCKER_REGISTRY_USERNAME --password-stdin
42
+ - run:
43
+ command: |
44
+ export CI_SHA1=$CIRCLE_SHA1
45
+ ddsl run test-ci
46
+ lint:
47
+ <<: *docker_options
48
+ steps:
49
+ - checkout
50
+ - setup_remote_docker
51
+ - run:
52
+ command: echo "$DOCKER_REGISTRY_PASSWORD" | docker login --username $DOCKER_REGISTRY_USERNAME --password-stdin
53
+ - run:
54
+ command: |
55
+ export CI_SHA1=$CIRCLE_SHA1
56
+ ddsl run lint-ci
data/.ddsl.yml ADDED
@@ -0,0 +1,48 @@
1
+ version: 1
2
+
3
+ builds:
4
+ - name: feature-branch
5
+ type: docker
6
+ context: .
7
+ file: docker/Dockerfile
8
+ tags:
9
+ - bilby91/ddsl:$CI_SHA1
10
+ push: true
11
+ cache_from:
12
+ - bilby91/ddsl:latest
13
+ - name: master-branch
14
+ type: docker
15
+ context: .
16
+ file: docker/Dockerfile
17
+ tags:
18
+ - bilby91/ddsl:$CI_SHA1
19
+ - bilby91/ddsl:latest
20
+ push: true
21
+ cache_from:
22
+ - bilby91/ddsl:latest
23
+ - name: dev
24
+ type: docker-compose
25
+ file: docker/docker-compose.yml
26
+
27
+ runs:
28
+ - name: bash
29
+ type: docker-compose
30
+ file: docker/docker-compose.yml
31
+ service: ddsl
32
+ cmd: /bin/bash
33
+ - name: test-ci
34
+ type: docker
35
+ image: bilby91/ddsl:$CI_SHA1
36
+ cmd: rspec spec .
37
+ - name: test
38
+ type: docker
39
+ image: bilby91/ddsl:latest
40
+ cmd: rspec spec .
41
+ - name: lint-ci
42
+ type: docker
43
+ image: bilby91/ddsl:$CI_SHA1
44
+ cmd: rubocop .
45
+ - name: lint
46
+ type: docker
47
+ image: bilby91/ddsl:latest
48
+ cmd: rubocop .
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ # Code Coverage
2
+ coverage
3
+
4
+ # Compiled gem
5
+ *.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,19 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+
4
+ Metrics/LineLength:
5
+ Max: 120
6
+
7
+ Metrics/MethodLength:
8
+ Max: 15
9
+
10
+ Metrics/BlockLength:
11
+ Exclude:
12
+ - 'spec/**/*.rb'
13
+
14
+ Style/Documentation:
15
+ Enabled: false
16
+
17
+ Style/AccessModifierDeclarations:
18
+ EnforcedStyle: inline
19
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ddsl (0.0.1)
5
+ clamp (~> 1)
6
+ json-schema (~> 2)
7
+ transproc (~> 1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.5.2)
13
+ public_suffix (>= 2.0.2, < 4.0)
14
+ ast (2.4.0)
15
+ clamp (1.3.0)
16
+ diff-lcs (1.3)
17
+ docile (1.3.1)
18
+ jaro_winkler (1.5.1)
19
+ json (2.1.0)
20
+ json-schema (2.8.1)
21
+ addressable (>= 2.4)
22
+ parallel (1.12.1)
23
+ parser (2.5.3.0)
24
+ ast (~> 2.4.0)
25
+ powerpack (0.1.2)
26
+ public_suffix (3.0.3)
27
+ rainbow (3.0.0)
28
+ rspec (3.8.0)
29
+ rspec-core (~> 3.8.0)
30
+ rspec-expectations (~> 3.8.0)
31
+ rspec-mocks (~> 3.8.0)
32
+ rspec-core (3.8.0)
33
+ rspec-support (~> 3.8.0)
34
+ rspec-expectations (3.8.2)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.8.0)
37
+ rspec-mocks (3.8.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.8.0)
40
+ rspec-support (3.8.0)
41
+ rubocop (0.60.0)
42
+ jaro_winkler (~> 1.5.1)
43
+ parallel (~> 1.10)
44
+ parser (>= 2.5, != 2.5.1.1)
45
+ powerpack (~> 0.1)
46
+ rainbow (>= 2.2.2, < 4.0)
47
+ ruby-progressbar (~> 1.7)
48
+ unicode-display_width (~> 1.4.0)
49
+ ruby-progressbar (1.10.0)
50
+ simplecov (0.16.1)
51
+ docile (~> 1.1)
52
+ json (>= 1.8, < 3)
53
+ simplecov-html (~> 0.10.0)
54
+ simplecov-html (0.10.2)
55
+ transproc (1.0.2)
56
+ unicode-display_width (1.4.0)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ ddsl!
63
+ rspec (~> 3)
64
+ rubocop (~> 0.60)
65
+ simplecov (~> 0.16)
66
+
67
+ BUNDLED WITH
68
+ 1.17.1
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # ddsl
2
+
3
+ Docker Declarative Specific Language
4
+
5
+ `ddsl` lets you declare how your docker images are built and what checks (test, linter, etc) need be run in your images.
6
+
7
+ ```yaml
8
+ version: 1
9
+
10
+ builds:
11
+ - name: main
12
+ type: docker
13
+ context: .
14
+ file: docker/Dockerfile
15
+ tags:
16
+ - bilby91/ddsl:latest
17
+ - name: dev
18
+ type: docker-compose
19
+ file: docker/docker-compose.yml
20
+
21
+ runs:
22
+ - name: bash
23
+ type: docker-compose
24
+ file: docker/docker-compose.yml
25
+ service: ddsl
26
+ cmd: /bin/bash
27
+
28
+ - name: test
29
+ type: docker
30
+ image: bilby91/ddsl:latest
31
+ cmd: rspec spec .
32
+
33
+ - name: lint
34
+ type: docker
35
+ image: bilby91/ddsl:latest
36
+ cmd: rubocop .
37
+ ```
38
+
39
+ ## Dependencies
40
+
41
+ - ruby
42
+ - docker
43
+ - docker-compose
44
+
45
+ ## TODO
46
+
47
+ - [X] Docker Compose support
48
+ - [X] Variable interpolation
49
+ - [X] Build/Test DDSL using DDSL. Inception :)
50
+ - [ ] Add CI GitLab
51
+ - [ ] Add CI Travis
52
+ - [ ] Variable sharing/reusing
53
+ - [ ] Registries?
54
+ - [ ] External secret proviers ? (KMS, Google?)
55
+
56
+ ## Contact
57
+
58
+ - Martín Fernández <mfernandez@geofore.com>
data/bin/ddsl ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/ddsl'
5
+
6
+ DDSL::CLI.run
data/bin/dev ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+
3
+ export COMPOSE_FILE=docker/docker-compose.yml
4
+
5
+ case "$1" in
6
+ bash)
7
+ docker-compose run --rm ddsl /bin/bash
8
+ ;;
9
+ build)
10
+ docker-compose build
11
+ ;;
12
+ down)
13
+ docker-compose down
14
+ ;;
15
+ esac
data/ddsl.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'ddsl/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'ddsl'
9
+ spec.version = DDSL::VERSION
10
+ spec.homepage = 'https://github.com/bilby91/ddsl'
11
+ spec.license = 'MIT'
12
+ spec.authors = ['Martin Fernandez']
13
+ spec.email = ['fmartin91@gmail.com']
14
+ spec.summary = 'Docker Declarative Specific Language'
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.executables = ['ddsl']
19
+ spec.require_paths = ['lib']
20
+ spec.add_dependency 'clamp', '~> 1'
21
+ spec.add_dependency 'json-schema', '~> 2'
22
+ spec.add_dependency 'transproc', '~> 1'
23
+ spec.add_development_dependency 'rspec', '~> 3'
24
+ spec.add_development_dependency 'rubocop', '~> 0.60'
25
+ spec.add_development_dependency 'simplecov', '~> 0.16'
26
+ end
data/docker/Dockerfile ADDED
@@ -0,0 +1,44 @@
1
+ FROM docker:18.05
2
+
3
+ LABEL maintainer="Martín Fernández <mfernandez@geoforce.com>"
4
+
5
+ ENV APP_HOME /var/www/app
6
+
7
+ # Install the base tooling
8
+ RUN apk add --no-cache \
9
+ build-base \
10
+ gcc \
11
+ python \
12
+ py-pip \
13
+ python-dev \
14
+ gettext \
15
+ curl \
16
+ bash \
17
+ git \
18
+ ruby \
19
+ ruby-dev \
20
+ ruby-bigdecimal
21
+
22
+ # Install docker-compose
23
+ RUN pip install docker-compose
24
+
25
+ # Install ruby dependencies
26
+ RUN gem install bundler --no-ri
27
+
28
+ WORKDIR ${APP_HOME}
29
+
30
+ # Copy only Gemfile for caching
31
+ COPY lib/ddsl/version.rb $APP_HOME/lib/ddsl/version.rb
32
+ COPY Gemfile* *.gemspec $APP_HOME/
33
+
34
+ # Install ruby dependencies
35
+ RUN bundle install
36
+
37
+ # COPY app to container
38
+ COPY . $APP_HOME
39
+
40
+ # Build the gem locally
41
+ RUN bundle exec gem build ddsl.gemspec
42
+
43
+ # Install binary
44
+ RUN bundle exec gem install --no-rdoc --no-ri --local ddsl-0.0.1.gem
@@ -0,0 +1,34 @@
1
+ FROM docker:18.05
2
+
3
+ LABEL maintainer="Martín Fernández <mfernandez@geoforce.com>"
4
+
5
+ ENV APP_HOME /var/www/app
6
+
7
+ # Install the base tooling
8
+ RUN apk add --no-cache \
9
+ build-base \
10
+ gcc \
11
+ python \
12
+ py-pip \
13
+ python-dev \
14
+ gettext \
15
+ curl \
16
+ bash \
17
+ git \
18
+ ruby \
19
+ ruby-dev \
20
+ ruby-bigdecimal
21
+
22
+ # Install untrusted packages (separate line for scoping)
23
+ RUN apk add --no-cache \
24
+ --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ \
25
+ --allow-untrusted \
26
+ aws-cli
27
+
28
+ # Install docker-compose
29
+ RUN pip install docker-compose
30
+
31
+ # Install ruby dependencies
32
+ RUN gem install builder bundler --no-ri
33
+
34
+ WORKDIR ${APP_HOME}
@@ -0,0 +1,22 @@
1
+ version: '3'
2
+
3
+ volumes:
4
+ ddsl_bundle:
5
+
6
+ services:
7
+ dind:
8
+ image: docker:dind
9
+ privileged: true
10
+ ddsl:
11
+ build:
12
+ context: ../
13
+ dockerfile: docker/Dockerfile.dev
14
+ environment:
15
+ BUNDLE_PATH: /bundle
16
+ DOCKER_HOST: tcp://dind:2375
17
+ volumes:
18
+ - ../:/var/www/app:cached
19
+ - ddsl_bundle:/bundle:cached
20
+ - ~/.bash_history:/root/.bash_history
21
+ depends_on:
22
+ - dind
data/lib/ddsl/cli.rb ADDED
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'clamp'
4
+
5
+ require_relative './parser'
6
+ require_relative './variable_injector'
7
+ require_relative './shell'
8
+ require_relative './command'
9
+
10
+ module DDSL
11
+ class CLI < Clamp::Command
12
+ option '--config', 'CONFIG', 'Configuration file path'
13
+
14
+ subcommand 'build', 'Build the docker image associated with the project' do
15
+ parameter 'NAME ...', 'name of the build', required: true, attribute_name: :names
16
+
17
+ def execute
18
+ with_builder(search_targets!('builds')) do |runner, spec|
19
+ begin
20
+ runner.run(spec)
21
+ rescue DDSL::Shell::ExitStatusError
22
+ $stdout.puts 'Build failed.'
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ subcommand 'run', 'Run a docker container or docker-compose service' do
29
+ parameter 'NAME ...', 'name of the run', required: true, attribute_name: :names
30
+
31
+ def execute
32
+ with_runner(search_targets!('runs')) do |runner, spec|
33
+ begin
34
+ runner.run(spec)
35
+ rescue DDSL::Shell::ExitStatusError
36
+ $stdout.puts 'Run failed.'
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ private def with_builder(builds)
43
+ builds.map do |b|
44
+ yield(builder_for_type(b['type']), b)
45
+ end
46
+ end
47
+
48
+ private def with_runner(runs)
49
+ runs.map do |r|
50
+ yield(runner_for_type(r['type']), r)
51
+ end
52
+ end
53
+
54
+ private def runner_for_type(type)
55
+ case type
56
+ when 'docker'
57
+ Command::Docker::Run.new
58
+ when 'docker-compose'
59
+ Command::DockerCompose::Run.new
60
+ end
61
+ end
62
+
63
+ private def builder_for_type(type)
64
+ case type
65
+ when 'docker'
66
+ Command::Docker::Build.new
67
+ when 'docker-compose'
68
+ Command::DockerCompose::Build.new
69
+ end
70
+ end
71
+
72
+ private def search_targets!(type)
73
+ command_targets = targets(type)
74
+ raise Clamp::UsageError.new('invalid NAME given', type) unless command_targets.count == names.count
75
+
76
+ command_targets
77
+ end
78
+
79
+ private def targets(type)
80
+ parsed_config[type].select { |item| names.include? item['name'] }
81
+ end
82
+
83
+ private def config_path
84
+ @config_path ||= config || '.ddsl.yml'
85
+ end
86
+
87
+ private def parsed_config
88
+ @parsed_config ||= DDSL::VariableInjector.new(ENV).inject(
89
+ DDSL::Parser.new.parse(config_path)
90
+ )
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './dsl'
4
+
5
+ module DDSL
6
+ module Command
7
+ class Base
8
+ include DSL
9
+
10
+ attr_reader :shell
11
+
12
+ def initialize(shell = DDSL::Shell.new)
13
+ @shell = shell
14
+ end
15
+
16
+ def run(spec)
17
+ argv = [
18
+ executable,
19
+ executable_options.call(spec),
20
+ command,
21
+ options.call(spec),
22
+ arguments.call(spec).values
23
+ ].flatten
24
+
25
+ @shell.call!(argv)
26
+
27
+ exec_after_block(spec)
28
+ end
29
+
30
+ def exec_after_block(spec)
31
+ instance_exec(spec, &after_block) unless after_block.nil?
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base'
4
+
5
+ module DDSL
6
+ module Command
7
+ module Docker
8
+ class Build < Base
9
+ executable 'docker'
10
+ command 'build'
11
+
12
+ options do
13
+ accept_keys(%w[
14
+ build_args file cache_from tags labels rm
15
+ ])
16
+
17
+ rename_keys(
18
+ 'build_args' => 'build_arg',
19
+ 'tags' => 'tag',
20
+ 'labels' => 'label'
21
+ )
22
+
23
+ optionize_keys
24
+ expand_options
25
+ end
26
+
27
+ arguments do
28
+ accept_keys(['context'])
29
+ end
30
+
31
+ after do |spec|
32
+ spec['tags'].each { |t| Push.new(shell).run('image' => t) } if spec['push'] && spec['tags'].count.positive?
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base'
4
+
5
+ module DDSL
6
+ module Command
7
+ module Docker
8
+ class Push < Base
9
+ executable 'docker'
10
+ command 'push'
11
+
12
+ arguments do
13
+ accept_keys(['image'])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base'
4
+
5
+ module DDSL
6
+ module Command
7
+ module Docker
8
+ class Run < Base
9
+ executable 'docker'
10
+ command 'run'
11
+
12
+ options do
13
+ accept_keys(%w[
14
+ rm envs volumes ports
15
+ ])
16
+
17
+ rename_keys(
18
+ 'envs' => 'env',
19
+ 'volumes' => 'volume',
20
+ 'ports' => 'publish'
21
+ )
22
+
23
+ optionize_keys
24
+ expand_options
25
+ end
26
+
27
+ arguments do
28
+ accept_keys(%w[image cmd])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base'
4
+
5
+ module DDSL
6
+ module Command
7
+ module DockerCompose
8
+ class Build < Base
9
+ executable 'docker-compose'
10
+ command 'build'
11
+
12
+ executable_options do
13
+ accept_keys([
14
+ 'file'
15
+ ])
16
+
17
+ optionize_keys
18
+ expand_options
19
+ end
20
+
21
+ options do
22
+ accept_keys(%w[
23
+ build_args memory parallel compress force_rm pull no_cache
24
+ ])
25
+
26
+ rename_keys(
27
+ 'build_args' => 'build_arg'
28
+ )
29
+
30
+ optionize_keys
31
+ expand_options
32
+ end
33
+
34
+ arguments do
35
+ accept_keys(['service'])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end