summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2018-02-23 15:58:57 +0200
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2018-02-26 16:06:49 +0200
commit645dceb0a233fc523ac16611fa3fec317d29a7e1 (patch)
tree4bfc439d7720d8e7f715c749d5837088641418f2
parenteff5746b5e7cf4075edd6d1c76fdcd24c1603bb4 (diff)
downloadgitlab-ce-645dceb0a233fc523ac16611fa3fec317d29a7e1.tar.gz
Run plugins as separate process and pass data via STDIN
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
-rw-r--r--.gitignore2
-rw-r--r--config/application.rb1
-rw-r--r--generator_templates/plugins/template.rb16
-rw-r--r--lib/gitlab/plugin.rb28
-rw-r--r--lib/tasks/plugins.rake24
-rwxr-xr-xplugins/available/save_to_file.clj3
-rwxr-xr-xplugins/available/save_to_file.rb3
-rw-r--r--plugins/enabled/.gitkeep (renamed from plugins/.gitkeep)0
8 files changed, 27 insertions, 50 deletions
diff --git a/.gitignore b/.gitignore
index fa39ae01ff0..35ca92b1a93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,4 +66,4 @@ eslint-report.html
/locale/**/LC_MESSAGES
/locale/**/*.time_stamp
/.rspec
-/plugins/*
+/plugins/enabled/*
diff --git a/config/application.rb b/config/application.rb
index f2fc6270748..918bd4d57cf 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -28,7 +28,6 @@ module Gitlab
config.eager_load_paths.push(*%W[#{config.root}/lib
#{config.root}/app/models/hooks
#{config.root}/app/models/members
- #{config.root}/plugins
#{config.root}/app/models/project_services
#{config.root}/app/workers/concerns
#{config.root}/app/services/concerns
diff --git a/generator_templates/plugins/template.rb b/generator_templates/plugins/template.rb
deleted file mode 100644
index 16c87f2c2b2..00000000000
--- a/generator_templates/plugins/template.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# Requirements
-# * File name must end with _s.rb. For example, jenkins_plugin.rb.
-# * All code should be inside class. No code should be executed on file load.
-# * Class name must be same as file name.
-# If file name is jenkins_plugin.rb then class name must be JenkinsPlugin.
-#
-# Reccomendations
-# * Code should not depend on or use GitLab classes and other code.
-# * Consider contributing your plugin to GitLab source code so we can test it
-# and make sure it will work in further version.
-#
-class $NAMEPlugin
- def execute(data)
- # TODO: Implement me
- end
-end
diff --git a/lib/gitlab/plugin.rb b/lib/gitlab/plugin.rb
index 9604cac4b20..1035d258907 100644
--- a/lib/gitlab/plugin.rb
+++ b/lib/gitlab/plugin.rb
@@ -1,23 +1,35 @@
module Gitlab
module Plugin
def self.files
- Dir.glob(Rails.root.join('plugins', '*_plugin.rb'))
+ Dir.glob(Rails.root.join('plugins/enabled/*'))
end
def self.execute_all_async(data)
files.each do |file|
+ puts file
PluginWorker.perform_async(file, data)
end
end
def self.execute(file, data)
- # TODO: Implement
- #
- # Reuse some code from gitlab-shell https://gitlab.com/gitlab-org/gitlab-shell/blob/master/lib/gitlab_custom_hook.rb#L40
- # Pass data as STDIN (or JSON encode?)
- #
- # 1. Return true if 0 exit code
- # 2. Return false if non-zero exit code
+ # Prepare the hook subprocess. Attach a pipe to its stdin, and merge
+ # both its stdout and stderr into our own stdout.
+ stdin_reader, stdin_writer = IO.pipe
+ hook_pid = spawn({}, file, in: stdin_reader, err: :out)
+ stdin_reader.close
+
+ # Submit changes to the hook via its stdin.
+ begin
+ IO.copy_stream(StringIO.new(data.to_json), stdin_writer)
+ rescue Errno::EPIPE
+ # It is not an error if the hook does not consume all of its input.
+ end
+
+ # Close the pipe to let the hook know there is no further input.
+ stdin_writer.close
+
+ Process.wait(hook_pid)
+ $?.success?
end
end
end
diff --git a/lib/tasks/plugins.rake b/lib/tasks/plugins.rake
index 9c9f1fece85..f4d7edb2eb2 100644
--- a/lib/tasks/plugins.rake
+++ b/lib/tasks/plugins.rake
@@ -1,28 +1,4 @@
namespace :plugins do
- desc 'Generate skeleton for new plugin'
- task generate: :environment do
- ARGV.each { |a| task a.to_sym { } }
- name = ARGV[1]
-
- unless name.present?
- puts 'Error. You need to specify a name for the plugin'
- exit 1
- end
-
- class_name = name.classify
- param = name.underscore
- file_path = Rails.root.join('plugins', param + '_plugin.rb')
- template = File.read(Rails.root.join('generator_templates', 'plugins', 'template.rb'))
- template.gsub!('$NAME', class_name)
-
- if File.write(file_path, template)
- puts "Done. Your plugin saved under #{file_path}."
- puts 'Feel free to edit it.'
- else
- puts "Failed to save #{file_path}."
- end
- end
-
desc 'Validate existing plugins'
task validate: :environment do
puts 'Validating plugins from /plugins directory'
diff --git a/plugins/available/save_to_file.clj b/plugins/available/save_to_file.clj
new file mode 100755
index 00000000000..a59d83749d3
--- /dev/null
+++ b/plugins/available/save_to_file.clj
@@ -0,0 +1,3 @@
+#!/usr/bin/env clojure
+(let [in (slurp *in*)]
+ (spit "/tmp/clj-data.txt" in))
diff --git a/plugins/available/save_to_file.rb b/plugins/available/save_to_file.rb
new file mode 100755
index 00000000000..61b0df9bfd6
--- /dev/null
+++ b/plugins/available/save_to_file.rb
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+x = STDIN.read
+File.write('/tmp/rb-data.txt', x)
diff --git a/plugins/.gitkeep b/plugins/enabled/.gitkeep
index e69de29bb2d..e69de29bb2d 100644
--- a/plugins/.gitkeep
+++ b/plugins/enabled/.gitkeep