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 +4 -4
- data/README.md +5 -5
- data/lib/etcenv/cli.rb +2 -2
- data/lib/etcenv/dockerenv_file.rb +1 -5
- data/lib/etcenv/dotenv_file.rb +1 -5
- data/lib/etcenv/environment.rb +11 -4
- data/lib/etcenv/version.rb +1 -1
- data/lib/etcenv/watcher.rb +31 -9
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e08b420a67f38847ae025f781cbedb6484a0af74
|
4
|
+
data.tar.gz: 84cc434c7876ceb2f31e0158dde5665d4d005d73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
85
|
+
etcdctl set /envs/my-app/.include common
|
86
86
|
```
|
87
87
|
|
88
|
-
- `
|
89
|
-
- For multiple
|
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).
|
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
|
data/lib/etcenv/dotenv_file.rb
CHANGED
data/lib/etcenv/environment.rb
CHANGED
@@ -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 = '
|
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 '
|
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
|
|
data/lib/etcenv/version.rb
CHANGED
data/lib/etcenv/watcher.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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.
|
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-
|
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.
|
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
|