etcenv 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c67fca7ce92b7e16d5365bdc969aa6e974fc6cc9
4
- data.tar.gz: 99ad3db08fcc4e806a677cfe085bb475e1dceab7
3
+ metadata.gz: e08b420a67f38847ae025f781cbedb6484a0af74
4
+ data.tar.gz: 84cc434c7876ceb2f31e0158dde5665d4d005d73
5
5
  SHA512:
6
- metadata.gz: 3c1e239945d4bbbd0735f3f8ec451eab0da1ca607cdbfd9390543b10aec9718364ec51081fa521343d9d05607b55357fc73b8a2f2ff45a22f83d568edb26ea22
7
- data.tar.gz: d5b380c6fa77885aa7d0d1d522b185184fa959a9f6864018b01696061451aeea356b47f84a09e9adf9ae93f1e0f2b848928016c8e2415cb6b322a5d67fef7479
6
+ metadata.gz: 033c93840d0379655f653c87a5fcd551b171489c6bd24d859dda7be495b3c1ce45c831f53e98916acd31fdfea25d87ae8ed84a10975a28836c9b00e04e373c65
7
+ data.tar.gz: fa114bfa98c149a549cd0c68b1424b758ee57fb30a7d8d2a25a1919639ae49de6490925fc5f193978dd4acff3efce79b3fa84bc405ab908c267cdb50760fb198
data/README.md CHANGED
@@ -67,12 +67,12 @@ In docker mode, etcenv evaluates `${...}` expansion like dotenv do.
67
67
 
68
68
  ### Include other directory's variables
69
69
 
70
- Set directory path to `_include`. Directories can be specified multiple, separated by comma.
70
+ Set directory path to `.include`. Directories can be specified multiple, separated by comma.
71
71
 
72
72
  ```
73
73
  etcdctl mkdir /common
74
74
  etcdctl set /common/COMMON_SECRET xxx
75
- etcdctl set /my-app/_include /common
75
+ etcdctl set /my-app/.include /common
76
76
  ```
77
77
 
78
78
  Also, you can omit path of parent directory:
@@ -82,11 +82,11 @@ etcdctl mkdir /envs/common
82
82
  etcdctl set /envs/common/COMMON_SECRET xxx
83
83
 
84
84
  etcdctl mkdir /envs/my-app
85
- etcdctl set /envs/my-app/_include common
85
+ etcdctl set /envs/my-app/.include common
86
86
  ```
87
87
 
88
- - `_include` will be applied recursively (up to 10 times by default). If `_include` is looping, it'll be an error.
89
- - For multiple `_include`, value for same key may be overwritten.
88
+ - `.include` will be applied recursively (up to 10 times by default). If `.include` is looping, it'll be an error.
89
+ - For multiple `.include`, value for same key may be overwritten.
90
90
  - If `a` includes `b`,`c` and `b` includes `d`, result for `a` will be: `d`, `b`, `c`, then `a`.
91
91
 
92
92
  ## Development
data/lib/etcenv/cli.rb CHANGED
@@ -104,7 +104,7 @@ module Etcenv
104
104
  return 1
105
105
  end
106
106
  env = argv.inject(nil) do |env, key|
107
- new_env = Environment.new(etcd, key).env
107
+ new_env = Environment.new(etcd, key).expanded_env
108
108
  env ? env.merge(new_env) : new_env
109
109
  end
110
110
  dump_env(env)
@@ -129,7 +129,6 @@ module Etcenv
129
129
  envs = argv.map { |key| Environment.new(etcd, key) }
130
130
 
131
131
  watchers = envs.map { |env| Watcher.new(env, verbose: true) }
132
- Thread.abort_on_exception = true
133
132
 
134
133
  dumper_ch = Queue.new
135
134
  dumper = Thread.new do
@@ -142,6 +141,7 @@ module Etcenv
142
141
  dumper_ch.pop
143
142
  end
144
143
  end
144
+ dumper.abort_on_exception = true
145
145
 
146
146
  watchers.map do |watcher|
147
147
  Thread.new do
@@ -8,12 +8,8 @@ module Etcenv
8
8
 
9
9
  attr_reader :env
10
10
 
11
- def expanded_env
12
- VariableExpander.expand @env
13
- end
14
-
15
11
  def lines
16
- expanded_env.map { |k,v| "#{k}=#{v}" }
12
+ env.map { |k,v| "#{k}=#{v}" }
17
13
  end
18
14
 
19
15
  def to_s
@@ -8,12 +8,8 @@ module Etcenv
8
8
 
9
9
  attr_reader :env
10
10
 
11
- def expanded_env
12
- VariableExpander.expand @env
13
- end
14
-
15
11
  def lines
16
- expanded_env.map { |k, v| make_dotenv_line(k, v) }
12
+ env.map { |k, v| make_dotenv_line(k, v) }
17
13
  end
18
14
 
19
15
  def to_s
@@ -1,10 +1,12 @@
1
+ require 'etcenv/variable_expander'
2
+
1
3
  module Etcenv
2
4
  class Environment
3
5
  class NotDirectory < StandardError; end
4
6
  class DepthLimitError < StandardError; end
5
7
  class LoopError < StandardError; end
6
8
 
7
- INCLUDE_KEY = '_include'
9
+ INCLUDE_KEY = '.include'
8
10
  MAX_DEPTH_DEFAULT = 10
9
11
 
10
12
  def initialize(etcd, root_key, max_depth: MAX_DEPTH_DEFAULT)
@@ -18,6 +20,10 @@ module Etcenv
18
20
  attr_reader :root_key, :env, :etcd
19
21
  attr_accessor :max_depth
20
22
 
23
+ def expanded_env
24
+ VariableExpander.expand(env)
25
+ end
26
+
21
27
  def modified_indices
22
28
  @modified_indices ||= {}
23
29
  end
@@ -29,7 +35,7 @@ module Etcenv
29
35
  includes.each do |name|
30
36
  env.merge! fetch(name)
31
37
  end
32
- env.delete '_include'
38
+ env.delete '.include'
33
39
  @env = env
34
40
  end
35
41
  self
@@ -50,7 +56,7 @@ module Etcenv
50
56
  end
51
57
 
52
58
  def default_prefix
53
- root_key.sub(/^.*\//, '')
59
+ root_key.sub(/^(.*)\/.+?$/, '\1')
54
60
  end
55
61
 
56
62
  def resolve_key(key)
@@ -80,11 +86,12 @@ module Etcenv
80
86
 
81
87
  node.children.each do |child|
82
88
  name = child.key.sub(/^.*\//, '')
89
+
90
+ index = [index, child.modified_index].max
83
91
  if child.dir
84
92
  next
85
93
  else
86
94
  dir[name] = child.value
87
- index = [index, child.modified_index].max
88
95
  end
89
96
  end
90
97
 
@@ -1,3 +1,3 @@
1
1
  module Etcenv
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -2,9 +2,13 @@ require 'thread'
2
2
 
3
3
  module Etcenv
4
4
  class Watcher
5
+ WATCH_TIMEOUT = 120
6
+
5
7
  def initialize(env, verbose: false)
6
8
  @env = env
7
9
  @verbose = verbose
10
+ @indices = {}
11
+ @lock = Mutex.new
8
12
  end
9
13
 
10
14
  attr_reader :env, :verbose
@@ -16,11 +20,8 @@ module Etcenv
16
20
  def watch
17
21
  ch = Queue.new
18
22
  threads = env.modified_indices.map do |key, index|
19
- Thread.new do
20
- $stderr.puts "[watcher] waiting for change on #{key} (index: #{index.succ})" if verbose
21
- etcd.watch(key, recursive: true, index: index.succ)
22
- $stderr.puts "[watcher] dir #{key} has updated" if verbose
23
- ch << key
23
+ Thread.new(ch, key, index, &method(:watch_thread)).tap do |th|
24
+ th.abort_on_exception = true
24
25
  end
25
26
  end
26
27
  report = ch.pop
@@ -30,11 +31,32 @@ module Etcenv
30
31
 
31
32
  def auto_reload_loop
32
33
  loop do
33
- watch
34
- $stderr.puts "[watcher] reloading env #{env.root_key}" if verbose
35
- env.load
36
- yield env if block_given?
34
+ begin
35
+ watch
36
+ $stderr.puts "[watcher] reloading env #{env.root_key}" if verbose
37
+ env.load
38
+ yield env if block_given?
39
+ rescue => e
40
+ $stderr.puts "[watcher][error] Failed to reload env #{env.root_key}: #{e.inspect}"
41
+ $stderr.puts "\t#{e.backtrace.join("\n\t")}"
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def watch_thread(ch, key, index)
49
+ $stderr.puts "[watcher] waiting for change on #{key} (index: #{index.succ})" if verbose
50
+ response = etcd.watch(key, recursive: true, index: [@indices[key] || 0, index].max.succ, timeout: WATCH_TIMEOUT)
51
+ @lock.synchronize do
52
+ # Record modified_index in watcher itself; Because the latest index may be hidden in normal response
53
+ # e.g. unlisted keys, removed keys
54
+ @indices[key] = response.node.modified_index
37
55
  end
56
+ $stderr.puts "[watcher] dir #{key} has updated" if verbose
57
+ ch << key
58
+ rescue Net::ReadTimeout
59
+ retry
38
60
  end
39
61
  end
40
62
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etcenv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shota Fukumori (sora_h)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-07 00:00:00.000000000 Z
11
+ date: 2015-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  version: '0'
115
115
  requirements: []
116
116
  rubyforge_project:
117
- rubygems_version: 2.2.2
117
+ rubygems_version: 2.4.5
118
118
  signing_key:
119
119
  specification_version: 4
120
120
  summary: Dump etcd keys into dotenv file or docker env file