right_agent 0.5.1

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.
Files changed (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +78 -0
  3. data/Rakefile +86 -0
  4. data/lib/right_agent.rb +66 -0
  5. data/lib/right_agent/actor.rb +163 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +189 -0
  8. data/lib/right_agent/agent.rb +735 -0
  9. data/lib/right_agent/agent_config.rb +403 -0
  10. data/lib/right_agent/agent_identity.rb +209 -0
  11. data/lib/right_agent/agent_tags_manager.rb +213 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/broker_client.rb +683 -0
  14. data/lib/right_agent/command.rb +30 -0
  15. data/lib/right_agent/command/agent_manager_commands.rb +134 -0
  16. data/lib/right_agent/command/command_client.rb +136 -0
  17. data/lib/right_agent/command/command_constants.rb +42 -0
  18. data/lib/right_agent/command/command_io.rb +128 -0
  19. data/lib/right_agent/command/command_parser.rb +87 -0
  20. data/lib/right_agent/command/command_runner.rb +105 -0
  21. data/lib/right_agent/command/command_serializer.rb +63 -0
  22. data/lib/right_agent/console.rb +65 -0
  23. data/lib/right_agent/core_payload_types.rb +42 -0
  24. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  25. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  26. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  27. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  28. data/lib/right_agent/core_payload_types/dev_repositories.rb +90 -0
  29. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  30. data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
  31. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  32. data/lib/right_agent/core_payload_types/login_user.rb +62 -0
  33. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  34. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -0
  35. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  36. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  37. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +73 -0
  38. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  39. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  40. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  41. data/lib/right_agent/daemonize.rb +35 -0
  42. data/lib/right_agent/dispatcher.rb +348 -0
  43. data/lib/right_agent/enrollment_result.rb +217 -0
  44. data/lib/right_agent/exceptions.rb +30 -0
  45. data/lib/right_agent/ha_broker_client.rb +1278 -0
  46. data/lib/right_agent/idempotent_request.rb +140 -0
  47. data/lib/right_agent/log.rb +418 -0
  48. data/lib/right_agent/monkey_patches.rb +29 -0
  49. data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
  50. data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -0
  51. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  52. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  53. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  54. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  55. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  56. data/lib/right_agent/monkey_patches/ruby_patch/singleton_patch.rb +46 -0
  57. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -0
  58. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +90 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  64. data/lib/right_agent/multiplexer.rb +91 -0
  65. data/lib/right_agent/operation_result.rb +270 -0
  66. data/lib/right_agent/packets.rb +637 -0
  67. data/lib/right_agent/payload_formatter.rb +104 -0
  68. data/lib/right_agent/pid_file.rb +159 -0
  69. data/lib/right_agent/platform.rb +319 -0
  70. data/lib/right_agent/platform/darwin.rb +227 -0
  71. data/lib/right_agent/platform/linux.rb +268 -0
  72. data/lib/right_agent/platform/windows.rb +1204 -0
  73. data/lib/right_agent/scripts/agent_controller.rb +522 -0
  74. data/lib/right_agent/scripts/agent_deployer.rb +379 -0
  75. data/lib/right_agent/scripts/common_parser.rb +153 -0
  76. data/lib/right_agent/scripts/log_level_manager.rb +193 -0
  77. data/lib/right_agent/scripts/stats_manager.rb +256 -0
  78. data/lib/right_agent/scripts/usage.rb +58 -0
  79. data/lib/right_agent/secure_identity.rb +92 -0
  80. data/lib/right_agent/security.rb +32 -0
  81. data/lib/right_agent/security/cached_certificate_store_proxy.rb +63 -0
  82. data/lib/right_agent/security/certificate.rb +102 -0
  83. data/lib/right_agent/security/certificate_cache.rb +89 -0
  84. data/lib/right_agent/security/distinguished_name.rb +56 -0
  85. data/lib/right_agent/security/encrypted_document.rb +84 -0
  86. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  87. data/lib/right_agent/security/signature.rb +86 -0
  88. data/lib/right_agent/security/static_certificate_store.rb +69 -0
  89. data/lib/right_agent/sender.rb +937 -0
  90. data/lib/right_agent/serialize.rb +29 -0
  91. data/lib/right_agent/serialize/message_pack.rb +102 -0
  92. data/lib/right_agent/serialize/secure_serializer.rb +131 -0
  93. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  94. data/lib/right_agent/serialize/serializable.rb +135 -0
  95. data/lib/right_agent/serialize/serializer.rb +149 -0
  96. data/lib/right_agent/stats_helper.rb +731 -0
  97. data/lib/right_agent/subprocess.rb +38 -0
  98. data/lib/right_agent/tracer.rb +124 -0
  99. data/right_agent.gemspec +60 -0
  100. data/spec/actor_registry_spec.rb +81 -0
  101. data/spec/actor_spec.rb +99 -0
  102. data/spec/agent_config_spec.rb +226 -0
  103. data/spec/agent_identity_spec.rb +75 -0
  104. data/spec/agent_spec.rb +571 -0
  105. data/spec/broker_client_spec.rb +961 -0
  106. data/spec/command/agent_manager_commands_spec.rb +51 -0
  107. data/spec/command/command_io_spec.rb +93 -0
  108. data/spec/command/command_parser_spec.rb +79 -0
  109. data/spec/command/command_runner_spec.rb +72 -0
  110. data/spec/command/command_serializer_spec.rb +51 -0
  111. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  112. data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
  113. data/spec/core_payload_types/login_user_spec.rb +98 -0
  114. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  115. data/spec/core_payload_types/spec_helper.rb +23 -0
  116. data/spec/dispatcher_spec.rb +372 -0
  117. data/spec/enrollment_result_spec.rb +53 -0
  118. data/spec/ha_broker_client_spec.rb +1673 -0
  119. data/spec/idempotent_request_spec.rb +136 -0
  120. data/spec/log_spec.rb +177 -0
  121. data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
  122. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  123. data/spec/monkey_patches/string_patch_spec.rb +99 -0
  124. data/spec/multiplexer_spec.rb +48 -0
  125. data/spec/operation_result_spec.rb +171 -0
  126. data/spec/packets_spec.rb +418 -0
  127. data/spec/platform/platform_spec.rb +60 -0
  128. data/spec/results_mock.rb +45 -0
  129. data/spec/secure_identity_spec.rb +50 -0
  130. data/spec/security/cached_certificate_store_proxy_spec.rb +56 -0
  131. data/spec/security/certificate_cache_spec.rb +71 -0
  132. data/spec/security/certificate_spec.rb +49 -0
  133. data/spec/security/distinguished_name_spec.rb +46 -0
  134. data/spec/security/encrypted_document_spec.rb +55 -0
  135. data/spec/security/rsa_key_pair_spec.rb +55 -0
  136. data/spec/security/signature_spec.rb +66 -0
  137. data/spec/security/static_certificate_store_spec.rb +52 -0
  138. data/spec/sender_spec.rb +887 -0
  139. data/spec/serialize/message_pack_spec.rb +131 -0
  140. data/spec/serialize/secure_serializer_spec.rb +102 -0
  141. data/spec/serialize/serializable_spec.rb +90 -0
  142. data/spec/serialize/serializer_spec.rb +174 -0
  143. data/spec/spec.opts +2 -0
  144. data/spec/spec_helper.rb +77 -0
  145. data/spec/stats_helper_spec.rb +681 -0
  146. data/spec/tracer_spec.rb +114 -0
  147. metadata +320 -0
@@ -0,0 +1,49 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ class Object
24
+ unless defined? instance_exec # 1.9 and 1.8.7
25
+ module InstanceExecHelper; end
26
+ include InstanceExecHelper
27
+
28
+ # Evaluate the block with the given arguments within the context of
29
+ # this object, so self is set to the method receiver.
30
+ #
31
+ # From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
32
+ def instance_exec(*args, &block)
33
+ begin
34
+ old_critical, Thread.critical = Thread.critical, true
35
+ n = 0
36
+ n += 1 while respond_to?(method_name = "__instance_exec#{n}")
37
+ InstanceExecMethods.module_eval { define_method(method_name, &block) }
38
+ ensure
39
+ Thread.critical = old_critical
40
+ end
41
+
42
+ begin
43
+ send(method_name, *args)
44
+ ensure
45
+ InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'singleton'
24
+
25
+ module RightScale
26
+
27
+ module Singleton
28
+
29
+ module ClassMethods
30
+
31
+ # Redirect class methods to singleton instance
32
+ def method_missing(meth, *args, &blk)
33
+ self.instance.__send__(meth, *args, &blk)
34
+ end
35
+
36
+ end
37
+
38
+ # Upon inclusion, also include standard Singleton mixin
39
+ def self.included(base)
40
+ base.__send__(:include, ::Singleton)
41
+ base.__send__(:extend, ClassMethods)
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,107 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ class String
24
+ ##
25
+ # Convert to snake case.
26
+ #
27
+ # "FooBar".snake_case #=> "foo_bar"
28
+ # "HeadlineCNNNews".snake_case #=> "headline_cnn_news"
29
+ # "CNN".snake_case #=> "cnn"
30
+ #
31
+ # @return [String] Receiver converted to snake case.
32
+ #
33
+ # @api public
34
+ def snake_case
35
+ return downcase if match(/\A[A-Z]+\z/)
36
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
37
+ gsub(/([a-z])([A-Z])/, '\1_\2').
38
+ downcase
39
+ end
40
+
41
+ ##
42
+ # Convert a constant name to a path, assuming a conventional structure.
43
+ #
44
+ # "FooBar::Baz".to_const_path # => "foo_bar/baz"
45
+ #
46
+ # @return [String] Path to the file containing the constant named by receiver
47
+ # (constantized string), assuming a conventional structure.
48
+ #
49
+ # @api public
50
+ def to_const_path
51
+ snake_case.gsub(/::/, "/")
52
+ end
53
+
54
+ # Convert constant name to constant
55
+ #
56
+ # "FooBar::Baz".to_const => FooBar::Baz
57
+ #
58
+ # @return [Constant] Constant corresponding to given name or nil if no
59
+ # constant with that name exists
60
+ #
61
+ # @api public
62
+ def to_const
63
+ names = split('::')
64
+ names.shift if names.empty? || names.first.empty?
65
+
66
+ constant = Object
67
+ names.each do |name|
68
+ # modified to return nil instead of raising an const_missing error
69
+ constant = constant && constant.const_defined?(name) ? constant.const_get(name) : nil
70
+ end
71
+ constant
72
+ end
73
+
74
+ # Reverse operation of snake case:
75
+ #
76
+ # "some_string/some_other_string" => "SomeString::SomeOtherString"
77
+ #
78
+ # @return [String] Camelized string
79
+ #
80
+ # @api public
81
+ if !String.public_method_defined?(:camelize)
82
+ def camelize(first_letter = :upper)
83
+ case first_letter
84
+ when :upper then gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
85
+ when :lower then first + camelize(self)[1..-1]
86
+ end
87
+ end
88
+ end
89
+
90
+ # Add ability to output colored text to console
91
+ # e.g.: puts "Hello".red
92
+ def bold; colorize("\e[1m\e[29m"); end
93
+ def grey; colorize("\e[30m"); end
94
+ def red; colorize("\e[1m\e[31m"); end
95
+ def dark_red; colorize("\e[31m"); end
96
+ def green; colorize("\e[1m\e[32m"); end
97
+ def dark_green; colorize("\e[32m"); end
98
+ def yellow; colorize("\e[1m\e[33m"); end
99
+ def blue; colorize("\e[1m\e[34m"); end
100
+ def dark_blue; colorize("\e[34m"); end
101
+ def pur; colorize("\e[1m\e[35m"); end
102
+ def colorize(color_code)
103
+ # Doesn't work with the Windows prompt...
104
+ (RightScale::Platform.windows? || !$stdout.isatty) ? to_s : "#{color_code}#{to_s}\e[0m"
105
+ end
106
+
107
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ # load File monkey-patch first to enable use of File.normalize_path
24
+ require File.expand_path(File.join(File.dirname(__FILE__), 'windows_patch', 'file_patch'))
25
+
26
+ # hereafter used normalize_path to ensure files are only required once.
27
+ WINDOWS_MONKEY_PATCHES_BASE_DIR = File.normalize_path(File.join(File.dirname(__FILE__), 'windows_patch'))
28
+
29
+ require File.join(WINDOWS_MONKEY_PATCHES_BASE_DIR, 'process_patch')
30
+ require File.join(WINDOWS_MONKEY_PATCHES_BASE_DIR, 'stdio_patch')
31
+ require File.join(WINDOWS_MONKEY_PATCHES_BASE_DIR, 'time_patch')
32
+ require File.join(WINDOWS_MONKEY_PATCHES_BASE_DIR, 'win32ole_patch')
@@ -0,0 +1,90 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+
25
+ begin
26
+ require 'windows/file'
27
+
28
+ class File
29
+
30
+ # converts a long path to a short path. in windows terms, this means
31
+ # taking any file/folder name over 8 characters in length and truncating
32
+ # it to 6 characters with ~1..~n appended depending on how many similar
33
+ # names exist in the same directory. file extensions are simply chopped
34
+ # at three letters. the short name is equivalent for all API calls to
35
+ # the long path but requires no special quoting, etc. the path must
36
+ # exist at least partially for the API call to succeed.
37
+ #
38
+ # === Parameters
39
+ # long_path(String):: fully or partially existing long path to be
40
+ # converted to its short path equivalent.
41
+ #
42
+ # === Return
43
+ # short_path(String):: short path equivalent or same path if non-existent
44
+ def self.long_path_to_short_path(long_path)
45
+ if File.exists?(long_path)
46
+ length = 260
47
+ while true
48
+ buffer = 0.chr * length
49
+ length = ::Windows::File::GetShortPathName.call(long_path, buffer, buffer.length)
50
+ if length < buffer.length
51
+ break
52
+ end
53
+ end
54
+ return buffer.unpack('A*').first.gsub("\\", "/")
55
+ else
56
+ # must get short path for any existing ancestor since child doesn't
57
+ # (currently) exist.
58
+ child_name = File.basename(long_path)
59
+ long_parent_path = File.dirname(long_path)
60
+
61
+ # note that root dirname is root itself (at least in windows)
62
+ return long_path if long_path == long_parent_path
63
+
64
+ # recursion
65
+ short_parent_path = long_path_to_short_path(File.dirname(long_path))
66
+ return File.join(short_parent_path, child_name)
67
+ end
68
+ end
69
+
70
+ # First expand the path then shorten the directory.
71
+ # Only shorten the directory and not the file name because 'gem' wants
72
+ # long file names
73
+ def self.normalize_path(file_name, *dir_string)
74
+ path = File.expand_path(file_name, *dir_string)
75
+ dir = self.long_path_to_short_path(File.dirname(path))
76
+ File.join(dir, File.basename(path))
77
+ end
78
+
79
+ end
80
+
81
+ rescue LoadError
82
+ # use the simple definition of normalize_path to avoid breaking code which
83
+ # depends on having this definition.
84
+ class File
85
+ def self.normalize_path(file_name, *dir_string)
86
+ File.expand_path(file_name, *dir_string)
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+
25
+ begin
26
+ # win32/process monkey-patches the Process class but drops support for any kill
27
+ # signals which are not directly portable. some signals are acceptable, if not
28
+ # strictly portable. the 'TERM' signal used to be supported in Ruby v1.8.6 but
29
+ # raises an exception in Ruby v1.8.7. we will monkey-patch the monkey-patch to
30
+ # get the best possible implementation of signals.
31
+ WIN32_PROCESS_LOAD_ORDER_ERROR = "Must require process_patch before win32/process"
32
+
33
+ module Process
34
+ unless defined?(@@ruby_c_kill)
35
+ @@ruby_c_kill = method(:kill)
36
+
37
+ # check to ensure this is the first time 'win32/process' has been required
38
+ raise LoadError, WIN32_PROCESS_LOAD_ORDER_ERROR unless require 'win32/process'
39
+
40
+ @@win32_kill = method(:kill)
41
+
42
+ def self.kill(sig, *pids)
43
+ sig = 1 if 'TERM' == sig # Signals 1 and 4-8 kill the process in a nice manner.
44
+ @@win32_kill.call(sig, *pids)
45
+ end
46
+
47
+ # implements getpgid() for Windws
48
+ def self.getpgid(pid)
49
+ # FIX: we currently only use this to check if the process is running.
50
+ # it is possible to get the parent process id for a process in Windows if
51
+ # we actually need this info.
52
+ return Process.kill(0, pid).contains?(pid) ? 0 : -1
53
+ rescue
54
+ raise Errno::ESRCH
55
+ end
56
+ end
57
+ end
58
+
59
+ rescue LoadError => e
60
+ # ignore load error and skip monkey-patch if gems are not yet installed.
61
+ # re-raise if the error condition we explicitly check for.
62
+ raise if WIN32_PROCESS_LOAD_ORDER_ERROR == e.message
63
+ end
@@ -0,0 +1,27 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ # it's useful to auto-flush console output on Windows where it would otherwise
24
+ # be unavailable from a ruby process which was hanging (our code would never
25
+ # hang, of course). this is consistent with Powershell's auto-flush behavior.
26
+ STDOUT.sync = true
27
+ STDERR.sync = true
@@ -0,0 +1,55 @@
1
+ #
2
+ # Copyright (c) 2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+
25
+ begin
26
+ require 'windows/time'
27
+
28
+ # monkey patch Time.now because Windows Ruby interpreters used the wrong API
29
+ # and queried local time instead of UTC time prior to Ruby v1.9.1. This
30
+ # made the Ruby 1.8.x interpreters vulnerable to external changes to
31
+ # timezone which cause Time.now to return times which are offset from from the
32
+ # correct value. This implementation is borrowed from the C source for Ruby
33
+ # v1.9.1 from www.ruby-lang.org ("win32/win32.c").
34
+ if RUBY_VERSION < "1.9.1"
35
+ class Time
36
+ def self.now
37
+ # query UTC time as a 64-bit ularge value.
38
+ filetime = 0.chr * 8
39
+ ::Windows::Time::GetSystemTimeAsFileTime.call(filetime)
40
+ low_date_time = filetime[0,4].unpack('V')[0]
41
+ high_date_time = filetime[4,4].unpack('V')[0]
42
+ value = high_date_time * 0x100000000 + low_date_time
43
+
44
+ # value is now 100-nanosec intervals since 1601/01/01 00:00:00 UTC,
45
+ # convert it into UNIX time (since 1970/01/01 00:00:00 UTC).
46
+ value /= 10 # 100-nanoseconds to microseconds
47
+ microseconds = 1000 * 1000
48
+ value -= ((1970 - 1601) * 365.2425).to_i * 24 * 60 * 60 * microseconds
49
+ return Time.at(value / microseconds, value % microseconds)
50
+ end
51
+ end
52
+ end
53
+ rescue LoadError
54
+ # ignore load error and skip monkey-patch if gems are not yet installed.
55
+ end