ecs_compose 0.1.0.pre3 → 0.1.0.pre4

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 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