compose-hook 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9a8865abb92f4d9916b9f007a066da7061623976bd520d0ee5dad4cf0e4564d
4
- data.tar.gz: ea8dd4da5e6cd2dd4430d9d95cce2e3e3693f6cebf7542f4330b2c176f951254
3
+ metadata.gz: c3491bcf7a0049e4ff7bfa1ba0db224ed10f40050c3bede86d09b770fad954da
4
+ data.tar.gz: fc05d1cc28ac4cacb2d1df76587fc915fa4074bc2798153f81628fc9e8e78d53
5
5
  SHA512:
6
- metadata.gz: ab7ab971dd554908b7f268201ecd6f5da5332b7750db790188001a211c1cb152136ee3dcda0e0440c276034f7b9027265564d98eb36ada6cbc1c3764f7e3419f
7
- data.tar.gz: e7cd153333d508b66136c099a3ff3c9e90f970e3f117dff97cf17e8e9da5e77be24f786cd35d9975da377f1448f49ab5506bce584c1dacc7591a2cc99cf38292
6
+ metadata.gz: 0bd14948077b984c891ffe561a640902b0d05cebc671edeb841cd5d78b02043deeeb03da02fd019c3dfae6357784c44780f0701e26d55d92e90896d7fc8e8fcd
7
+ data.tar.gz: f81395406a042fbe05dd04d8c80a8a5b98d2ab7cbff321bece6968d2a4820f37494ebea4c2fabb70da287c3e80ccb924359f7e6f5c4722ced8bbe4060b1330ff
data/.drone.yml CHANGED
@@ -26,6 +26,15 @@ steps:
26
26
  branch:
27
27
  - master
28
28
 
29
+ trigger:
30
+ event:
31
+ - push
32
+
33
+ ---
34
+ kind: pipeline
35
+ name: tag
36
+
37
+ steps:
29
38
  - name: Publish to RubyGems
30
39
  image: ruby:2.6
31
40
  environment:
@@ -39,8 +48,8 @@ steps:
39
48
  - gem update bundler
40
49
  - bundle --jobs $(nproc)
41
50
  - bundle exec gem build compose-hook.gemspec
42
- - bundle exec gem push compose-hook-0.1.0.gem
51
+ - bundle exec gem push compose-hook-$DRONE_TAG.gem
43
52
 
44
53
  trigger:
45
54
  event:
46
- - push
55
+ - tag
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- compose-hook (0.1.0)
4
+ compose-hook (0.1.1)
5
5
  faraday
6
6
  jwt (~> 2.2)
7
7
  puma
data/README.md CHANGED
@@ -1,23 +1,40 @@
1
1
  # Compose-hook
2
2
 
3
+
3
4
  Simple application to update a service managed by compose using a webhook.
4
5
  The trigger is secured with a shared secret.
5
6
 
6
- ## Usage
7
+
8
+
9
+ ### Installation
7
10
 
8
11
  Install the gem:
9
12
  ```
10
- gem install compose-hook
13
+ gem install compose-hook
11
14
  ```
12
15
 
13
16
  Install the systemd service on the target machine:
14
17
  ```
15
- bin/install_webhook
18
+ bin/install_webhook
16
19
  ```
17
20
 
21
+ Create a config file of the following format:
22
+ ```yaml
23
+ - domain: "www.example.com" # target domain
24
+ root: "/home/deploy/example" # the root location of docker-compose
25
+ subpath: "compose" # [optional] directory containing target Compose files
26
+ - domain: "its.awesome.com"
27
+ root: "/home/deploy/awesome"
28
+ subpath: ""
29
+ ```
30
+
31
+ Export the config file path as `CONFIG_PATH` before launching the server.
32
+
33
+ ### Usage
34
+
18
35
  Test your installation with a payload
19
36
  ```
20
- compose-payload *service* *docker image* *url*
37
+ compose-payload *service* *docker image* *url*
21
38
  ```
22
39
 
23
40
  Made with :heart: at [openware](https://www.openware.com/)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -1,11 +1,19 @@
1
- #!/bin/bash
2
- SECRET=$(ruby -rsecurerandom -e 'puts SecureRandom.hex(20)')
1
+ #!/usr/bin/env ruby
3
2
 
4
- sed s/GENERATED_HMAC_SECRET/${SECRET}/g templates/webhook.service > webhook.service
5
- sed -i s#TARGET_DIRECTORY#${PWD}#g webhook.service
3
+ # frozen_string_literal: true
6
4
 
7
- echo "Generated Secret: ${SECRET}"
5
+ require 'erb'
6
+ require 'fileutils'
8
7
 
9
- sudo mv ./webhook.service /etc/systemd/system/webhook.service
10
- sudo systemctl daemon-reload
11
- sudo systemctl start webhook
8
+ TEMPLATE_PATH = "templates/webhook.service.erb"
9
+ OUTPUT_PATH = "/etc/systemd/system/webhook.service"
10
+
11
+ @secret = SecureRandom.hex(20)
12
+ @config_path = ENV.fetch("STAGES_PATH", File.join(Dir.pwd, "config/deployments.yml"))
13
+ template = ERB.new(File.read(TEMPLATE_PATH))
14
+ File.write(OUTPUT_PATH, template.result(binding))
15
+
16
+ puts "Generated Secret: #{secret}"
17
+
18
+ system("sudo systemctl daemon-reload")
19
+ system("sudo systemctl start webhook")
@@ -0,0 +1,3 @@
1
+ - domain: "www.example.com"
2
+ root: "/home/deploy/example"
3
+ subpath: "compose"
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "English"
3
4
  require "json"
4
5
  require "yaml"
5
6
  require "sinatra/base"
@@ -4,6 +4,8 @@ class ComposeHook::WebHook < Sinatra::Base
4
4
  class RequestError < StandardError; end
5
5
  class ServerError < StandardError; end
6
6
 
7
+ attr_accessor :config, :secret, :decoder
8
+
7
9
  CONFIG_PATH = "compose/docker-compose.yml"
8
10
  STAGES_PATH = "/home/deploy/webhook/stages.yml"
9
11
 
@@ -11,18 +13,35 @@ class ComposeHook::WebHook < Sinatra::Base
11
13
 
12
14
  def initialize
13
15
  super
14
- secret = ENV["WEBHOOK_JWT_SECRET"]
15
- raise "WEBHOOK_JWT_SECRET is not set" if secret.to_s.empty?
16
+
17
+ @secret = ENV["WEBHOOK_JWT_SECRET"]
18
+ raise "WEBHOOK_JWT_SECRET is not set" if @secret.to_s.empty?
19
+
20
+ @config = YAML.load_file(ENV["CONFIG_PATH"])
21
+ raise "The config file is empty or non-existent" if @config.empty?
16
22
 
17
23
  @decoder = ComposeHook::Payload.new(secret: secret)
18
24
  end
19
25
 
20
- def update_config(service, image)
21
- config = YAML.load_file(CONFIG_PATH)
22
- raise RequestError.new("Unknown service") if config["services"][service].nil?
26
+ def update_service(path, service, image)
27
+ file = YAML.load_file(path)
28
+
29
+ file["services"][service]["image"] = image
30
+ File.write(path, file.to_yaml)
31
+ end
32
+
33
+ def find_service(service, path)
34
+ res = ""
23
35
 
24
- config["services"][service]["image"] = image
25
- File.open(CONFIG_PATH, "w") {|f| f.write config.to_yaml }
36
+ Dir[File.join(path, "*.yml")].each do |file|
37
+ begin
38
+ res = file.path unless YAML.load_file(file)["services"][service].empty?
39
+ rescue StandardError => e
40
+ puts "Error while parsing deployment files:", e
41
+ end
42
+ end
43
+
44
+ res
26
45
  end
27
46
 
28
47
  before do
@@ -38,16 +57,16 @@ class ComposeHook::WebHook < Sinatra::Base
38
57
  decoded = @decoder.safe_decode(token)
39
58
  return answer(400, "invalid token") unless decoded
40
59
 
41
- stages = YAML.load_file(STAGES_PATH)
42
-
43
60
  service = decoded["service"]
44
61
  image = decoded["image"]
45
62
  hostname = request.host
46
- stage_path = stages.find {|s| s["domain"] == hostname }["path"]
63
+ deployment = config.find { |d| d["domain"] == hostname }
64
+ service_file = find_service(service, File.join(deployment["path"], deployment["subpath"]))
47
65
 
48
66
  return answer(400, "service is not specified") unless service
49
67
  return answer(400, "image is not specified") unless image
50
- return answer(404, "invalid domain") unless stage_path
68
+ return answer(404, "invalid domain") unless deployment
69
+ return answer(404, "invalid service") unless service_file
51
70
  return answer(400, "invalid image") if (%r(^(([-_\w\.]){,20}(\/|:))+([-\w\.]{,20})$) =~ image).nil?
52
71
 
53
72
  system "docker image pull #{image}"
@@ -57,10 +76,10 @@ class ComposeHook::WebHook < Sinatra::Base
57
76
  return answer(404, "invalid image") unless $CHILD_STATUS.success?
58
77
  end
59
78
 
60
- Dir.chdir(stage_path) do
61
- update_config(service, image)
79
+ Dir.chdir(deployment["root"]) do
80
+ update_service(service_file, service, image)
62
81
  system "docker-compose up -Vd #{service}"
63
- raise ServerError.new("could not restart container") unless $CHILD_STATUS.success?
82
+ raise ServerError.new("could not recreate the container") unless $CHILD_STATUS.success?
64
83
  end
65
84
 
66
85
  return answer(200, "service #{service} updated with image #{image}")
@@ -3,11 +3,11 @@ Description=Compose Webhook service
3
3
 
4
4
  [Service]
5
5
  User=deploy
6
- Environment="WEBHOOK_JWT_SECRET=GENERATED_HMAC_SECRET"
6
+ Environment="WEBHOOK_JWT_SECRET=<%= @secret %>"
7
+ Environment="CONFIG_PATH=<%= @config_path %>"
7
8
  ExecStart=/bin/bash -c "source ~/.rvm/scripts/rvm; compose-hook"
8
9
  Type=simple
9
10
  Restart=always
10
- WorkingDirectory=TARGET_DIRECTORY
11
11
 
12
12
  [Install]
13
13
  WantedBy=multi-user.target
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compose-hook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danylo P.
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-01-30 00:00:00.000000000 Z
13
+ date: 2020-02-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: faraday
@@ -246,11 +246,11 @@ files:
246
246
  - bin/install_webhook
247
247
  - compose-hook.gemspec
248
248
  - config.ru
249
+ - config/deployments.yml
249
250
  - lib/compose-hook.rb
250
251
  - lib/compose_hook/payload.rb
251
252
  - lib/compose_hook/webhook.rb
252
- - stages.yml
253
- - templates/webhook.service
253
+ - templates/webhook.service.erb
254
254
  homepage: https://www.openware.com
255
255
  licenses: []
256
256
  metadata: {}
data/stages.yml DELETED
@@ -1,2 +0,0 @@
1
- - domain: "www.example.com"
2
- path: "/home/deploy/example"