vcap_common 1.0.10
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.
- data/lib/json_message.rb +139 -0
- data/lib/json_schema.rb +84 -0
- data/lib/services/api/async_requests.rb +43 -0
- data/lib/services/api/clients/service_gateway_client.rb +107 -0
- data/lib/services/api/const.rb +9 -0
- data/lib/services/api/messages.rb +153 -0
- data/lib/services/api/util.rb +17 -0
- data/lib/services/api.rb +6 -0
- data/lib/vcap/common.rb +236 -0
- data/lib/vcap/component.rb +172 -0
- data/lib/vcap/config.rb +32 -0
- data/lib/vcap/fiber_tracing.rb +45 -0
- data/lib/vcap/json_schema.rb +202 -0
- data/lib/vcap/priority_queue.rb +164 -0
- data/lib/vcap/process_utils.rb +43 -0
- data/lib/vcap/quota.rb +152 -0
- data/lib/vcap/rolling_metric.rb +74 -0
- data/lib/vcap/spec/em.rb +32 -0
- data/lib/vcap/spec/forked_component/base.rb +87 -0
- data/lib/vcap/spec/forked_component/nats_server.rb +28 -0
- data/lib/vcap/spec/forked_component.rb +2 -0
- data/lib/vcap/subprocess.rb +211 -0
- data/lib/vcap/user_pools/user_ops.rb +47 -0
- data/lib/vcap/user_pools/user_pool.rb +45 -0
- data/lib/vcap/user_pools/user_pool_util.rb +107 -0
- metadata +166 -0
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'posix-spawn'
|
2
|
+
|
3
|
+
module VCAP
|
4
|
+
class SubprocessError < StandardError; end
|
5
|
+
|
6
|
+
# Command exited with unexpected status code
|
7
|
+
class SubprocessStatusError < SubprocessError
|
8
|
+
attr_reader :command, :status, :stdout, :stderr
|
9
|
+
|
10
|
+
def initialize(command, stdout, stderr, status)
|
11
|
+
@command = command
|
12
|
+
@status = status
|
13
|
+
@stdout = stdout
|
14
|
+
@stderr = stderr
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"ERROR: Command '#{@command}' exited with status '#{status.exitstatus}'"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Command ran longer than allowed
|
23
|
+
class SubprocessTimeoutError < SubprocessError
|
24
|
+
attr_reader :command, :timeout, :stdout, :stderr
|
25
|
+
|
26
|
+
def initialize(timeout, command, stdout, stderr)
|
27
|
+
@command = command
|
28
|
+
@timeout = timeout
|
29
|
+
@stdout = stdout
|
30
|
+
@stderr = stderr
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
"ERROR: Command '#{@command}' timed out"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Failure reading from stdin/stdout
|
39
|
+
class SubprocessReadError < SubprocessError
|
40
|
+
attr_reader :command, :stdout, :stderr
|
41
|
+
|
42
|
+
def initialize(failed_iostr, command, stdout, stderr)
|
43
|
+
@failed_iostr = failed_iostr
|
44
|
+
@command = command
|
45
|
+
@stdout = stdout
|
46
|
+
@stderr = stderr
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
"ERROR: Failed reading from #{@failed_iostr} while executing '#{@command}'"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Utility class providing:
|
55
|
+
# - Ability to capture stdout/stderr of a command
|
56
|
+
# - Exceptions when commands fail (useful for running a chain of commands)
|
57
|
+
# - Easier integration with unit tests.
|
58
|
+
class Subprocess
|
59
|
+
READ_SIZE = 4096
|
60
|
+
|
61
|
+
def self.run(*args)
|
62
|
+
VCAP::Subprocess.new.run(*args)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Runs the supplied command in a subshell.
|
66
|
+
#
|
67
|
+
# @param command String The command to be run
|
68
|
+
# @param expected_exit_status Integer The expected exit status of the command in [0, 255]
|
69
|
+
# @param timeout Integer How long the command should be allowed to run for
|
70
|
+
# nil indicates no timeout
|
71
|
+
# @param options Hash Options to be passed to Posix::Spawn
|
72
|
+
# See https://github.com/rtomayko/posix-spawn
|
73
|
+
# @param env Hash Environment to be passed to Posix::Spawn
|
74
|
+
# See https://github.com/rtomayko/posix-spawn
|
75
|
+
#
|
76
|
+
# @raise VCAP::SubprocessStatusError Thrown if the exit status does not match the expected
|
77
|
+
# exit status.
|
78
|
+
# @raise VCAP::SubprocessTimeoutError Thrown if a timeout occurs.
|
79
|
+
# @raise VCAP::SubprocessReadError Thrown if there is an error reading from any of the pipes
|
80
|
+
# to the child.
|
81
|
+
#
|
82
|
+
# @return Array An array of [stdout, stderr, status]. Note that status
|
83
|
+
# is an instance of Process::Status.
|
84
|
+
#
|
85
|
+
def run(command, expected_exit_status=0, timeout=nil, options={}, env={})
|
86
|
+
# We use a pipe to ourself to time out long running commands (if desired) as follows:
|
87
|
+
# 1. Set up a pipe to ourselves
|
88
|
+
# 2. Install a signal handler that writes to one end of our pipe on SIGCHLD
|
89
|
+
# 3. Select on the read end of our pipe and check if our process exited
|
90
|
+
sigchld_r, sigchld_w = IO.pipe
|
91
|
+
prev_sigchld_handler = install_sigchld_handler(sigchld_w)
|
92
|
+
|
93
|
+
start = Time.now.to_i
|
94
|
+
child_pid, stdin, stdout, stderr = POSIX::Spawn.popen4(env, command, options)
|
95
|
+
stdin.close
|
96
|
+
|
97
|
+
# Used to look up the name of an io object when an errors occurs while
|
98
|
+
# reading from it, as well as to look up the corresponding buffer to
|
99
|
+
# append to.
|
100
|
+
io_map = {
|
101
|
+
stderr => { :name => 'stderr', :buf => '' },
|
102
|
+
stdout => { :name => 'stdout', :buf => '' },
|
103
|
+
sigchld_r => { :name => 'sigchld_r', :buf => '' },
|
104
|
+
sigchld_w => { :name => 'sigchld_w', :buf => '' },
|
105
|
+
}
|
106
|
+
|
107
|
+
status = nil
|
108
|
+
time_left = timeout
|
109
|
+
read_cands = [stdout, stderr, sigchld_r]
|
110
|
+
error_cands = read_cands.dup
|
111
|
+
|
112
|
+
begin
|
113
|
+
while read_cands.length > 0
|
114
|
+
active_ios = IO.select(read_cands, nil, error_cands, time_left)
|
115
|
+
|
116
|
+
# Check if timeout was hit
|
117
|
+
if timeout
|
118
|
+
time_left = timeout - (Time.now.to_i - start)
|
119
|
+
unless active_ios && (time_left > 0)
|
120
|
+
raise VCAP::SubprocessTimeoutError.new(timeout,
|
121
|
+
command,
|
122
|
+
io_map[stdout][:buf],
|
123
|
+
io_map[stderr][:buf])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Read as much as we can from the readable ios before blocking
|
128
|
+
for io in active_ios[0]
|
129
|
+
begin
|
130
|
+
io_map[io][:buf] << io.read_nonblock(READ_SIZE)
|
131
|
+
rescue IO::WaitReadable
|
132
|
+
# Reading would block, so put ourselves back on the loop
|
133
|
+
rescue EOFError
|
134
|
+
# Pipe has no more data, remove it from the readable/error set
|
135
|
+
# NB: We cannot break from the loop here, as the other pipes may have data to be read
|
136
|
+
read_cands.delete(io)
|
137
|
+
error_cands.delete(io)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Our signal handler notified us that >= 1 children have exited;
|
141
|
+
# check if our child has exited.
|
142
|
+
if (io == sigchld_r) && Process.waitpid(child_pid, Process::WNOHANG)
|
143
|
+
status = $?
|
144
|
+
read_cands.delete(sigchld_r)
|
145
|
+
error_cands.delete(sigchld_r)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Error reading from one or more pipes.
|
150
|
+
unless active_ios[2].empty?
|
151
|
+
io_names = active_ios[2].map {|io| io_map[io][:name] }
|
152
|
+
raise SubprocessReadError.new(io_names.join(', '),
|
153
|
+
command,
|
154
|
+
io_map[stdout][:buf],
|
155
|
+
io_map[stderr][:buf])
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
rescue
|
160
|
+
# A timeout or an error occurred while reading from one or more pipes.
|
161
|
+
# Kill the process if we haven't reaped its exit status already.
|
162
|
+
kill_pid(child_pid) unless status
|
163
|
+
raise
|
164
|
+
|
165
|
+
ensure
|
166
|
+
# Make sure we reap the child's exit status, close our fds, and restore
|
167
|
+
# the previous SIGCHLD handler
|
168
|
+
unless status
|
169
|
+
Process.waitpid(child_pid)
|
170
|
+
status = $?
|
171
|
+
end
|
172
|
+
io_map.each_key {|io| io.close unless io.closed? }
|
173
|
+
trap('CLD') { prev_sigchld_handler.call } if prev_sigchld_handler
|
174
|
+
end
|
175
|
+
|
176
|
+
unless status.exitstatus == expected_exit_status
|
177
|
+
raise SubprocessStatusError.new(command,
|
178
|
+
io_map[stdout][:buf],
|
179
|
+
io_map[stderr][:buf],
|
180
|
+
status)
|
181
|
+
end
|
182
|
+
|
183
|
+
[io_map[stdout][:buf], io_map[stderr][:buf], status]
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def install_sigchld_handler(write_pipe)
|
189
|
+
prev_handler = trap('CLD') do
|
190
|
+
begin
|
191
|
+
# Notify select loop that a child exited. We use a nonblocking write
|
192
|
+
# to avoid writing more than PIPE_BUF bytes before we have the chance
|
193
|
+
# to drain the pipe. Note that we only need to write a single byte
|
194
|
+
# to detect if our child has exited.
|
195
|
+
write_pipe.write_nonblock('x') unless write_pipe.closed?
|
196
|
+
rescue IO::WaitWritable
|
197
|
+
end
|
198
|
+
prev_handler.call if prev_handler
|
199
|
+
end
|
200
|
+
prev_handler
|
201
|
+
end
|
202
|
+
|
203
|
+
def kill_pid(pid)
|
204
|
+
begin
|
205
|
+
Process.kill('KILL', pid)
|
206
|
+
rescue Errno::ESRCH
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__),'../../common/lib'))
|
2
|
+
$:.unshift(File.join(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'logger'
|
5
|
+
require 'vcap/subprocess'
|
6
|
+
|
7
|
+
module VCAP
|
8
|
+
module UserOps
|
9
|
+
class << self
|
10
|
+
def run(cmd, expected_exit_status = 0)
|
11
|
+
result = VCAP::Subprocess.run(cmd, expected_exit_status)
|
12
|
+
end
|
13
|
+
|
14
|
+
def group_exists?(name)
|
15
|
+
found = false
|
16
|
+
Etc.group { |g| found = true if g.name == name}
|
17
|
+
Etc.endgrent
|
18
|
+
found
|
19
|
+
end
|
20
|
+
|
21
|
+
def install_group(group_name)
|
22
|
+
run("addgroup --system #{group_name}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove_group(group_name)
|
26
|
+
run("delgroup --system #{group_name}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def user_exists?(name)
|
30
|
+
found = false
|
31
|
+
Etc.passwd { |u| found = true if u.name == name}
|
32
|
+
Etc.endpwent
|
33
|
+
found
|
34
|
+
end
|
35
|
+
|
36
|
+
def install_user(user_name, group_name)
|
37
|
+
run("adduser --system --quiet --no-create-home --home '/nonexistent' #{user_name}")
|
38
|
+
run("usermod -g #{group_name} #{user_name}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_user(user_name)
|
42
|
+
run("deluser #{user_name}")
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__),'..'))
|
2
|
+
$:.unshift(File.dirname(__FILE__))
|
3
|
+
require 'user_pool_util'
|
4
|
+
require 'user_ops'
|
5
|
+
require 'subprocess'
|
6
|
+
|
7
|
+
module VCAP
|
8
|
+
class UserPool
|
9
|
+
attr_accessor :free_users
|
10
|
+
attr_accessor :busy_users
|
11
|
+
|
12
|
+
def initialize(name, logger = nil)
|
13
|
+
@logger = logger || Logger.new(STDOUT)
|
14
|
+
UserPoolUtil.init
|
15
|
+
@free_users = UserPoolUtil.open_pool(name)
|
16
|
+
@busy_users = Hash.new
|
17
|
+
@logger.debug("Initialized user pool #{name} with #{@free_users.size} users.")
|
18
|
+
end
|
19
|
+
|
20
|
+
def alloc_user
|
21
|
+
user_name, user = @free_users.shift
|
22
|
+
if user_name != nil
|
23
|
+
@busy_users[user_name] = user
|
24
|
+
else
|
25
|
+
raise "out of users!!"
|
26
|
+
end
|
27
|
+
@logger.debug "alloc()'d user #{user_name}"
|
28
|
+
user
|
29
|
+
end
|
30
|
+
|
31
|
+
def free_user(user)
|
32
|
+
user_name = user[:user_name]
|
33
|
+
if @busy_users.has_key?(user_name)
|
34
|
+
VCAP::Subprocess.run("pkill -9 -u #{user_name}", 1)
|
35
|
+
@busy_users.delete(user_name)
|
36
|
+
@free_users[user_name] = user
|
37
|
+
@logger.debug "free()'d user #{user_name}"
|
38
|
+
else
|
39
|
+
raise "invalid free user: #{user_name}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'vcap/subprocess'
|
5
|
+
require 'user_ops'
|
6
|
+
|
7
|
+
module VCAP
|
8
|
+
module UserPoolUtil
|
9
|
+
class << self
|
10
|
+
def init(logger = nil)
|
11
|
+
@logger = logger || Logger.new(STDOUT)
|
12
|
+
end
|
13
|
+
|
14
|
+
def user_from_num(name, num)
|
15
|
+
"user-pool-#{name}-#{num}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def group_from_name(name)
|
19
|
+
"user-pool-#{name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def kill_group_procs(group_name)
|
23
|
+
@logger.debug("killing all procs in group #{group_name}")
|
24
|
+
#XXX -- fixme VCAP::Subprocess.run("pkill -9 -G #{group_name}" , 0)
|
25
|
+
end
|
26
|
+
|
27
|
+
def install_pool(name, size)
|
28
|
+
raise ArgumentError("pool name must not contain dashes") if name =~ /-/
|
29
|
+
group_name = group_from_name(name)
|
30
|
+
|
31
|
+
@logger.info("Creating user pool #{name} with #{size} users.")
|
32
|
+
if VCAP::UserOps.group_exists?(group_name)
|
33
|
+
raise ArgumentError.new("group #{group_name} already exists")
|
34
|
+
end
|
35
|
+
VCAP::UserOps.install_group(group_name)
|
36
|
+
kill_group_procs(group_name)
|
37
|
+
|
38
|
+
begin
|
39
|
+
1.upto(size) do |number|
|
40
|
+
user_name = user_from_num(name, number)
|
41
|
+
if VCAP::UserOps.user_exists?(user_name)
|
42
|
+
VCAP::UserOps.remove_user(user_name)
|
43
|
+
@logger.warn("User reset occured for user #{user_name}!")
|
44
|
+
end
|
45
|
+
@logger.debug("installing user #{user_name}")
|
46
|
+
VCAP::UserOps.install_user(user_name, group_name)
|
47
|
+
end
|
48
|
+
rescue => e
|
49
|
+
@logger.error e.to_s
|
50
|
+
@logger.error("pool creation failed, cleaning up")
|
51
|
+
remove_pool(name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def remove_pool(name)
|
56
|
+
@logger.info("Removing user pool #{name}.")
|
57
|
+
group_name = group_from_name(name)
|
58
|
+
kill_group_procs(group_name)
|
59
|
+
|
60
|
+
Etc.passwd { |u|
|
61
|
+
if u.name.split('-')[2] == name
|
62
|
+
@logger.debug "removed user #{u.name}"
|
63
|
+
VCAP::UserOps.remove_user(u.name)
|
64
|
+
end
|
65
|
+
}
|
66
|
+
Etc.endpwent
|
67
|
+
|
68
|
+
if VCAP::UserOps.group_exists?(group_name)
|
69
|
+
VCAP::UserOps.remove_group(group_name)
|
70
|
+
else
|
71
|
+
@logger.warn "Pool group #{group_name} missing!!"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def pool_exists?(name)
|
76
|
+
group_name = group_from_name(name)
|
77
|
+
VCAP::UserOps.group_exists?(group_name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def open_pool(name)
|
81
|
+
group_name = group_from_name(name)
|
82
|
+
pool_users = Hash.new
|
83
|
+
unless VCAP::UserOps.group_exists?(group_name)
|
84
|
+
raise ArgumentError.new("no group named #{group_name} exists - can't open pool.")
|
85
|
+
end
|
86
|
+
Etc.passwd { |u|
|
87
|
+
if u.name.split('-')[2] == name
|
88
|
+
pool_users[u.name] = {:user_name => u.name, :uid => u.uid, :gid => u.gid}
|
89
|
+
end
|
90
|
+
}
|
91
|
+
pool_users
|
92
|
+
end
|
93
|
+
|
94
|
+
def pool_list
|
95
|
+
list = []
|
96
|
+
Etc.group { |g|
|
97
|
+
if ['user','pool'] == g.name.split('-')[0..1]
|
98
|
+
list.push(g.name.split('-')[2])
|
99
|
+
end
|
100
|
+
}
|
101
|
+
Etc.endgrent
|
102
|
+
list.map {|name| "#{name} #{open_pool(name).size}"}
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vcap_common
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.10
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Derek Collison
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-02-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: eventmachine
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.12.11.cloudfoundry.3
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.12.11.cloudfoundry.3
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: thin
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.3.1
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.3.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yajl-ruby
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.8.3
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.3
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: nats
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.4.22.beta.8
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.4.22.beta.8
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: posix-spawn
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.3.6
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.3.6
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.9.2
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.9.2
|
110
|
+
description: common vcap classes/methods
|
111
|
+
email:
|
112
|
+
- derek.collison@gmail.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- lib/json_message.rb
|
118
|
+
- lib/json_schema.rb
|
119
|
+
- lib/services/api/async_requests.rb
|
120
|
+
- lib/services/api/clients/service_gateway_client.rb
|
121
|
+
- lib/services/api/const.rb
|
122
|
+
- lib/services/api/messages.rb
|
123
|
+
- lib/services/api/util.rb
|
124
|
+
- lib/services/api.rb
|
125
|
+
- lib/vcap/common.rb
|
126
|
+
- lib/vcap/component.rb
|
127
|
+
- lib/vcap/config.rb
|
128
|
+
- lib/vcap/fiber_tracing.rb
|
129
|
+
- lib/vcap/json_schema.rb
|
130
|
+
- lib/vcap/priority_queue.rb
|
131
|
+
- lib/vcap/process_utils.rb
|
132
|
+
- lib/vcap/quota.rb
|
133
|
+
- lib/vcap/rolling_metric.rb
|
134
|
+
- lib/vcap/spec/em.rb
|
135
|
+
- lib/vcap/spec/forked_component/base.rb
|
136
|
+
- lib/vcap/spec/forked_component/nats_server.rb
|
137
|
+
- lib/vcap/spec/forked_component.rb
|
138
|
+
- lib/vcap/subprocess.rb
|
139
|
+
- lib/vcap/user_pools/user_ops.rb
|
140
|
+
- lib/vcap/user_pools/user_pool.rb
|
141
|
+
- lib/vcap/user_pools/user_pool_util.rb
|
142
|
+
homepage: http://github.com/vmware-ac/core
|
143
|
+
licenses: []
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
require_paths:
|
147
|
+
- lib
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
requirements: []
|
161
|
+
rubyforge_project:
|
162
|
+
rubygems_version: 1.8.22
|
163
|
+
signing_key:
|
164
|
+
specification_version: 3
|
165
|
+
summary: vcap common
|
166
|
+
test_files: []
|