Skip to content

Commit fc11ccd

Browse files
authored
Merge pull request #1 from ib-ruby/framebuffer
Framebuffer
2 parents abc8934 + 6f34a6a commit fc11ccd

File tree

7 files changed

+127
-41
lines changed

7 files changed

+127
-41
lines changed

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
Provides a Container including a running TWS/Gateway in an isolated environment.
44

55
* The TWS/Gateway is restarted once a day
6+
* Framebuffer device to redirect Gateway-Output
7+
* X11 integration to run GUI-applications inside the container
68
* A reverse SSH-Tunnel is implemented for an extra layer of security
79
* [Simple-Monitor](https://github.com/ib-ruby/simple-monitor) is started upon setup
810
* Anything is prepared to run an reliable Trading-Bot in a secure environment
9-
* a suitable ruby installation to develope and run ib-ruby-trading solutions
11+
* A suitable ruby installation to develop and run ib-ruby-trading solutions
1012

1113
## Background
1214

@@ -29,7 +31,7 @@ provides the proprietary `IB-API` and the `FIX-Protocol`, the industry standard
2931
Edit `config.sh`
3032

3133
The script `setup.sh`
32-
* downloads and installs a minimized Ubuntu Linux Image (Unbuntu 20.4 LTS)
34+
* downloads and installs a minimized Ubuntu Linux Image (Ubuntu 20.4 LTS)
3335
* downloads the official binaries from the interactive brokers server into the container
3436
* downloads the [IBC](https://github.com/IbcAlpha/IBC) automation software providing tws/gateway-autostart
3537
* prepares the container to run ruby programs
@@ -57,6 +59,13 @@ The script is called with up to six arguments
5759
```
5860
All arguments are requested interactively if absent
5961

62+
After successfully initializing the container, the gateway is started (output goes into the framebuffer) and a TMUX-Session
63+
is opened. [Simple-Monitor](https://github.com/ib-ruby/simple-monitor) is autostarted.
64+
65+
The Control-Key is **CRTL A**; _CRTL A d_ detaches from the session.
66+
67+
The container is accessible (with X11 support) through: `lxc open {container name}`
68+
6069
## Finishing
6170

6271
On your Middleman Server, edit `~.ssh/config` and add the reverse tunnel specification
@@ -81,7 +90,7 @@ This software is tested on Ubuntu systems.
8190

8291
## ToDo
8392

84-
* Implement adressing the ibgateway application and enable the fix protocol
93+
* Implement addressing the ibgateway application and enable the fix protocol
8594

8695
## CONTRIBUTING
8796

kill-gateway.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
kill -9 `ps -ef | grep export | grep -v grep|awk '{print $2}'`
3+
kill -9 `ps -ef | grep java | grep -v grep|awk '{print $2}'`
4+
echo "Gateway instance killed"
5+

lxdguiprofile.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--2021-03-13 08:51:42-- https://blog.simos.info/wp-content/uploads/2018/06/lxdguiprofile.txt
2+
Auflösen des Hostnamens blog.simos.info (blog.simos.info) … 163.172.159.205
3+
Verbindungsaufbau zu blog.simos.info (blog.simos.info)|163.172.159.205|:443 … verbunden.
4+
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
5+
Länge: 614 [text/plain]
6+
Wird in »lxdguiprofile.txt.1« gespeichert.
7+
8+
0K 100% 68,2M=0s
9+
10+
2021-03-13 08:51:43 (68,2 MB/s) - »lxdguiprofile.txt.1« gespeichert [614/614]
11+

setup.sh

Lines changed: 85 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
export DEBIAN_FRONTEND=noninteractive
2525
source config.sh
2626

27+
print_status(){
28+
echo "[+] $*"
29+
}
30+
print_error() {
31+
echo "[!] $*"
32+
}
33+
print_question() {
34+
echo "[?] $*"
35+
}
2736

2837
if [ -f $logfile ] ; then rm $logfile ; fi
2938
touch $logfile
@@ -32,27 +41,27 @@ SILENT=$logfile
3241
if test -n "${1}"; then
3342
CONTAINER=${1}
3443
elif test -z $CONTAINER ; then
35-
read -p "Name des Containers: " CONTAINER
44+
read -p "[?] Name des Containers: " CONTAINER
3645
fi
3746
if test -z $CONTAINER ; then
38-
echo "Es muss eine Bezeichnung für den Container angegeben werden!"
47+
print_error "Es muss eine Bezeichnung für den Container angegeben werden!"
3948
exit 255
4049
fi
4150

4251
if test -n "${2}"; then
4352
LOGIN=${2}
4453
elif test -z "$LOGIN" ; then
45-
read -p "Interactive Brokers Account Login: " LOGIN
54+
read -p "[?] Interactive Brokers Account Login: " LOGIN
4655
fi
4756

4857
if test -n "${3}"; then
4958
PASS=${3}
5059
elif test -z "$PASS" ; then
51-
read -ps "Interactive Brokers Account Password: " PASS
60+
read -ps "[?] Interactive Brokers Account Password: " PASS
5261
fi
5362

5463
if test -z $DEMOACCOUNT ; then
55-
read -p "Demoaccount? [y|N]:"
64+
read -p "[?] Demoaccount? [y|N]:"
5665
if [ ! $REPLY = 'y' ] && [ ! $REPLY = 'j' ] ; then
5766
DEMOACCOUNT=0
5867
else
@@ -63,7 +72,7 @@ fi
6372
if test -n "${5}" ; then
6473
SSH_MIDDLEMAN_SERVER=${5}
6574
elif test -z "$SSH_MIDDLEMAN_SERVER" ; then
66-
read -p "Bezeichnung oder IP des Endpunkts des SSH-Tunnels [return=keinen Tunnel verwenden]: " SSH_MIDDLEMAN_SERVER
75+
read -p "[?] Bezeichnung oder IP des Endpunkts des SSH-Tunnels [return=keinen Tunnel verwenden]: " SSH_MIDDLEMAN_SERVER
6776
fi
6877

6978
if test -z $SSH_MIDDLEMAN_SERVER ; then
@@ -73,9 +82,9 @@ else
7382
if test -n "${4}" ; then
7483
SSH_PORT_NUMBER=${4}
7584
elif test -z "$SSH_PORT_NUMBER" ; then
76-
echo "Erzeuge zufällige Ports ..."
85+
print_status "Erzeuge zufällige Ports ..."
7786
SSH_PORT_NUMBER=$[ ( $RANDOM % 10000 ) + 10000 ]
78-
read -p "Port für SSH-Tunnel [$SSH_PORT_NUMBER]: " port
87+
read -p "[?] Port für SSH-Tunnel [$SSH_PORT_NUMBER]: " port
7988
if [ -n $port ] ; then
8089
SSH_PORT_NUMBER=$port
8190
fi
@@ -86,42 +95,43 @@ else
8695
SSH_MIDDLEMAN_USER=${6}
8796
elif test -z "$SSH_MIDDLEMAN_USER" ; then
8897
user=`whoami`
89-
read -p "Benutzer auf dem Endpunkt des SSH-Tunnels: $SSH_MIDDLEMAN_SERVER:[$user] " SSH_MIDDLEMAN_USER
98+
read -p "[?] Benutzer auf dem Endpunkt des SSH-Tunnels: $SSH_MIDDLEMAN_SERVER:[$user] " SSH_MIDDLEMAN_USER
9099
if [[ -z $SSH_MIDDLEMAN_USER ]]; then
91100
SSH_MIDDLEMAN_USER=$user
92101
fi
93102
fi
94103
fi
104+
read -p "[?] Gateway Ausgabe in Framebuffer umleiten? [Y/n]:" cont
105+
if [[ -n $cont || $cont == 'n' ]] ; then
106+
TWS_DISPLAY=:0
107+
else
108+
TWS_DISPLAY=:99
109+
fi
95110

96111

97-
echo "-------------------------"
98-
echo "Containter: $CONTAINER"
99-
echo "Login: $LOGIN"
100-
echo "Password: **** " # $PASS"
101-
echo "Demoaccount: `if [ $DEMOACCOUNT -eq 1 ] ; then echo "ja" ; else echo "nein"; fi ` "
102-
echo "Gateway/TWS: `if [ "$PRODUCT" = tws ] ; then echo "$INSTANCE" ; else echo "Gateway" ; fi `"
112+
print_status "......................................"
113+
print_status "Containter: $CONTAINER"
114+
print_status "Login: $LOGIN"
115+
print_status "Password: **** " # $PASS"
116+
print_status "Demoaccount: `if [ $DEMOACCOUNT -eq 1 ] ; then echo "ja" ; else echo "nein"; fi ` "
117+
print_status "Gateway/TWS: `if [ "$PRODUCT" = tws ] ; then echo "$INSTANCE" ; else echo "Gateway" ; fi `"
103118
if [ $SETUP_AUTOSSH -eq 1 ] ; then
104-
echo "PORT: $SSH_PORT_NUMBER"
105-
echo "Backport: $SSH_MONITORING_PORT_NUMBER"
106-
echo "Middleman: $SSH_MIDDLEMAN_SERVER"
107-
echo "Middleman User: $SSH_MIDDLEMAN_USER"
119+
print_status "PORT: $SSH_PORT_NUMBER"
120+
print_status "Backport: $SSH_MONITORING_PORT_NUMBER"
121+
print_status "Middleman: $SSH_MIDDLEMAN_SERVER"
122+
print_status "Middleman User: $SSH_MIDDLEMAN_USER"
108123
else
109-
echo "SSH-Tunnel wird nicht installiert "
110-
echo "......................................"
124+
print_status "SSH-Tunnel wird nicht installiert "
111125
fi
112-
read -p "Installieren? [Y/n]:" cont
126+
print_status "Ausgabe für Gateway: $TWS_DISPLAY "
127+
print_status "......................................"
128+
read -p "[?] Installieren? [Y/n]:" cont
113129
if [[ -n $cont || $cont == 'n' ]] ; then
114130
exit 255
115131
fi
116132

117133

118134

119-
print_status(){
120-
echo "[+] $*"
121-
}
122-
print_error() {
123-
echo "[!] $*"
124-
}
125135

126136

127137

@@ -182,7 +192,7 @@ prepare_lxd(){
182192
lxc profile create gui
183193
lxc profile edit gui < lxdguiprofile.txt
184194
# alias anlegen
185-
lxc alias add ubuntu 'exec @ARGS@ -- sudo --login --user ubuntu'
195+
lxc alias add open 'exec @ARGS@ -- sudo --login --user ubuntu'
186196
fi
187197

188198
}
@@ -238,6 +248,7 @@ init_container(){
238248

239249
print_status "Installiere Java Das dauert einige Minuten ..."
240250
$access_container sudo apt-get update >> $SILENT
251+
241252
$access_container sudo apt-get install -y openjdk-14-jre >> $SILENT
242253

243254
# testen, ob java installiert ist:
@@ -255,6 +266,21 @@ init_container(){
255266
fi
256267
}
257268

269+
270+
setup_xvfb(){
271+
local access_container="lxc exec $CONTAINER -- sudo --login --user ubuntu --"
272+
$access_container sudo apt-get install -y xvfb >> $SILENT
273+
lxc file push xvfb.service $CONTAINER/home/ubuntu/
274+
$access_container sudo mv /home/ubuntu/xvfb.service /lib/systemd/system/xvfb.service
275+
$access_container sudo chmod +x /lib/systemd/system/xvfb.service
276+
$access_container sudo systemctl enable /lib/systemd/system/xvfb.service
277+
$access_container sudo systemctl start xvfb.service
278+
# autostart xvfb
279+
$access_container sudo systemctl enable xvfb
280+
# $access_container export DISPLAY=:99
281+
282+
}
283+
258284
apply_ibc(){
259285
# Download der IBC-Software
260286
# Kopieren in Container
@@ -288,10 +314,10 @@ apply_ibc(){
288314
if [ $DEMOACCOUNT -eq 1 ] ; then
289315
$access_container sed -in ' 143 s/=live/=paper/ ' /home/ubuntu/ibc/config.ini
290316
# AcceptNonBrokerageAccountWarning=no
291-
$access_container sed -in ' 321 s/=no/=yes/ ' /home/ubuntu/ibc/config.ini
317+
$access_container sed -in ' 322 s/=no/=yes/ ' /home/ubuntu/ibc/config.ini
292318
fi
293319
# MinimizeMainWindow=no
294-
$access_container sed -in ' 206 s/=no/=yes/ ' /home/ubuntu/ibc/config.ini
320+
# $access_container sed -in ' 207 s/=no/=yes/ ' /home/ubuntu/ibc/config.ini
295321
if [ "$PRODUCT" = "tws" ] ; then
296322
$access_container sed -in ' 21 s/978/981/ ' /home/ubuntu/ibc/twsstart.sh
297323
# $access_container sed -in ' 23 s/=/=paper/ ' /home/ubuntu/ibc/twsstart.sh
@@ -304,15 +330,33 @@ apply_ibc(){
304330
$access_container sed -in ' 25 s/\/opt/\~/ ' /home/ubuntu/ibc/gatewaystart.sh
305331
touch ibc_cronfile
306332
local lxd_display=`$access_container echo $DISPLAY`
333+
# set display , if no DISPLAY setting is found, use :99 (xvfb)
334+
if [ $lxd_display ] ; then
335+
if [ "$TWS_DISPLAY" == ":0" ] ; then
336+
TWS_DISPLAY=$lxd_display
337+
fi
338+
else
339+
# $access_container export DISPLAY=:99
340+
TWS_DISPLAY=:99
341+
fi
342+
307343
echo 'START_TIME * * 1-5 export DISPLAY=ibc-display && /bin/bash /home/ubuntu/ibc/gatewaystart.sh -inline' > ibc_cronfile
308-
sed -e " 1 s/ibc-display/$lxd_display/ " -e " 1 s/START_TIME/$START_TIME/ " ibc_cronfile > t_c
309344
if [ $INSTANCE = "tws" ] ; then
310-
sed -in ' s/gateway/tws/ ' t_c
345+
sed -in ' s/gateway/tws/ ' ibc_cronfile
346+
sed -in ' s/ibc-display/$lxd_display/ ' ibc_cronfile
347+
else
348+
sed -in " s/ibc-display/$TWS_DISPLAY/ " ibc_cronfile
311349
fi
350+
sed -in " s/START_TIME/$START_TIME/ " ibc_cronfile
312351

313-
lxc file push t_c $CONTAINER/home/ubuntu/ibc_cronfile
314-
rm t_c
352+
lxc file push ibc_cronfile $CONTAINER/home/ubuntu/
315353
rm ibc_cronfile
354+
lxc file push start_framebuffer_gateway.sh $CONTAINER/home/ubuntu/
355+
lxc file push start_gateway.sh $CONTAINER/home/ubuntu/
356+
lxc file push kill_gateway.sh $CONTAINER/home/ubuntu/
357+
$access_container chmod a+x start_framebuffer_gateway.sh
358+
$access_container chmod a+x start_gateway.sh
359+
$access_container chmod a+x kill_gateway.sh
316360
$access_container crontab -u ubuntu /home/ubuntu/ibc_cronfile
317361
$access_container rm /home/ubuntu/ibc_cronfile
318362
fi
@@ -447,6 +491,7 @@ run_ats(){
447491
# starte die IB-Software
448492
local access_container="lxc exec $CONTAINER -- sudo --login --user ubuntu --"
449493
$access_container /home/ubuntu/ibc/${INSTANCE}start.sh -inline &
494+
$access_container /home/ubuntu/ibc/${INSTANCE}start.sh -inline &
450495
sleep 5
451496
$access_container /home/ubuntu/simple-monitor/start-simple-monitor
452497
return 0
@@ -463,20 +508,22 @@ launch_image
463508
download_ib_software
464509

465510
init_container
466-
print_status " +++++++++++++++++++++++++++++++++++++++ "
511+
print_status "......................................"
467512
print_status " Container ${CONTAINER} ist angelegt "
468513

514+
setup_xvfb
515+
print_status " Framebuffer device eingerichtet "
469516
if [ $SETUP_AUTOSSH -eq 1 ] ; then
470517
setup_reverse_tunnel
471518
print_status " Reverse Tunnel ist aufgebaut "
472519
fi
473520

474521

475522

476-
print_status "Installiere IBC "
523+
print_status " Installiere IBC "
477524
apply_ibc
478525

479-
print_status "Installiere simple-monitor "
526+
print_status " Installiere simple-monitor "
480527
install_simple_monitor
481528

482529
run_ats

start_framebuffer_gateway.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
export DISPLAY=:99 && /bin/bash /home/ubuntu/ibc/gatewaystart.sh -inline &

start_gateway.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
/home/ubuntu/ibc/gatewaystart.sh -inline &

xvfb.service

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[Unit]
2+
Description=X Virtual Frame Buffer Service
3+
After=network.target
4+
5+
[Service]
6+
User=root
7+
ExecStart=/usr/bin/Xvfb :99 -screen 0 1024x768x24
8+
9+
[Install]
10+
WantedBy=multi-user.target

0 commit comments

Comments
 (0)