aethernal-agent 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.gitlab-ci.yml +23 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.lock +107 -0
  9. data/README.md +35 -0
  10. data/Rakefile +31 -0
  11. data/Vagrantfile +32 -0
  12. data/aethernal-agent.gemspec +45 -0
  13. data/bin/console +14 -0
  14. data/bin/run-aa-for-test +35 -0
  15. data/bin/setup +8 -0
  16. data/exe/aa-web +7 -0
  17. data/lib/aethernal_agent.rb +34 -0
  18. data/lib/aethernal_agent/apache/apache.rb +70 -0
  19. data/lib/aethernal_agent/apache/templates/aa-user.conf.erb +21 -0
  20. data/lib/aethernal_agent/app.rb +317 -0
  21. data/lib/aethernal_agent/apt.rb +30 -0
  22. data/lib/aethernal_agent/errors.rb +17 -0
  23. data/lib/aethernal_agent/filesystem.rb +178 -0
  24. data/lib/aethernal_agent/loader.rb +56 -0
  25. data/lib/aethernal_agent/manifest.rb +6 -0
  26. data/lib/aethernal_agent/operation.rb +51 -0
  27. data/lib/aethernal_agent/operation_pool.rb +46 -0
  28. data/lib/aethernal_agent/plugins/deluge/deluge.rb +65 -0
  29. data/lib/aethernal_agent/plugins/deluge/manifest.yml +51 -0
  30. data/lib/aethernal_agent/plugins/deluge/meta/deluge.png +0 -0
  31. data/lib/aethernal_agent/plugins/deluge/templates/auth.erb +2 -0
  32. data/lib/aethernal_agent/plugins/deluge/templates/core.conf.erb +95 -0
  33. data/lib/aethernal_agent/plugins/deluge/templates/deluge-web.service.erb +12 -0
  34. data/lib/aethernal_agent/plugins/deluge/templates/deluge.apache.conf.erb +9 -0
  35. data/lib/aethernal_agent/plugins/deluge/templates/deluged.service.erb +12 -0
  36. data/lib/aethernal_agent/plugins/deluge/templates/hostlist.conf.erb +14 -0
  37. data/lib/aethernal_agent/plugins/deluge/templates/web.conf.erb +24 -0
  38. data/lib/aethernal_agent/plugins/filebrowser/filebrowser.rb +45 -0
  39. data/lib/aethernal_agent/plugins/filebrowser/files/filebrowser.service +12 -0
  40. data/lib/aethernal_agent/plugins/filebrowser/manifest.yml +51 -0
  41. data/lib/aethernal_agent/plugins/filebrowser/meta/filebrowser.png +0 -0
  42. data/lib/aethernal_agent/plugins/filebrowser/templates/filebrowser.apache.conf.erb +6 -0
  43. data/lib/aethernal_agent/plugins/gitea/files/gitea.service +12 -0
  44. data/lib/aethernal_agent/plugins/gitea/gitea.rb +64 -0
  45. data/lib/aethernal_agent/plugins/gitea/manifest.yml +53 -0
  46. data/lib/aethernal_agent/plugins/gitea/meta/gitea.png +0 -0
  47. data/lib/aethernal_agent/plugins/gitea/templates/app.ini.erb +68 -0
  48. data/lib/aethernal_agent/plugins/gitea/templates/gitea.apache.conf.erb +6 -0
  49. data/lib/aethernal_agent/plugins/olaris/manifest.yml +52 -0
  50. data/lib/aethernal_agent/plugins/olaris/meta/olaris.png +0 -0
  51. data/lib/aethernal_agent/plugins/olaris/olaris.rb +35 -0
  52. data/lib/aethernal_agent/plugins/olaris/templates/olaris.apache.conf.erb +6 -0
  53. data/lib/aethernal_agent/plugins/olaris/templates/olaris.service.erb +12 -0
  54. data/lib/aethernal_agent/plugins/ombi/manifest.yml +57 -0
  55. data/lib/aethernal_agent/plugins/ombi/meta/ombi.jpeg +0 -0
  56. data/lib/aethernal_agent/plugins/ombi/ombi.rb +81 -0
  57. data/lib/aethernal_agent/plugins/ombi/templates/ombi.apache.conf.erb +6 -0
  58. data/lib/aethernal_agent/plugins/ombi/templates/ombi.service.erb +14 -0
  59. data/lib/aethernal_agent/plugins/plex/files/plex.service +26 -0
  60. data/lib/aethernal_agent/plugins/plex/manifest.yml +49 -0
  61. data/lib/aethernal_agent/plugins/plex/meta/plex.png +0 -0
  62. data/lib/aethernal_agent/plugins/plex/plex.rb +65 -0
  63. data/lib/aethernal_agent/plugins/plex/templates/Preferences.xml.erb +2 -0
  64. data/lib/aethernal_agent/plugins/radarr/files/radarr.service +13 -0
  65. data/lib/aethernal_agent/plugins/radarr/manifest.yml +68 -0
  66. data/lib/aethernal_agent/plugins/radarr/meta/radarr.png +0 -0
  67. data/lib/aethernal_agent/plugins/radarr/radarr.rb +72 -0
  68. data/lib/aethernal_agent/plugins/radarr/templates/config.xml.erb +16 -0
  69. data/lib/aethernal_agent/plugins/radarr/templates/radarr.apache.conf.erb +6 -0
  70. data/lib/aethernal_agent/plugins/sonarr/files/sonarr.service +13 -0
  71. data/lib/aethernal_agent/plugins/sonarr/manifest.yml +66 -0
  72. data/lib/aethernal_agent/plugins/sonarr/meta/sonarr.jpeg +0 -0
  73. data/lib/aethernal_agent/plugins/sonarr/sonarr.rb +70 -0
  74. data/lib/aethernal_agent/plugins/sonarr/templates/config.xml.erb +16 -0
  75. data/lib/aethernal_agent/plugins/sonarr/templates/sonarr.apache.conf.erb +6 -0
  76. data/lib/aethernal_agent/plugins/vnc/files/xstartup +9 -0
  77. data/lib/aethernal_agent/plugins/vnc/manifest.yml +41 -0
  78. data/lib/aethernal_agent/plugins/vnc/meta/vnc.png +0 -0
  79. data/lib/aethernal_agent/plugins/vnc/templates/vnc.service.erb +14 -0
  80. data/lib/aethernal_agent/plugins/vnc/vnc.rb +41 -0
  81. data/lib/aethernal_agent/systemd.rb +123 -0
  82. data/lib/aethernal_agent/template.rb +57 -0
  83. data/lib/aethernal_agent/utils.rb +107 -0
  84. data/lib/aethernal_agent/version.rb +3 -0
  85. data/lib/aethernal_agent/webserver/api.rb +77 -0
  86. data/lib/aethernal_agent/webserver/core.rb +32 -0
  87. metadata +257 -0
@@ -0,0 +1,56 @@
1
+ require 'aethernal_agent/apt'
2
+ require 'aethernal_agent/utils'
3
+ require 'aethernal_agent/apache/apache'
4
+
5
+ module AethernalAgent
6
+ class Loader
7
+ include AethernalAgent::Apt
8
+ include AethernalAgent::Utils
9
+
10
+ attr_accessor :loaded_manifests
11
+
12
+ def initialize
13
+ self.loaded_manifests = []
14
+ self.dynamic_load
15
+ end
16
+
17
+ def ensure_server_state
18
+ apt_package(packages: ["unzip", "apache2"])
19
+
20
+ AethernalAgent::Apache.new.ensure_mods
21
+ end
22
+
23
+
24
+ def dynamic_load
25
+ AethernalAgent.logger.info "Checking embedded plugins"
26
+ embedded_plugins = File.expand_path(File.join(File.dirname(__FILE__), 'plugins/*/*.yml'))
27
+ require_plugins_from_paths(embedded_plugins)
28
+
29
+ AethernalAgent.logger.info "Checking custom plugins"
30
+ custom_plugins = File.join(Dir.home,".config", "bytesized", "aethernal_agent", "plugins", "*", "*.yml")
31
+ require_plugins_from_paths(custom_plugins)
32
+
33
+ AethernalAgent.logger.info "Ensuring server state"
34
+ self.ensure_server_state
35
+ end
36
+
37
+ def require_plugins_from_paths(paths)
38
+ AethernalAgent.logger.debug "Checking in #{paths}"
39
+ Dir[paths].each do |file_path|
40
+ m = read_manifest(file_path)
41
+ AethernalAgent.logger.info "Loading #{m.name} - v#{m.version} from #{m.script_name}"
42
+ if check_manifest(m)
43
+ require file_path.gsub("manifest.yml",m["script_name"])
44
+ self.loaded_manifests << m
45
+ else
46
+ AethernalAgent.logger.warn "Manifest #{m.name} required aethernal_agent version '#{m.required_aethernal_agent_version}' but '#{AethernalAgent::VERSION}' is loaded, not loading plugin."
47
+ end
48
+ end
49
+ end
50
+
51
+ def read_manifest(file_path)
52
+ AethernalAgent.logger.info "Loading manifest from '#{file_path}'"
53
+ return OpenStruct.new(YAML.load_file(file_path))
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ module AethernalAgent
2
+ class Manifest
3
+ def self.load_file(file_path)
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,51 @@
1
+ class AethernalAgent::Operation
2
+ attr_accessor :uuid, :plugin_name, :method, :options, :result, :started_at, :completed_at, :exception, :backtrace, :errors
3
+
4
+ def initialize(plugin_name, method, options)
5
+ self.plugin_name = plugin_name
6
+ self.method = method
7
+ self.options = options
8
+ self.uuid = SecureRandom.uuid
9
+ end
10
+
11
+ def run
12
+ self.started_at = Time.now
13
+
14
+ begin
15
+ plugin = "AethernalAgent::#{self.plugin_name.titlecase}".constantize.new(self.options)
16
+ self.result = plugin.send(self.method, self.options)
17
+ if self.result.is_a?(Hash) && self.result.has_key?(:errors)
18
+ self.errors = self.result[:errors]
19
+ end
20
+ rescue StandardError => e
21
+ self.exception = e.message
22
+ self.backtrace = e.backtrace
23
+ end
24
+
25
+ self.completed_at = Time.now
26
+ end
27
+
28
+ def success?
29
+ !self.failed?
30
+ end
31
+
32
+ def failed?
33
+ !self.exception.nil? || !self.errors.blank?
34
+ end
35
+
36
+ def is_completed?
37
+ !self.completed_at.nil?
38
+ end
39
+
40
+ def is_started?
41
+ !self.started_at.nil?
42
+ end
43
+
44
+ def attributes
45
+ {method: self.method, plugin_name: self.plugin_name, options: self.options, uuid: self.uuid, result: self.result, success: self.success?, failed: self.failed?, is_completed: self.is_completed?, errors: self.errors, exception: self.exception, backtrace: self.backtrace, completed_at: self.completed_at, started_at: self.started_at}
46
+ end
47
+
48
+ def to_json(options ={})
49
+ self.attributes.to_json
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ class AethernalAgent::OperationPool
2
+ attr_accessor :operations
3
+
4
+ def initialize(size)
5
+ @size = size
6
+ @jobs = Queue.new
7
+ self.operations = {}
8
+ end
9
+
10
+ def start
11
+ @pool = Array.new(@size) do |i|
12
+ Thread.new do
13
+ Thread.current[:id] = i
14
+ catch(:exit) do
15
+ loop do
16
+ op = @jobs.pop
17
+ AethernalAgent.logger.debug("Worker #{i} - Picking up job #{op.uuid}")
18
+ op.run
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def queue_size
26
+ @jobs.size
27
+ end
28
+
29
+ def operation_size
30
+ self.operations.keys.size
31
+ end
32
+
33
+ def add_operation(op)
34
+ @jobs << op
35
+ self.operations[op.uuid] = op
36
+ end
37
+
38
+ def get_operation(uuid)
39
+ op = self.operations[uuid]
40
+ if !op.nil? && op.is_completed?
41
+ self.operations.delete(uuid)
42
+ end
43
+
44
+ return op
45
+ end
46
+ end
@@ -0,0 +1,65 @@
1
+ class AethernalAgent::Deluge < AethernalAgent::App
2
+ def initialize(options = {})
3
+ super(options)
4
+ end
5
+
6
+ def install_packages(options = {})
7
+ super(options)
8
+ end
9
+
10
+ def uninstall_packages(options = {})
11
+ super(options)
12
+ end
13
+
14
+ def remove_app_user(options = {})
15
+ super do
16
+ directory(home_folder_path(".config/deluge"), action: :delete)
17
+ end
18
+ end
19
+
20
+ def configure_app_user(options = {})
21
+ self.install_packages(options)
22
+
23
+ super(options) do |opts|
24
+ directory( home_folder_path(".config/deluge"), owner: self.user)
25
+ salt = SecureRandom.hex(20)
26
+
27
+ vars = {
28
+ identifier: SecureRandom.hex(20),
29
+ daemon_port: opts['daemon_port'],
30
+ port: opts['port'],
31
+ password: opts['password'],
32
+ user: opts['user'],
33
+ home: home_folder_path,
34
+ salt: salt,
35
+ listen_port: opts['listen_port'],
36
+ password_sha: sha_1_hash(opts['password'], salt)
37
+ }
38
+
39
+ write_template(template_path('core.conf.erb'),
40
+ deluge_config_path('core.conf'),
41
+ vars,
42
+ {owner: vars[:user]})
43
+
44
+ write_template(template_path('web.conf.erb'),
45
+ deluge_config_path('web.conf'),
46
+ vars,
47
+ {owner: vars[:user]})
48
+
49
+ write_template(template_path('auth.erb'),
50
+ deluge_config_path('auth'),
51
+ vars,
52
+ {owner: vars[:user]})
53
+
54
+ write_template(template_path('hostlist.conf.erb'),
55
+ deluge_config_path('hostlist.conf'),
56
+ vars,
57
+ {owner: vars[:user]})
58
+ end
59
+ end
60
+
61
+ protected
62
+ def deluge_config_path(path ="/")
63
+ File.join(home_folder_path(".config/deluge"), path)
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ name: Deluge
2
+ script_name: deluge.rb
3
+ version: 0.1
4
+ required_aethernal_agent_version: "~> 0.1.0"
5
+ description: Deluge is a fully-featured cross-platform BitTorrent client.
6
+ installation_type: global_install
7
+ configuration_type: multi_user
8
+ plain_name: deluge
9
+ built_in_updater: false
10
+ apache_configuration: deluge.apache.conf.erb
11
+ icon:
12
+ name: deluge.png
13
+ sha256sum: 23931765c77e7d667bdfef7a04f16593a4832a76620f393d7b965b57c017ae4b
14
+ services:
15
+ - deluged
16
+ - deluge-web
17
+ actions:
18
+ restart:
19
+ user:
20
+ required: true
21
+ linux_user: true
22
+ configure_app_user:
23
+ listen_port:
24
+ auto_generate_port: true
25
+ match_host_port: true
26
+ daemon_port:
27
+ auto_generate_port: true
28
+ port:
29
+ auto_generate_port: true
30
+ min: 9000
31
+ max: 9999
32
+ user:
33
+ required: true
34
+ linux_user: true
35
+ password:
36
+ required: false
37
+ auto_generate: true
38
+ display_values:
39
+ - user
40
+ - password
41
+ estimated_size_mb: 30
42
+ package:
43
+ ppa:
44
+ - deluge-team/stable
45
+ apt:
46
+ "18.04":
47
+ packages:
48
+ - deluged
49
+ - deluge-gtk
50
+ - deluge-web
51
+ - deluge-console
@@ -0,0 +1,2 @@
1
+ localclient:b1f2fddc91ec44c08c198646c47feef002c317c1:10
2
+ <%= @user %>:<%= @password_sha %>:10
@@ -0,0 +1,95 @@
1
+ {
2
+ "file": 1,
3
+ "format": 1
4
+ }{
5
+ "add_paused": false,
6
+ "allow_remote": false,
7
+ "auto_manage_prefer_seeds": false,
8
+ "auto_managed": true,
9
+ "cache_expiry": 60,
10
+ "cache_size": 512,
11
+ "copy_torrent_file": false,
12
+ "daemon_port": <%= @daemon_port %>,
13
+ "del_copy_torrent_file": false,
14
+ "dht": true,
15
+ "dont_count_slow_torrents": false,
16
+ "download_location": "<%= @home %>/Downloads",
17
+ "download_location_paths_list": [],
18
+ "enabled_plugins": [],
19
+ "enc_in_policy": 1,
20
+ "enc_level": 2,
21
+ "enc_out_policy": 1,
22
+ "geoip_db_location": "/usr/share/GeoIP/GeoIP.dat",
23
+ "ignore_limits_on_local_network": true,
24
+ "info_sent": 0.0,
25
+ "listen_interface": "",
26
+ "listen_ports": [
27
+ <%= @listen_port %>,
28
+ <%= @listen_port %>
29
+ ],
30
+ "listen_random_port": null,
31
+ "listen_reuse_port": true,
32
+ "listen_use_sys_port": false,
33
+ "lsd": true,
34
+ "max_active_downloading": 3,
35
+ "max_active_limit": 10,
36
+ "max_active_seeding": 1000,
37
+ "max_connections_global": 200,
38
+ "max_connections_per_second": 20,
39
+ "max_connections_per_torrent": -1,
40
+ "max_download_speed": -1.0,
41
+ "max_download_speed_per_torrent": -1,
42
+ "max_half_open_connections": 50,
43
+ "max_upload_slots_global": 100,
44
+ "max_upload_slots_per_torrent": -1,
45
+ "max_upload_speed": -1.0,
46
+ "max_upload_speed_per_torrent": -1,
47
+ "move_completed": false,
48
+ "move_completed_path": "<%= @home %>/Downloads",
49
+ "move_completed_paths_list": [],
50
+ "natpmp": true,
51
+ "new_release_check": false,
52
+ "outgoing_interface": "",
53
+ "outgoing_ports": [
54
+ 0,
55
+ 0
56
+ ],
57
+ "path_chooser_accelerator_string": "Tab",
58
+ "path_chooser_auto_complete_enabled": true,
59
+ "path_chooser_max_popup_rows": 20,
60
+ "path_chooser_show_chooser_button_on_localhost": true,
61
+ "path_chooser_show_hidden_files": false,
62
+ "peer_tos": "0x00",
63
+ "plugins_location": "<%= @home %>/.config/deluge/plugins",
64
+ "pre_allocate_storage": false,
65
+ "prioritize_first_last_pieces": false,
66
+ "proxy": {
67
+ "anonymous_mode": false,
68
+ "force_proxy": false,
69
+ "hostname": "",
70
+ "password": "",
71
+ "port": 8080,
72
+ "proxy_hostnames": true,
73
+ "proxy_peer_connections": true,
74
+ "proxy_tracker_connections": true,
75
+ "type": 0,
76
+ "username": ""
77
+ },
78
+ "queue_new_to_top": false,
79
+ "random_outgoing_ports": true,
80
+ "random_port": false,
81
+ "rate_limit_ip_overhead": true,
82
+ "remove_seed_at_ratio": false,
83
+ "seed_time_limit": 180,
84
+ "seed_time_ratio_limit": 7.0,
85
+ "send_info": false,
86
+ "sequential_download": false,
87
+ "share_ratio_limit": 2.0,
88
+ "shared": false,
89
+ "stop_seed_at_ratio": false,
90
+ "stop_seed_ratio": 2.0,
91
+ "super_seeding": false,
92
+ "torrentfiles_location": "<%= @home %>/Downloads",
93
+ "upnp": true,
94
+ "utpex": true
95
+ }
@@ -0,0 +1,12 @@
1
+ [Unit]
2
+ Description=Deluge Web
3
+ After=network-online.target
4
+
5
+ [Service]
6
+ Type=simple
7
+ ExecStart=/usr/bin/deluge-web -d
8
+ Restart=on-failure
9
+ TimeoutStopSec=120
10
+
11
+ [Install]
12
+ WantedBy=multi-user.target
@@ -0,0 +1,9 @@
1
+ ProxyPass /deluge http://127.0.0.1:<%= @port %>/
2
+ <Location /deluge>
3
+ ProxyPassReverse /
4
+ ProxyPassReverseCookiePath / /deluge
5
+ RequestHeader set X-Deluge-Base "/deluge"
6
+ Order allow,deny
7
+ Allow from all
8
+ </Location>
9
+
@@ -0,0 +1,12 @@
1
+ [Unit]
2
+ Description=Deluge Daemon
3
+ After=network-online.target
4
+
5
+ [Service]
6
+ Type=simple
7
+ ExecStart=/usr/bin/deluged -d
8
+ Restart=on-failure
9
+ TimeoutStopSec=120
10
+
11
+ [Install]
12
+ WantedBy=multi-user.target
@@ -0,0 +1,14 @@
1
+ {
2
+ "file": 3,
3
+ "format": 1
4
+ }{
5
+ "hosts": [
6
+ [
7
+ "<%= @identifier %>",
8
+ "127.0.0.1",
9
+ <%= @daemon_port %>,
10
+ "<%= @user %>",
11
+ "<%= @password_sha %>"
12
+ ]
13
+ ]
14
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "file": 2,
3
+ "format": 1
4
+ }{
5
+ "base": "/",
6
+ "cert": "ssl/daemon.cert",
7
+ "default_daemon": "",
8
+ "enabled_plugins": [],
9
+ "first_login": false,
10
+ "https": false,
11
+ "interface": "::",
12
+ "language": "",
13
+ "pkey": "ssl/daemon.pkey",
14
+ "port": <%= @port %>,
15
+ "pwd_salt": "<%= @salt %>",
16
+ "pwd_sha1": "<%= @password_sha %>",
17
+ "session_timeout": 3600,
18
+ "sessions": {},
19
+ "show_session_speed": true,
20
+ "show_sidebar": true,
21
+ "sidebar_multiple_filters": true,
22
+ "sidebar_show_zero": false,
23
+ "theme": "gray"
24
+ }