ecs_compose 0.1.0.pre3 → 0.1.0.pre4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fbbe54755b0b5dec1afb9e69c2ac60f9596bfb5
4
- data.tar.gz: 7af5f4efec236b452d48cd59459b110c52ad54b2
3
+ metadata.gz: 03ed8e188cb8fa565118d8c2c16ba0356598cd7b
4
+ data.tar.gz: a415fe0ad3bfcaea20c8b099d9c912287c9c2050
5
5
  SHA512:
6
- metadata.gz: ce8958805db591750f41d0e1df666928ccd08a89b19f48ba550e3971819624b96b7364a021593fc5968fe09f159069eb164df097145dd94282907cc109e20f1f
7
- data.tar.gz: 2ad1d9684ebda80d7f77d24a4b41eac61d22a3b8f4c695b76198939b4a1d232e8028e1e344e659a8e3736aa75f9899f51ea5fb92cb2a47c46f1014ffdca2b1df
6
+ metadata.gz: eabf75635023f1d8cf4b4d040c181d46cb65e3086e00af95056f3efa14115902f418e15741e87431a3cf654f0c9ea5ba3a87eaa77e5bf89a00e8c703e97ad7f3
7
+ data.tar.gz: 1e718e40e5eed1a37a1c01c33652cbc4f5d030fbd715d6cc53016b3dd5e8f73b434ce160611d01b3b43150de1aac87c419de0137b0db70a32cc0b5345ea6bf15
data/README.md CHANGED
@@ -27,10 +27,13 @@ Or install it yourself as:
27
27
  Using the Amazon Web Services console, create a new ECS cluster and define a service `my-service`. Describe your service using a standard `docker-compose.yml` file. Then run:
28
28
 
29
29
  ```sh
30
- ecs-compose up my-service docker-compose.yml
30
+ ecs-compose -i service:my-service up
31
31
  ```
32
32
 
33
- This will update the task definition `my-service`, and then update the running copy of `my-service` to the new task definition.
33
+ This will update the task definition `my-service`, and then update the running copy of `my-service` to the new task definition. The `-i` argument specifies the ECS task type (a one-shot `task`, or a persistent `service`, as well as a value to use as the task definiton name and family name on ECS.
34
+
35
+ There's also a "manifest" mode that allows you to work with multiple
36
+ `docker-compose.yml` files, each defining a different service or task.
34
37
 
35
38
  ## Development
36
39
 
@@ -4,33 +4,116 @@ require "thor"
4
4
  module EcsCompose
5
5
  # Our basic command-line interface.
6
6
  class CLI < Thor
7
- class_option(:services, type: :string,
8
- desc: "A comma-separated list of containers to include. Defaults to all.")
9
-
10
- desc("conv FAMILY [YAML_FILE]",
11
- "Convert docker-compose.yml to ECS JSON format")
12
- def jsonify(family, yaml_file="docker-compose.yml")
13
- yaml = File.read(yaml_file)
14
- puts EcsCompose::JsonGenerator.new(family, yaml, services: services).json
7
+ DEFAULT_FILE = "docker-compose.yml"
8
+ DEFAULT_MANIFEST = "deploy/DEPLOY-MANIFEST.yml"
9
+
10
+ class_option(:manifest, type: :string,
11
+ aliases: %w(-m),
12
+ desc: "Manifest describing a set of tasks and services (takes precedence over --file) [default: #{DEFAULT_MANIFEST}]")
13
+ class_option(:file, type: :string,
14
+ aliases: %w(-f),
15
+ desc: "File describing a single task or service [default: #{DEFAULT_FILE}]")
16
+ class_option(:file_info, type: :string,
17
+ aliases: %w(-i),
18
+ desc: "Type and name for use with --file [ex: 'service:hello' or 'task:migrate']")
19
+
20
+ desc("up [SERVICES...]", "Register ECS task definitions and update services")
21
+ def up(*services)
22
+ available = manifest.task_definitions.select {|td| td.type == :service }
23
+ chosen = all_or_specified(available, services)
24
+
25
+ chosen.each do |service|
26
+ json = EcsCompose::JsonGenerator.new(service.name, service.yaml).json
27
+ EcsCompose::Ecs.update_service_with_json(service.name, json)
28
+ end
15
29
  end
16
30
 
17
- desc("up SERVICE [YAML_FILE]",
18
- "Update an ECS service to match YAML_FILE")
19
- def up(service, yaml_file="docker-compose.yml")
20
- yaml = File.read(yaml_file)
21
- json = EcsCompose::JsonGenerator.new(service, yaml, services: services).json
22
- EcsCompose::Ecs.update_service_with_json(service, json)
31
+ desc("register [TASK_DEFINITIONS...]", "Register ECS task definitions")
32
+ def register(*task_definitions)
33
+ available = manifest.task_definitions
34
+ chosen = all_or_specified(available, task_definitions)
35
+
36
+ chosen.each do |td|
37
+ json = EcsCompose::JsonGenerator.new(td.name, td.yaml).json
38
+ EcsCompose::Ecs.register_task_definition(json)
39
+ end
40
+ end
41
+
42
+ desc("json [TASK_DEFINITION]",
43
+ "Convert a task definition to ECS JSON format")
44
+ def json(task_definition=nil)
45
+ if task_definition.nil?
46
+ choices = manifest.task_definitions.map {|td| td.name }
47
+ case choices.length
48
+ when 0
49
+ fatal_err("Please supply a manifest with at least one task definition")
50
+ when 1
51
+ task_definition = choices.first
52
+ else
53
+ fatal_err("Please choose one of: #{choices.join(', ')}")
54
+ end
55
+ end
56
+
57
+ found = manifest.task_definitions.find {|td| td.name } or
58
+ fatal_err("Can't find task definition: #{task_definition}")
59
+ puts EcsCompose::JsonGenerator.new(found.name, found.yaml).json
23
60
  end
24
61
 
25
62
  protected
26
63
 
27
- # Parse our `services` option.
28
- def services
29
- if options[:services]
30
- options[:services].split(',')
64
+ # Choose either all items in `available`, or just those with the
65
+ # specified `names`.
66
+ def all_or_specified(available, names)
67
+ if names.empty?
68
+ available
31
69
  else
32
- nil
33
- end
70
+ available.select {|td| names.include?(td.name) }
71
+ end
72
+ end
73
+
74
+ # Figure out whether we have a manifest or a docker-compose.yml. We
75
+ # check supplied flags first, then defaults, and we prefer manifests
76
+ # when there's a tie.
77
+ def mode
78
+ @mode ||=
79
+ if options.manifest
80
+ :manifest
81
+ elsif options.file
82
+ :file
83
+ elsif File.exist?(DEFAULT_MANIFEST)
84
+ :manifest
85
+ elsif File.exist?(DEFAULT_FILE)
86
+ :file
87
+ else
88
+ fatal_err("Unable to find either #{DEFAULT_FILE} or #{DEFAULT_MANIFEST}")
89
+ end
90
+ end
91
+
92
+ # Create a manifest, either by reading it in, or synthesizing it from a
93
+ # `docker-compose.yml` file and some extra arguments.
94
+ def manifest
95
+ @manifest ||=
96
+ case mode
97
+ when :manifest
98
+ Manifest.read_from_manifest(options.manifest || DEFAULT_MANIFEST)
99
+ when :file
100
+ info = options.file_info
101
+ if info.nil?
102
+ fatal_err("Must pass -i option when using docker-compose.yml")
103
+ end
104
+ unless info =~ /\A(service|task):[-_A-Za-z0-9\z]/
105
+ fatal_err("Incorrectly formatted -i option")
106
+ end
107
+ Manifest.read_from_file(options.file || DEFAULT_FILE,
108
+ type.to_sym, name)
109
+ else raise "Unknown mode: #{mode}"
110
+ end
111
+ end
112
+
113
+ # Print an error and quit.
114
+ def fatal_err(msg)
115
+ STDERR.puts(msg.red)
116
+ exit(1)
34
117
  end
35
118
  end
36
119
  end
@@ -11,10 +11,9 @@ module EcsCompose
11
11
 
12
12
  # Create a new generator, specifying the family name to use, and the
13
13
  # raw YAML input.
14
- def initialize(family, yaml_text, services: nil)
14
+ def initialize(family, yaml_text)
15
15
  @family = family
16
16
  @yaml = Psych.load(yaml_text)
17
- @services = services
18
17
  end
19
18
 
20
19
  # Generate an ECS task definition as a raw Ruby hash.
@@ -51,11 +50,6 @@ module EcsCompose
51
50
  end
52
51
  end
53
52
 
54
- # Prune our services against a list if requested.
55
- if @services
56
- containers.select! {|c| @services.include?(c["name"]) }
57
- end
58
-
59
53
  {
60
54
  "family" => @family,
61
55
  "containerDefinitions" => containers,
@@ -0,0 +1,30 @@
1
+ require 'psych'
2
+
3
+ module EcsCompose
4
+
5
+ # A collection of multiple task definitions, including names and types.
6
+ class Manifest
7
+ # Build a manifest from a single `docker-compose.yml` file, using the
8
+ # supplied type and name.
9
+ def self.read_from_file(path, type, name)
10
+ new([TaskDefinition.new(type, name, File.read(path))])
11
+ end
12
+
13
+ # Read in a complete manifest.
14
+ def self.read_from_manifest(path)
15
+ dir = File.dirname(path)
16
+ defs = Psych.load_file(path)['task_definitions'].map do |name, info|
17
+ TaskDefinition.new(info['type'].to_sym,
18
+ name,
19
+ File.read(File.join(dir, info['path'])))
20
+ end
21
+ new(defs)
22
+ end
23
+
24
+ attr_reader :task_definitions
25
+
26
+ def initialize(task_definitions)
27
+ @task_definitions = task_definitions
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ module EcsCompose
2
+
3
+ # Information required to create an ECS task definition.
4
+ class TaskDefinition
5
+ attr_reader :type, :name, :yaml
6
+
7
+ def initialize(type, name, yaml)
8
+ @name = name
9
+ @type = type
10
+ @yaml = yaml
11
+ end
12
+ end
13
+ end
data/lib/ecs_compose.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require "ecs_compose/version"
2
2
  require "ecs_compose/json_generator"
3
3
  require "ecs_compose/ecs"
4
+ require "ecs_compose/task_definition"
5
+ require "ecs_compose/manifest"
4
6
 
5
7
  module EcsCompose
6
8
  # Your code goes here...
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecs_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre3
4
+ version: 0.1.0.pre4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kidd
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-08-03 00:00:00.000000000 Z
11
+ date: 2015-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -107,6 +107,8 @@ files:
107
107
  - lib/ecs_compose/cli.rb
108
108
  - lib/ecs_compose/ecs.rb
109
109
  - lib/ecs_compose/json_generator.rb
110
+ - lib/ecs_compose/manifest.rb
111
+ - lib/ecs_compose/task_definition.rb
110
112
  - lib/ecs_compose/version.rb
111
113
  - publish.sh
112
114
  homepage: https://github.com/faradayio/ecs_compose