shipitron 1.2.0 → 1.4.0
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 +4 -4
- data/.buildkite/pipeline.yml +94 -0
- data/.dockerignore +1 -0
- data/.gitattributes +1 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Deskfile +15 -0
- data/Dockerfile +40 -15
- data/Dockerfile.release +29 -6
- data/Dockerfile.staging +70 -0
- data/Gemfile +2 -0
- data/README.md +53 -15
- data/docker-compose.yml +54 -0
- data/lib/shipitron.rb +19 -2
- data/lib/shipitron/cli.rb +42 -42
- data/lib/shipitron/client.rb +9 -0
- data/lib/shipitron/client/bootstrap_application.rb +1 -0
- data/lib/shipitron/client/create_ecs_services.rb +7 -7
- data/lib/shipitron/client/deploy_application.rb +2 -0
- data/lib/shipitron/client/ensure_deploy_not_running.rb +2 -1
- data/lib/shipitron/client/fetch_clusters.rb +1 -0
- data/lib/shipitron/client/force_deploy.rb +1 -0
- data/lib/shipitron/client/generate_deploy.rb +41 -0
- data/lib/shipitron/client/load_application_config.rb +17 -0
- data/lib/shipitron/client/load_templates.rb +1 -0
- data/lib/shipitron/client/register_ecs_task_definitions.rb +5 -5
- data/lib/shipitron/client/run_ecs_tasks.rb +101 -72
- data/lib/shipitron/docker_image.rb +4 -1
- data/lib/shipitron/find_docker_volume_name.rb +68 -0
- data/lib/shipitron/git_info.rb +57 -0
- data/lib/shipitron/mustache_yaml_parser.rb +12 -8
- data/lib/shipitron/s3_copy.rb +46 -0
- data/lib/shipitron/server/deploy_application.rb +2 -0
- data/lib/shipitron/server/docker/build_image.rb +4 -1
- data/lib/shipitron/server/docker/configure.rb +46 -10
- data/lib/shipitron/server/docker/push_image.rb +3 -0
- data/lib/shipitron/server/docker/run_build_script.rb +17 -10
- data/lib/shipitron/server/download_build_cache.rb +11 -3
- data/lib/shipitron/server/fetch_deploy.rb +50 -0
- data/lib/shipitron/server/git/clone_local_copy.rb +4 -5
- data/lib/shipitron/server/git/update_cache.rb +2 -1
- data/lib/shipitron/server/run_post_build.rb +40 -1
- data/lib/shipitron/server/transform_cli_args.rb +4 -0
- data/lib/shipitron/server/update_ecs_task_definitions.rb +2 -1
- data/lib/shipitron/server/upload_build_cache.rb +10 -9
- data/lib/shipitron/version.rb +1 -1
- data/scripts/docker-entrypoint.sh +37 -3
- data/scripts/release-entrypoint.sh +20 -0
- data/shipitron.gemspec +11 -8
- data/test.yml +5 -0
- metadata +78 -25
- data/build_dev.sh +0 -27
data/docker-compose.yml
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
version: '3.8'
|
2
|
+
services:
|
3
|
+
shipitron:
|
4
|
+
build: .
|
5
|
+
image: outstand/shipitron:dev
|
6
|
+
environment:
|
7
|
+
FIXUID:
|
8
|
+
FIXGID:
|
9
|
+
volumes:
|
10
|
+
- bundler-data:/usr/local/bundle
|
11
|
+
- ~/dev/app:/app # Set this to the application to be shipitron'd
|
12
|
+
- shipitron-home:/home/shipitron
|
13
|
+
- ~/.config/shipitron:/home/shipitron/.config/shipitron
|
14
|
+
- .:/shipitron
|
15
|
+
|
16
|
+
specs:
|
17
|
+
build: .
|
18
|
+
image: outstand/shipitron:dev
|
19
|
+
command: rspec
|
20
|
+
environment:
|
21
|
+
FOG_LOCAL: 'true'
|
22
|
+
FIXUID:
|
23
|
+
FIXGID:
|
24
|
+
BUILDKITE:
|
25
|
+
BUILDKITE_BUILD_URL:
|
26
|
+
BUILDKITE_JOB_ID:
|
27
|
+
BUILDKITE_AGENT_ACCESS_TOKEN:
|
28
|
+
working_dir: /shipitron
|
29
|
+
volumes:
|
30
|
+
- bundler-data:/usr/local/bundle
|
31
|
+
- fog:/fog
|
32
|
+
- shipitron-home:/home/shipitron
|
33
|
+
- .:/shipitron
|
34
|
+
|
35
|
+
release_gem:
|
36
|
+
image: outstand/shipitron:dev
|
37
|
+
command: rake release
|
38
|
+
working_dir: /shipitron
|
39
|
+
environment:
|
40
|
+
FIXUID:
|
41
|
+
FIXGID:
|
42
|
+
volumes:
|
43
|
+
- bundler-data:/usr/local/bundle
|
44
|
+
- shipitron-home:/home/shipitron
|
45
|
+
- .:/shipitron
|
46
|
+
- ~/.dotfiles/gitconfig:/root/.gitconfig
|
47
|
+
- ~/.dotfiles/gitconfig.user:/root/.gitconfig.user
|
48
|
+
- ~/.ssh/id_rsa:/root/.ssh/id_rsa
|
49
|
+
- ~/.gem:/root/.gem
|
50
|
+
|
51
|
+
volumes:
|
52
|
+
fog:
|
53
|
+
shipitron-home:
|
54
|
+
bundler-data:
|
data/lib/shipitron.rb
CHANGED
@@ -7,6 +7,8 @@ require 'shipitron/smash'
|
|
7
7
|
module Shipitron
|
8
8
|
CONFIG_FILE = 'shipitron/config.yml'.freeze
|
9
9
|
SECRETS_FILE = '~/.config/shipitron/secrets.yml'.freeze
|
10
|
+
GLOBAL_CONFIG_FILE = '~/.config/shipitron/config.yml'.freeze
|
11
|
+
DEPLOY_BUCKET_PREFIX = "deploys/"
|
10
12
|
|
11
13
|
class << self
|
12
14
|
def config_file
|
@@ -18,10 +20,10 @@ module Shipitron
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def config
|
21
|
-
@config ||= Smash.load(Pathname.new(config_file).expand_path.to_s).merge(secrets)
|
23
|
+
@config ||= Smash.load(Pathname.new(config_file).expand_path.to_s).merge(secrets).merge(global_config)
|
22
24
|
rescue ArgumentError
|
23
25
|
Logger.warn "Config file '#{config_file}' does not exist"
|
24
|
-
@config = secrets
|
26
|
+
@config = secrets.merge(global_config)
|
25
27
|
end
|
26
28
|
|
27
29
|
def secrets_file
|
@@ -38,5 +40,20 @@ module Shipitron
|
|
38
40
|
Logger.warn "Secrets file '#{secrets_file}' does not exist"
|
39
41
|
@secrets = Smash.new
|
40
42
|
end
|
43
|
+
|
44
|
+
def global_config_file
|
45
|
+
@global_config_file ||= GLOBAL_CONFIG_FILE
|
46
|
+
end
|
47
|
+
|
48
|
+
def global_config_file=(file)
|
49
|
+
@global_config_file = file
|
50
|
+
end
|
51
|
+
|
52
|
+
def global_config
|
53
|
+
@global_config ||= Smash.load(Pathname.new(global_config_file).expand_path.to_s)
|
54
|
+
rescue ArgumentError
|
55
|
+
Logger.warn "Global config file '#{global_config_file}' does not exist"
|
56
|
+
@global_config = Smash.new
|
57
|
+
end
|
41
58
|
end
|
42
59
|
end
|
data/lib/shipitron/cli.rb
CHANGED
@@ -12,22 +12,26 @@ module Shipitron
|
|
12
12
|
desc 'deploy <app>', 'Deploys the app'
|
13
13
|
option :config_file, default: 'shipitron/config.yml'
|
14
14
|
option :secrets_file, default: '~/.config/shipitron/secrets.yml'
|
15
|
+
option :global_config_file, default: '~/.config/shipitron/config.yml'
|
15
16
|
option :debug, type: :boolean, default: false
|
16
17
|
option :simulate, type: :boolean, default: false
|
18
|
+
option :simulate_store_deploy, type: :boolean, default: false, desc: "Simulate and store deploy config in S3"
|
17
19
|
def deploy(app)
|
18
20
|
setup(
|
19
21
|
config_file: options[:config_file],
|
20
|
-
secrets_file: options[:secrets_file]
|
22
|
+
secrets_file: options[:secrets_file],
|
23
|
+
global_config_file: options[:global_config_file]
|
21
24
|
)
|
22
25
|
|
23
26
|
require 'shipitron/client/deploy_application'
|
24
27
|
result = Client::DeployApplication.call(
|
25
28
|
application: app,
|
26
|
-
simulate: options[:simulate]
|
29
|
+
simulate: options[:simulate],
|
30
|
+
simulate_store_deploy: options[:simulate_store_deploy]
|
27
31
|
)
|
28
32
|
|
29
33
|
if result.failure?
|
30
|
-
result.
|
34
|
+
result.error_messages.each do |error|
|
31
35
|
Logger.fatal error
|
32
36
|
end
|
33
37
|
Logger.fatal 'Deploy failed.'
|
@@ -50,7 +54,7 @@ module Shipitron
|
|
50
54
|
)
|
51
55
|
|
52
56
|
if result.failure?
|
53
|
-
result.
|
57
|
+
result.error_messages.each do |error|
|
54
58
|
Logger.fatal error
|
55
59
|
end
|
56
60
|
Logger.fatal 'Deploy failed.'
|
@@ -59,45 +63,40 @@ module Shipitron
|
|
59
63
|
|
60
64
|
|
61
65
|
desc 'server_deploy', 'Server-side component of deploy'
|
62
|
-
option :
|
63
|
-
option :repository, required: true
|
64
|
-
option :repository_branch, default: 'master'
|
65
|
-
option :bucket, required: true
|
66
|
-
option :build_cache_location, default: 'tmp/build-cache.tar.gz'
|
67
|
-
option :image_name, required: true
|
68
|
-
option :named_tag, default: 'latest'
|
69
|
-
option :region, required: true
|
70
|
-
option :clusters, type: :array, required: true
|
71
|
-
option :ecs_task_defs, type: :array, required: true
|
72
|
-
option :ecs_task_def_templates, type: :array, default: []
|
73
|
-
option :ecs_services, type: :array, default: []
|
74
|
-
option :ecs_service_templates, type: :array, default: []
|
75
|
-
option :build_script, default: nil
|
76
|
-
option :post_builds, type: :array
|
77
|
-
option :secrets_file, default: '~/.config/shipitron/secrets.yml'
|
78
|
-
option :debug, type: :boolean, default: false
|
66
|
+
option :deploy_id, required: true
|
79
67
|
def server_deploy
|
80
|
-
setup
|
81
|
-
|
82
|
-
)
|
68
|
+
setup
|
69
|
+
|
70
|
+
if !ENV.key?("SHIPITRON_DEPLOY_BUCKET") || !ENV.key?("SHIPITRON_DEPLOY_BUCKET_REGION")
|
71
|
+
raise "Missing shipitron deploy bucket env vars!"
|
72
|
+
end
|
73
|
+
|
74
|
+
require 'shipitron/server/fetch_deploy'
|
75
|
+
deploy_options = Server::FetchDeploy.call!(
|
76
|
+
deploy_bucket: ENV["SHIPITRON_DEPLOY_BUCKET"],
|
77
|
+
deploy_bucket_region: ENV["SHIPITRON_DEPLOY_BUCKET_REGION"],
|
78
|
+
deploy_id: options[:deploy_id]
|
79
|
+
).deploy_options
|
83
80
|
|
84
81
|
require 'shipitron/server/transform_cli_args'
|
85
82
|
cli_args = Server::TransformCliArgs.call!(
|
86
|
-
application:
|
87
|
-
repository_url:
|
88
|
-
repository_branch:
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
83
|
+
application: deploy_options[:name],
|
84
|
+
repository_url: deploy_options[:repository],
|
85
|
+
repository_branch: deploy_options[:repository_branch],
|
86
|
+
registry: deploy_options[:registry],
|
87
|
+
s3_cache_bucket: deploy_options[:bucket],
|
88
|
+
build_cache_location: deploy_options[:build_cache_location],
|
89
|
+
image_name: deploy_options[:image_name],
|
90
|
+
named_tag: deploy_options[:named_tag],
|
91
|
+
skip_push: deploy_options[:skip_push],
|
92
|
+
region: deploy_options[:region],
|
93
|
+
clusters: deploy_options[:clusters],
|
94
|
+
ecs_task_defs: deploy_options[:ecs_task_defs],
|
95
|
+
ecs_task_def_templates: deploy_options[:ecs_task_def_templates],
|
96
|
+
ecs_services: deploy_options[:ecs_services],
|
97
|
+
ecs_service_templates: deploy_options[:ecs_service_templates],
|
98
|
+
build_script: deploy_options[:build_script],
|
99
|
+
post_builds: deploy_options[:post_builds]
|
101
100
|
).cli_args
|
102
101
|
|
103
102
|
require 'shipitron/server/deploy_application'
|
@@ -106,7 +105,7 @@ module Shipitron
|
|
106
105
|
)
|
107
106
|
|
108
107
|
if result.failure?
|
109
|
-
result.
|
108
|
+
result.error_messages.each do |error|
|
110
109
|
Logger.fatal error
|
111
110
|
end
|
112
111
|
Logger.fatal 'Deploy failed.'
|
@@ -137,7 +136,7 @@ module Shipitron
|
|
137
136
|
)
|
138
137
|
|
139
138
|
if result.failure?
|
140
|
-
result.
|
139
|
+
result.error_messages.each do |error|
|
141
140
|
Logger.fatal error
|
142
141
|
end
|
143
142
|
Logger.fatal 'Bootstrap failed.'
|
@@ -145,7 +144,7 @@ module Shipitron
|
|
145
144
|
end
|
146
145
|
|
147
146
|
private
|
148
|
-
def setup(config_file:nil, secrets_file:nil)
|
147
|
+
def setup(config_file:nil, secrets_file:nil, global_config_file:nil)
|
149
148
|
$stdout.sync = true
|
150
149
|
if options[:debug] == false
|
151
150
|
Logger.level = :info
|
@@ -153,6 +152,7 @@ module Shipitron
|
|
153
152
|
|
154
153
|
Shipitron.config_file = config_file unless config_file.nil?
|
155
154
|
Shipitron.secrets_file = secrets_file unless secrets_file.nil?
|
155
|
+
Shipitron.global_config_file = global_config_file unless global_config_file.nil?
|
156
156
|
end
|
157
157
|
end
|
158
158
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shipitron'
|
2
|
+
require 'shipitron/client'
|
2
3
|
require 'shipitron/ecs_client'
|
3
4
|
require 'shipitron/mustache_yaml_parser'
|
4
5
|
require 'securerandom'
|
@@ -29,13 +30,12 @@ module Shipitron
|
|
29
30
|
|
30
31
|
service_def = Smash.load(
|
31
32
|
path.to_s,
|
32
|
-
parser: MustacheYamlParser
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
)
|
33
|
+
parser: MustacheYamlParser,
|
34
|
+
context: {
|
35
|
+
cluster: cluster_name,
|
36
|
+
revision: nil, # ECS will default to latest ACTIVE
|
37
|
+
count: service_count
|
38
|
+
}
|
39
39
|
).merge(
|
40
40
|
client_token: SecureRandom.uuid
|
41
41
|
)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shipitron'
|
2
|
+
require 'shipitron/client'
|
2
3
|
require 'shipitron/client/load_application_config'
|
3
4
|
require 'shipitron/client/load_templates'
|
4
5
|
require 'shipitron/client/fetch_clusters'
|
@@ -13,6 +14,7 @@ module Shipitron
|
|
13
14
|
|
14
15
|
required :application
|
15
16
|
optional :simulate
|
17
|
+
optional :simulate_store_deploy
|
16
18
|
|
17
19
|
organize [
|
18
20
|
LoadApplicationConfig,
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shipitron'
|
2
|
+
require 'shipitron/client'
|
2
3
|
require 'shipitron/ecs_client'
|
3
4
|
|
4
5
|
# Note: This is a best effort client side check to make sure there
|
@@ -21,7 +22,7 @@ module Shipitron
|
|
21
22
|
begin
|
22
23
|
response = ecs_client(region: cluster.region).list_tasks(
|
23
24
|
cluster: cluster.name,
|
24
|
-
started_by:
|
25
|
+
started_by: Shipitron::Client.started_by,
|
25
26
|
max_results: 1,
|
26
27
|
desired_status: status
|
27
28
|
)
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'shipitron'
|
2
|
+
require 'shipitron/client'
|
3
|
+
require 'shipitron/fetch_bucket'
|
4
|
+
require 'aws-sdk-s3'
|
5
|
+
require 'pastel'
|
6
|
+
|
7
|
+
module Shipitron
|
8
|
+
module Client
|
9
|
+
class GenerateDeploy
|
10
|
+
include Metaractor
|
11
|
+
|
12
|
+
required :server_deploy_opts
|
13
|
+
required :deploy_id
|
14
|
+
|
15
|
+
def call
|
16
|
+
s3_key = "#{Shipitron::DEPLOY_BUCKET_PREFIX}#{context.deploy_id}"
|
17
|
+
pastel = Pastel.new
|
18
|
+
Logger.info "Uploading deploy config to #{pastel.blue("s3://#{deploy_bucket}/#{s3_key}")}"
|
19
|
+
|
20
|
+
client = Aws::S3::Client.new(region: deploy_bucket_region)
|
21
|
+
|
22
|
+
client.put_object(
|
23
|
+
bucket: deploy_bucket,
|
24
|
+
key: s3_key,
|
25
|
+
body: context.server_deploy_opts.to_json,
|
26
|
+
acl: "private"
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def deploy_bucket
|
33
|
+
Shipitron.config.deploy_bucket
|
34
|
+
end
|
35
|
+
|
36
|
+
def deploy_bucket_region
|
37
|
+
Shipitron.config.deploy_bucket_region
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'shipitron'
|
2
|
+
require 'shipitron/client'
|
2
3
|
require 'shipitron/post_build'
|
4
|
+
require 'aws-sdk-core'
|
3
5
|
|
4
6
|
module Shipitron
|
5
7
|
module Client
|
@@ -11,6 +13,7 @@ module Shipitron
|
|
11
13
|
def call
|
12
14
|
context.repository_url = config.repository
|
13
15
|
context.repository_branch = config.repository_branch
|
16
|
+
context.registry = config.registry
|
14
17
|
context.s3_cache_bucket = config.cache_bucket
|
15
18
|
context.build_cache_location = config.build_cache_location
|
16
19
|
context.image_name = config.image_name
|
@@ -21,6 +24,7 @@ module Shipitron
|
|
21
24
|
config.named_tag
|
22
25
|
end
|
23
26
|
end
|
27
|
+
context.skip_push = config.skip_push
|
24
28
|
context.build_script = config.build_script
|
25
29
|
context.post_builds = begin
|
26
30
|
if config.post_builds.nil?
|
@@ -35,6 +39,19 @@ module Shipitron
|
|
35
39
|
context.ecs_services = config.ecs_services
|
36
40
|
context.ecs_task_def_dir = config.ecs_task_def_dir
|
37
41
|
context.ecs_service_dir = config.ecs_service_dir
|
42
|
+
|
43
|
+
if Shipitron.config.aws_access_key_id? && Shipitron.config.aws_secret_access_key?
|
44
|
+
Aws.config.update(
|
45
|
+
credentials: Aws::Credentials.new(
|
46
|
+
Shipitron.config.aws_access_key_id,
|
47
|
+
Shipitron.config.aws_secret_access_key
|
48
|
+
)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
if !Shipitron.config.deploy_bucket? || !Shipitron.config.deploy_bucket_region?
|
53
|
+
raise "Missing required deploy bucket configuration!"
|
54
|
+
end
|
38
55
|
end
|
39
56
|
|
40
57
|
private
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shipitron'
|
2
|
+
require 'shipitron/client'
|
2
3
|
require 'shipitron/ecs_client'
|
3
4
|
require 'shipitron/mustache_yaml_parser'
|
4
5
|
|
@@ -26,11 +27,10 @@ module Shipitron
|
|
26
27
|
|
27
28
|
task_def = Smash.load(
|
28
29
|
path.to_s,
|
29
|
-
parser: MustacheYamlParser
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
)
|
30
|
+
parser: MustacheYamlParser,
|
31
|
+
context: {
|
32
|
+
tag: 'latest'
|
33
|
+
}
|
34
34
|
)
|
35
35
|
|
36
36
|
begin
|