nutella_framework 0.1.2 → 0.2.0
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.
- checksums.yaml +4 -4
- data/Gemfile +4 -3
- data/VERSION +1 -1
- data/actors/main_interface/main_interface_bot.rb +148 -0
- data/actors/main_interface/public/index.html +47 -0
- data/actors/main_interface/startup +5 -0
- data/actors/main_interface/views/index.erb +45 -0
- data/actors/main_interface/views/not_found_404.erb +37 -0
- data/lib/cli/nutella_cli.rb +24 -15
- data/lib/config/config.rb +5 -67
- data/lib/config/current_project.rb +58 -0
- data/lib/config/persisted_hash.rb +114 -0
- data/lib/config/runlist.rb +19 -83
- data/lib/core/command.rb +2 -2
- data/lib/core/commands/broker.rb +23 -24
- data/lib/core/commands/checkup.rb +36 -37
- data/lib/core/commands/help.rb +3 -3
- data/lib/core/commands/install.rb +3 -4
- data/lib/core/commands/new.rb +26 -28
- data/lib/core/commands/runs.rb +22 -31
- data/lib/core/commands/start.rb +134 -121
- data/lib/core/commands/stop.rb +62 -48
- data/lib/core/nutella_core.rb +23 -12
- data/lib/core/run_command.rb +44 -0
- data/lib/core/tmux.rb +20 -18
- data/lib/logging/nutella_logging.rb +5 -5
- data/lib/nutella_framework.rb +8 -6
- data/nutella_framework.gemspec +15 -12
- data/test/config/test_config.rb +23 -22
- data/test/config/test_project.rb +13 -12
- data/test/config/test_runlist.rb +30 -22
- metadata +15 -12
- data/lib/config/project.rb +0 -53
- data/lib/extra/config.ru +0 -2
- data/lib/extra/interfaces_list.erubis +0 -14
- data/lib/extra/main_interface.rb +0 -9
- data/test/test_nutella_framework.rb +0 -31
data/lib/core/commands/start.rb
CHANGED
@@ -1,156 +1,169 @@
|
|
1
|
-
require 'core/
|
1
|
+
require 'core/run_command'
|
2
2
|
require 'core/tmux'
|
3
3
|
|
4
4
|
module Nutella
|
5
|
-
class Start <
|
5
|
+
class Start < RunCommand
|
6
6
|
@description = 'Starts all or some of the bots in the current project'
|
7
|
-
|
7
|
+
|
8
8
|
def run(args=nil)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
|
10
|
+
# If the current directory is not a nutella project, return
|
11
|
+
return unless Nutella.current_project.exist?
|
12
|
+
|
13
|
+
# Extract run (passed run name) and run_id
|
14
|
+
run, run_id = extract_names args
|
15
|
+
# Extract project directory and run_id
|
16
|
+
cur_prj_dir = Nutella.current_project.dir
|
17
|
+
|
18
|
+
# Check that the run_id is unique and add it to the list of runs
|
19
|
+
# If it's not, return (without adding the run_id to the list of course)
|
20
|
+
return unless add_to_run_list( run_id, cur_prj_dir )
|
21
|
+
|
22
|
+
# If running on the internal broker, start it if needed
|
23
|
+
if Nutella.config['broker'] == 'localhost'
|
24
|
+
return unless start_internal_broker
|
19
25
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# Start all "hidden bots"
|
30
|
-
start_hidden_bots
|
26
|
+
|
27
|
+
# Start all nutella internal actors, if needed
|
28
|
+
return unless start_nutella_actors
|
29
|
+
|
30
|
+
# Install dependencies, compile and start all bots
|
31
|
+
return unless prepare_bot( cur_prj_dir, 'dependencies', 'Installing dependencies for' )
|
32
|
+
return unless prepare_bot( cur_prj_dir, 'compile', 'Compiling' )
|
33
|
+
return unless start_bots( cur_prj_dir, run_id )
|
34
|
+
|
31
35
|
# Output success message
|
32
|
-
|
36
|
+
output_success_message( run_id, run, 'started' )
|
37
|
+
output_monitoring_details run_id
|
33
38
|
end
|
34
|
-
|
35
|
-
|
39
|
+
|
40
|
+
|
36
41
|
private
|
37
|
-
|
38
|
-
|
39
|
-
def
|
40
|
-
|
41
|
-
console.error 'Impossible to start project: an instance of this project with the same
|
42
|
-
console.error "You might want to kill it with 'nutella stop
|
42
|
+
|
43
|
+
|
44
|
+
def add_to_run_list(run_id, prj_dir)
|
45
|
+
unless Nutella.runlist.add?( run_id, prj_dir )
|
46
|
+
console.error 'Impossible to start project: an instance of this project with the same run_id is already running!'
|
47
|
+
console.error "You might want to kill it with 'nutella stop #{run_id}'"
|
43
48
|
return false
|
44
49
|
end
|
45
|
-
|
50
|
+
true
|
46
51
|
end
|
47
|
-
|
48
|
-
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
|
53
|
+
|
54
|
+
def start_internal_broker
|
55
|
+
pid_file_path = "#{Nutella.config['broker_dir']}bin/.pid"
|
56
|
+
return true if sanitize_pid_file pid_file_path
|
57
|
+
# Broker is not running and there is no file so we try to start
|
58
|
+
# and create a new pid file. Note that the pid file is created by
|
59
|
+
# the startup script!
|
60
|
+
pid = fork
|
61
|
+
exec("#{Nutella.config['broker_dir']}/startup") if pid.nil?
|
62
|
+
# Sleep a bit to give the chance to the broker to actually start up
|
63
|
+
sleep(0.8)
|
64
|
+
# All went well so we return true
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
# Cleans the pid file of a given process
|
70
|
+
# @param [String] pid_file_path the file storing the pid file of the process
|
71
|
+
# @return [Boolean] true if the pid file exists AND the process with that pid is still alive
|
72
|
+
def sanitize_pid_file( pid_file_path )
|
73
|
+
# Does the pid file exist?
|
74
|
+
# If it does we try to see if the process with that pid is still alive
|
75
|
+
if File.exist? pid_file_path
|
76
|
+
pid_file = File.open(pid_file_path, 'rb')
|
77
|
+
pid = pid_file.read.to_i
|
78
|
+
pid_file.close
|
55
79
|
begin
|
56
|
-
|
57
|
-
#
|
80
|
+
# If this statement doesn't throw an exception then a process with
|
81
|
+
# this pid is still alive so we do nothing and just return true
|
82
|
+
Process.getpgid pid
|
83
|
+
return true
|
58
84
|
rescue
|
59
|
-
#
|
60
|
-
|
61
|
-
|
85
|
+
# If there is an exception, there is no process with this pid
|
86
|
+
# so we have a stale pid file that we need to remove
|
87
|
+
File.delete pid_file_path
|
88
|
+
return false
|
62
89
|
end
|
63
|
-
else
|
64
|
-
# Broker is not running and there is no file
|
65
|
-
startAndCreatePid()
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def startAndCreatePid()
|
70
|
-
pid = fork
|
71
|
-
exec("#{Nutella.config["broker_dir"]}/startup") if pid.nil?
|
72
|
-
end
|
73
|
-
|
74
|
-
def createBotsConfig
|
75
|
-
botsconfig = Nutella.config.to_h
|
76
|
-
botsconfig.delete(:runs)
|
77
|
-
botsconfig[:prj_name] = Nutella.currentProject.config["name"]
|
78
|
-
File.open("#{@prj_dir}/.botsconfig.json", "w") do |f|
|
79
|
-
f.write(JSON.pretty_generate(botsconfig))
|
80
90
|
end
|
91
|
+
# If there is no pid file, there is no process running
|
92
|
+
false
|
81
93
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
94
|
+
|
95
|
+
|
96
|
+
def start_nutella_actors
|
97
|
+
nutella_actors_dir = "#{Nutella.config['nutella_home']}actors"
|
98
|
+
for_each_actor_in_dir nutella_actors_dir do |actor|
|
99
|
+
if File.exist? "#{nutella_actors_dir}/#{actor}/startup"
|
100
|
+
unless start_nutella_actor "#{nutella_actors_dir}/#{actor}"
|
101
|
+
return false
|
102
|
+
end
|
91
103
|
end
|
92
|
-
console.info "Installing dependencies for bot #{bot}."
|
93
|
-
cur_dir = Dir.pwd
|
94
|
-
Dir.chdir "#{@prj_dir}/bots/#{bot}"
|
95
|
-
system "./dependencies"
|
96
|
-
Dir.chdir cur_dir
|
97
104
|
end
|
105
|
+
true
|
98
106
|
end
|
99
|
-
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
107
|
+
|
108
|
+
def start_nutella_actor( actor_dir )
|
109
|
+
pid_file_path = "#{actor_dir}/.pid"
|
110
|
+
return true if sanitize_pid_file pid_file_path
|
111
|
+
# Actor is not running and there is no pid file so we try to start
|
112
|
+
# the actor and create a new pid file. Note that the pid file is created by
|
113
|
+
# the startup script!
|
114
|
+
nutella_config_file = "#{Nutella.config['nutella_home']}config.json"
|
115
|
+
runs_list_file = "#{Nutella.config['nutella_home']}runlist.json"
|
116
|
+
if nutella_config_file==nil || runs_list_file==nil
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
command = "#{actor_dir}/startup #{nutella_config_file} #{runs_list_file}"
|
120
|
+
pid = fork
|
121
|
+
exec(command) if pid.nil?
|
122
|
+
# All went well so we return true
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def prepare_bot( cur_prj_dir, script, message )
|
128
|
+
for_each_actor_in_dir cur_prj_dir do |bot|
|
129
|
+
# Skip bot if there is no '' script
|
130
|
+
next unless File.exist? "#{cur_prj_dir}/bots/#{bot}/#{script}"
|
131
|
+
# Output message
|
132
|
+
console.info "#{message} bot #{bot}."
|
133
|
+
# Execute 'dependencies' script
|
106
134
|
cur_dir = Dir.pwd
|
107
|
-
Dir.chdir "#{
|
108
|
-
system "
|
135
|
+
Dir.chdir "#{cur_prj_dir}/bots/#{bot}"
|
136
|
+
system "./#{script}"
|
109
137
|
Dir.chdir cur_dir
|
110
138
|
end
|
139
|
+
true
|
111
140
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
141
|
+
|
142
|
+
|
143
|
+
def start_bots( cur_prj_dir, run_id )
|
144
|
+
bots_dir = "#{cur_prj_dir}/bots/"
|
145
|
+
# Create a new tmux instance for this run
|
146
|
+
tmux = Tmux.new run_id
|
147
|
+
for_each_actor_in_dir bots_dir do |bot|
|
148
|
+
# If there is no 'startup' script output a warning (because
|
149
|
+
# startup is mandatory) and skip the bot
|
150
|
+
unless File.exist?("#{bots_dir}#{bot}/startup")
|
117
151
|
console.warn "Impossible to start bot #{bot}. Couldn't locate 'startup' script."
|
118
152
|
next
|
119
153
|
end
|
120
|
-
|
154
|
+
# Create a new window in the session for this run
|
155
|
+
tmux.new_bot_window bot
|
121
156
|
end
|
157
|
+
true
|
122
158
|
end
|
123
159
|
|
124
|
-
def start_interfaces
|
125
|
-
ports = Hash.new
|
126
|
-
Dir.entries("#{@prj_dir}/interfaces").select {|entry| File.directory?(File.join("#{@prj_dir}/interfaces",entry)) and !(entry =='.' || entry == '..') }.each do |iface|
|
127
|
-
if !File.exist?("#{@prj_dir}/interfaces/#{iface}/index.html")
|
128
|
-
console.warn "Impossible to start interface #{iface}. Couldn't locate 'index.html' file."
|
129
|
-
next
|
130
|
-
end
|
131
|
-
ports[iface] = @tmux.new_interface_window(iface)
|
132
|
-
end
|
133
|
-
ports
|
134
|
-
end
|
135
160
|
|
136
|
-
def
|
137
|
-
#
|
138
|
-
|
139
|
-
# Nutella.runlist.length
|
140
|
-
# Nutella.config['broker']
|
141
|
-
# Create the webpage for all interfaces
|
142
|
-
# Start the web_server serving the whole interfaces directory
|
143
|
-
# Output message that shows the port where we are connecting
|
144
|
-
end
|
145
|
-
|
146
|
-
def outputSuccessMessage(runid, run)
|
147
|
-
if runid == Nutella.currentProject.config["name"]
|
148
|
-
console.success "Project " + Nutella.currentProject.config["name"] + " started. Do `tmux attach-session -t #{Nutella.currentProject.config["name"]}` to monitor your bots."
|
149
|
-
else
|
150
|
-
console.success "Project " + Nutella.currentProject.config["name"] + ", run " + run + " started"
|
151
|
-
end
|
161
|
+
def output_monitoring_details( run_id )
|
162
|
+
console.success "Do `tmux attach-session -t #{run_id}` to monitor your bots."
|
163
|
+
console.success "Go to http://localhost:#{Nutella.config['main_interface_port']}/#{run_id} to access your interfaces"
|
152
164
|
end
|
153
|
-
|
165
|
+
|
166
|
+
|
154
167
|
end
|
155
168
|
|
156
169
|
end
|
data/lib/core/commands/stop.rb
CHANGED
@@ -1,70 +1,84 @@
|
|
1
|
-
require 'core/
|
1
|
+
require 'core/run_command'
|
2
2
|
require 'core/tmux'
|
3
3
|
|
4
4
|
module Nutella
|
5
|
-
class Stop <
|
6
|
-
@description =
|
7
|
-
|
5
|
+
class Stop < RunCommand
|
6
|
+
@description = 'Stops all or some of the bots in the current project'
|
7
|
+
|
8
8
|
def run(args=nil)
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
# If the current directory is not a nutella project, return
|
11
|
+
return unless Nutella.current_project.exist?
|
12
|
+
|
13
|
+
# Extract run (passed run name) and run_id
|
14
|
+
run, run_id = extract_names args
|
15
|
+
|
16
|
+
# Check that the run_id exists in the list and, if it is not,
|
17
|
+
# return false
|
18
|
+
return unless remove_from_run_list run_id
|
19
|
+
|
20
|
+
# Stops all the bots
|
21
|
+
Tmux.kill_session run_id
|
22
|
+
|
23
|
+
# Stop all nutella internal actors, if needed
|
24
|
+
if Nutella.runlist.empty?
|
25
|
+
stop_nutella_actors
|
11
26
|
end
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
if Nutella.runlist.empty? and Nutella.config['broker'] == "localhost"
|
17
|
-
stopBroker
|
27
|
+
|
28
|
+
# If running on the internal broker, stop it if needed
|
29
|
+
if Nutella.runlist.empty? and Nutella.config['broker'] == 'localhost'
|
30
|
+
stop_broker
|
18
31
|
end
|
19
|
-
|
20
|
-
Tmux.killSession(runid)
|
21
|
-
# Deletes bots config file if it exists
|
22
|
-
deleteBotsConfigFile
|
32
|
+
|
23
33
|
# Output success message
|
24
|
-
|
34
|
+
output_success_message( run_id, run, 'stopped' )
|
25
35
|
end
|
26
36
|
|
27
37
|
|
28
38
|
private
|
39
|
+
|
29
40
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
if runid == Nutella.currentProject.config["name"]
|
35
|
-
console.warn "Run #{runid} doesn't exist. Impossible to stop it."
|
36
|
-
else
|
37
|
-
console.warn "Run #{run} doesn't exist. Impossible to stop it."
|
38
|
-
end
|
39
|
-
return
|
41
|
+
def remove_from_run_list( run_id )
|
42
|
+
unless Nutella.runlist.delete? run_id
|
43
|
+
console.warn "Run #{run_id} doesn't exist. Impossible to stop it."
|
44
|
+
return false
|
40
45
|
end
|
46
|
+
true
|
41
47
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
Process.kill("SIGKILL", pid)
|
50
|
-
File.delete(pidFile)
|
48
|
+
|
49
|
+
|
50
|
+
def stop_nutella_actors
|
51
|
+
nutella_actors_dir = "#{Nutella.config['nutella_home']}actors"
|
52
|
+
for_each_actor_in_dir nutella_actors_dir do |actor|
|
53
|
+
pid_file_path = "#{nutella_actors_dir}/#{actor}/.pid"
|
54
|
+
kill_process_with_pid pid_file_path
|
51
55
|
end
|
52
56
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
57
|
+
|
58
|
+
|
59
|
+
def stop_broker
|
60
|
+
pid_file_path = "#{Nutella.config['broker_dir']}/bin/.pid"
|
61
|
+
kill_process_with_pid pid_file_path
|
59
62
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
|
64
|
+
|
65
|
+
# Does the process pid file exist?
|
66
|
+
# If it does we send a SIGKILL to the process with that pid
|
67
|
+
# to stop the process and delete the pid file
|
68
|
+
def kill_process_with_pid( pid_file_path )
|
69
|
+
if File.exist? pid_file_path
|
70
|
+
pid_file = File.open( pid_file_path, 'rb' )
|
71
|
+
pid = pid_file.read.to_i
|
72
|
+
pid_file.close
|
73
|
+
begin
|
74
|
+
Process.kill( 'SIGKILL', pid )
|
75
|
+
rescue
|
76
|
+
# Pid file exists but process is dead. Do nothing
|
77
|
+
end
|
78
|
+
File.delete pid_file_path
|
66
79
|
end
|
67
80
|
end
|
81
|
+
|
68
82
|
|
69
83
|
end
|
70
84
|
end
|
data/lib/core/nutella_core.rb
CHANGED
@@ -1,32 +1,43 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# Require all commands by iterating through all the files
|
2
|
+
# in the commands directory
|
3
|
+
Dir["#{File.dirname(__FILE__)}/commands/*.rb"].each do |file|
|
4
|
+
# noinspection RubyResolve
|
3
5
|
require "core/commands/#{File.basename(file, File.extname(file))}"
|
4
6
|
end
|
5
7
|
|
6
8
|
module Nutella
|
7
9
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
# This method executes a particular command
|
11
|
+
# @param command [String] the name of the command
|
12
|
+
# @param args [Array<String>] command line parameters passed to the command
|
13
|
+
def Nutella.execute_command (command, args=nil)
|
14
|
+
# Check that the command exists and if it does,
|
15
|
+
# execute its run method passing the args parameters
|
16
|
+
if command_exists?(command)
|
12
17
|
Object::const_get("Nutella::#{command.capitalize}").new.run(args)
|
13
18
|
else
|
14
19
|
console.error "Unknown command #{command}"
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
18
|
-
#
|
19
|
-
|
23
|
+
# This method checks that a particular command exists
|
24
|
+
# @return [Boolean] true if the command exists, false otherwise
|
25
|
+
def Nutella.command_exists?(command)
|
20
26
|
return Nutella.const_get("Nutella::#{command.capitalize}").is_a?(Class)
|
21
27
|
rescue NameError
|
22
28
|
return false
|
23
29
|
end
|
24
30
|
|
25
|
-
#
|
31
|
+
# This method initializes the nutella configuration file (config.json) with:
|
32
|
+
# - NUTELLA_HOME: the directory nutella is installed in
|
33
|
+
# - tmp_dir: temporary directory used when installing remote templates
|
34
|
+
# - broker_dir: directory where the local broker is installed in
|
35
|
+
# - main_interface_port: the port used to serve interfaces
|
26
36
|
def Nutella.init
|
27
|
-
Nutella.config[
|
28
|
-
Nutella.config[
|
29
|
-
Nutella.config[
|
37
|
+
Nutella.config['nutella_home'] = NUTELLA_HOME
|
38
|
+
Nutella.config['tmp_dir'] = "#{NUTELLA_HOME}.tmp/"
|
39
|
+
Nutella.config['broker_dir'] = "#{NUTELLA_HOME}broker/"
|
40
|
+
Nutella.config['main_interface_port'] = 57880
|
30
41
|
end
|
31
42
|
|
32
43
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'core/command'
|
2
|
+
|
3
|
+
module Nutella
|
4
|
+
# This class describes a run command which can be either start or stop.
|
5
|
+
# It is mostly a commodity class for code reuse.
|
6
|
+
class RunCommand < Command
|
7
|
+
|
8
|
+
def run (args=nil)
|
9
|
+
console.error 'Running generic RunCommand!!! WAT?'
|
10
|
+
end
|
11
|
+
|
12
|
+
# Extracts run name and run_id
|
13
|
+
# @param [Array<String>] args command line arguments passed to the command
|
14
|
+
# @return [String, String ] the run name (cleaned of nils) and the run_id
|
15
|
+
def extract_names( args )
|
16
|
+
# Check that the run name passed as parameter is not nil
|
17
|
+
run = args.nil? ? nil : args[0]
|
18
|
+
# Extract run_id
|
19
|
+
run_id = args.nil? ? Nutella.runlist.extract_run_id( '' ) : Nutella.runlist.extract_run_id( args[0] )
|
20
|
+
return run, run_id
|
21
|
+
end
|
22
|
+
|
23
|
+
# Executes a code block for each actor in a certain directory
|
24
|
+
# @param [String] actors_dir directory where we are iterating
|
25
|
+
# @yield [actor_dir] Gives the actor directory to the block
|
26
|
+
def for_each_actor_in_dir( actors_dir, &block )
|
27
|
+
Dir.entries(actors_dir).select {|entry| File.directory?(File.join(actors_dir, entry)) && !(entry =='.' || entry == '..') }.each do |actor_dir|
|
28
|
+
block.call actor_dir
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def output_success_message(run_id, run, action)
|
34
|
+
if run_id == Nutella.current_project.config['name']
|
35
|
+
console.success "Project #{Nutella.current_project.config['name']} #{action}!"
|
36
|
+
else
|
37
|
+
console.success "Project #{Nutella.current_project.config['name']}, run #{run} #{action}!"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/core/tmux.rb
CHANGED
@@ -2,26 +2,27 @@ module Nutella
|
|
2
2
|
|
3
3
|
class Tmux
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize( run_id )
|
6
|
+
@run_id = run_id
|
7
7
|
end
|
8
8
|
|
9
|
-
def new_bot_window(bot)
|
10
|
-
if
|
9
|
+
def new_bot_window( bot )
|
10
|
+
if defined? @sessions
|
11
|
+
# If a session already exists,
|
12
|
+
# simply create a new window for 'bot'.
|
13
|
+
# -k destroys the window if it can't be created
|
14
|
+
# Print info about creation of window
|
15
|
+
`tmux new-window -kP -n #{bot} &> /dev/null`
|
16
|
+
@sessions.push bot
|
17
|
+
else
|
11
18
|
# If there is no sessions, let's create one and, at the same time, create a new window for the bot
|
12
|
-
`tmux new-session -d -s #{@
|
19
|
+
`tmux new-session -d -s #{@run_id} -n #{bot} &> /dev/null`
|
13
20
|
@sessions = [bot]
|
14
|
-
else
|
15
|
-
# Create new window for `bot`
|
16
|
-
# -k destroys it if it can't be created
|
17
|
-
# Pring info about creation of window
|
18
|
-
`tmux new-window -kP -n #{bot} &> /dev/null`
|
19
|
-
@sessions.push(bot)
|
20
21
|
end
|
21
22
|
# Select window
|
22
|
-
`tmux select-window -t #{@
|
23
|
+
`tmux select-window -t #{@run_id}:#{@sessions.length-1} &> /dev/null`
|
23
24
|
# Start bot
|
24
|
-
`tmux send-keys "cd bots/#{bot};./startup #{@
|
25
|
+
`tmux send-keys "cd bots/#{bot};./startup #{@run_id} #{Nutella.config['broker']}" C-m`
|
25
26
|
end
|
26
27
|
|
27
28
|
def new_interface_window( iface )
|
@@ -31,15 +32,16 @@ module Nutella
|
|
31
32
|
`tmux new-window -kP -n #{iface} &> /dev/null`
|
32
33
|
@sessions.push(iface)
|
33
34
|
# Select window
|
34
|
-
`tmux select-window -t #{@
|
35
|
-
port =
|
35
|
+
`tmux select-window -t #{@run_id}:#{@sessions.length-1} &> /dev/null`
|
36
|
+
port = Nutella.config['main_interface_port'] + @sessions.length
|
37
|
+
url = "http://localhost:#{port}/index.html"
|
36
38
|
# Start serving interface
|
37
39
|
`tmux send-keys "cd interfaces/#{iface};thin -R #{Nutella.config['nutella_home']}/lib/extra/config.ru -p #{port.to_s} start" C-m`
|
38
|
-
|
40
|
+
url
|
39
41
|
end
|
40
42
|
|
41
|
-
def self.
|
42
|
-
`tmux kill-session -t #{
|
43
|
+
def self.kill_session( run_id )
|
44
|
+
`tmux kill-session -t #{run_id} &> /dev/null`
|
43
45
|
end
|
44
46
|
|
45
47
|
end
|
@@ -8,9 +8,9 @@ module Nutella
|
|
8
8
|
include Singleton
|
9
9
|
|
10
10
|
def initialize
|
11
|
-
console = NutellaLogger.new(
|
12
|
-
log = NutellaLoggerRemote.new(
|
13
|
-
@loggers = {
|
11
|
+
console = NutellaLogger.new('console')
|
12
|
+
log = NutellaLoggerRemote.new('log')
|
13
|
+
@loggers = {:log => log, :console => console}
|
14
14
|
end
|
15
15
|
|
16
16
|
def logger(name)
|
@@ -25,11 +25,11 @@ end
|
|
25
25
|
module Kernel
|
26
26
|
|
27
27
|
def console
|
28
|
-
Nutella::NutellaLogging.instance.logger(
|
28
|
+
Nutella::NutellaLogging.instance.logger(:console)
|
29
29
|
end
|
30
30
|
|
31
31
|
def log
|
32
|
-
Nutella::NutellaLogging.instance.logger(
|
32
|
+
Nutella::NutellaLogging.instance.logger(:log)
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|
data/lib/nutella_framework.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
#
|
1
|
+
# Import all the modules
|
2
2
|
require 'logging/nutella_logging'
|
3
3
|
require 'core/nutella_core'
|
4
|
-
require 'cli/nutella_cli'
|
5
4
|
require 'config/config'
|
6
5
|
require 'config/runlist'
|
7
|
-
require 'config/
|
6
|
+
require 'config/current_project'
|
7
|
+
require 'cli/nutella_cli'
|
8
8
|
|
9
9
|
module Nutella
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
home_dir = File.dirname(__FILE__)
|
11
|
+
NUTELLA_HOME = home_dir[0..-4]
|
12
|
+
|
13
|
+
# If the nutella configuration file (config.json) is empty (or doesn't exist) we're going to initialize it
|
14
|
+
# with nutella constants and defaults
|
13
15
|
if Nutella.config.empty?
|
14
16
|
Nutella.init
|
15
17
|
end
|