Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
smartpublicbuilding
openhab-pb-stack
Commits
109d97c6
Commit
109d97c6
authored
Apr 23, 2019
by
dobli
Browse files
split hostname from building name
parent
a191a409
Changes
1
Hide whitespace changes
Inline
Side-by-side
building_manager.py
View file @
109d97c6
...
...
@@ -137,51 +137,52 @@ def generate_initial_compose():
yaml
.
dump
(
init_content
,
compose_f
)
def
add_sftp_service
(
hostname
,
number
=
0
):
def
add_sftp_service
(
building
,
number
=
0
):
"""Generates an sftp entry and adds it to the compose file
:
hostname
: names of
host
that the services is added to
:
building
: names of
building
that the services is added to
:number: increment of exposed port to prevent overlaps
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# service name
service_name
=
f
'sftp_
{
hostname
}
'
service_name
=
f
'sftp_
{
building
}
'
# template
template
=
get_service_template
(
Service
.
SFTP
.
prefix
)
# only label contraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
template
[
'ports'
]
=
[
f
'
{
2222
+
number
}
:22'
]
# attach volumes
volume_base
=
'/home/ohadmin/'
template
[
'volumes'
]
=
get_attachable_volume_list
(
volume_base
,
hostname
)
template
[
'volumes'
]
=
get_attachable_volume_list
(
volume_base
,
building
)
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
def
add_openhab_service
(
host
name
):
def
add_openhab_service
(
building
,
host
):
"""Generates an openhab entry and adds it to the compose file
:hostname: names of host that the services is added to
:building: name of building that the services is added to
:host: host the building is added to, used for routing
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# service name
service_name
=
f
'openhab_
{
hostname
}
'
service_name
=
f
'openhab_
{
building
}
'
# template
template
=
get_service_template
(
Service
.
OPENHAB
.
prefix
)
# only label contraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
# include in backups of this building
template
[
'deploy'
][
'labels'
].
append
(
f
'backup=
{
hostname
}
'
)
template
[
'deploy'
][
'labels'
].
append
(
f
'backup=
{
building
}
'
)
# traefik backend
template
[
'deploy'
][
'labels'
].
append
(
f
'traefik.backend=
{
service_name
}
'
)
# traefik frontend domain->openhab
template
[
'deploy'
][
'labels'
].
extend
(
generate_traefik_host_labels
(
host
name
,
segment
=
'main'
))
generate_traefik_host_labels
(
host
,
segment
=
'main'
))
# traefik frontend subdomain openhab_hostname.* -> openhab
template
[
'deploy'
][
'labels'
].
append
(
f
'traefik.sub.frontend.rule=HostRegexp:'
...
...
@@ -195,22 +196,22 @@ def add_openhab_service(hostname):
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
def
add_nodered_service
(
hostname
):
def
add_nodered_service
(
building
):
"""Generates an nodered entry and adds it to the compose file
:
hostname
: name
s
of
host
that the services is added to
:
building
: name of
building
that the services is added to
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# service name
service_name
=
f
'nodered_
{
hostname
}
'
service_name
=
f
'nodered_
{
building
}
'
# template
template
=
get_service_template
(
Service
.
NODERED
.
prefix
)
# only label contraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
template
[
'deploy'
][
'labels'
].
append
(
f
'traefik.backend=
{
service_name
}
'
)
template
[
'deploy'
][
'labels'
].
append
(
f
'backup=
{
hostname
}
'
)
template
[
'deploy'
][
'labels'
].
append
(
f
'backup=
{
building
}
'
)
template
[
'deploy'
][
'labels'
].
extend
(
generate_traefik_path_labels
(
service_name
,
segment
=
'main'
))
template
[
'deploy'
][
'labels'
].
extend
(
...
...
@@ -223,21 +224,21 @@ def add_nodered_service(hostname):
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
def
add_mqtt_service
(
hostname
,
number
=
0
):
def
add_mqtt_service
(
building
,
number
=
0
):
"""Generates an mqtt entry and adds it to the compose file
:
hostname
: name
s
of
host
that the services is added to
:
building
: name of
building
that the services is added to
:number: increment of exposed port to prevent overlaps
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# service name
service_name
=
f
'mqtt_
{
hostname
}
'
service_name
=
f
'mqtt_
{
building
}
'
# template
template
=
get_service_template
(
Service
.
MQTT
.
prefix
)
# only label contraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
# ports incremented by number of services
template
[
'ports'
]
=
[
f
'
{
1883
+
number
}
:1883'
,
f
'
{
9001
+
number
}
:9001'
]
...
...
@@ -248,17 +249,17 @@ def add_mqtt_service(hostname, number=0):
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
def
add_postgres_service
(
hostname
,
postfix
=
None
):
def
add_postgres_service
(
building
,
postfix
=
None
):
"""Generates an postgres entry and adds it to the compose file
:
hostname
: name
s
of
host
that the services is added to
:
building
: name of
building
that the services is added to
:postfix: an identifier for this service
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# use
hostname
as postfix when empty
# use
building
as postfix when empty
if
postfix
is
None
:
service_name
=
f
'postgres_
{
hostname
}
'
service_name
=
f
'postgres_
{
building
}
'
else
:
service_name
=
f
'postgres_
{
postfix
}
'
...
...
@@ -266,7 +267,7 @@ def add_postgres_service(hostname, postfix=None):
template
=
get_service_template
(
Service
.
POSTGRES
.
prefix
)
# only label constraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
# replace volumes with named entries in template
template
[
'volumes'
]
=
generate_named_volumes
(
...
...
@@ -275,22 +276,22 @@ def add_postgres_service(hostname, postfix=None):
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
def
add_file_service
(
hostname
):
def
add_file_service
(
building
):
"""Generates a file manager entry and adds it to the compose file
:
hostname
: names of host that the services is added to
:
building
: names of host that the services is added to
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# service name
service_name
=
f
'
{
Service
.
FILES
.
prefix
}
_
{
hostname
}
'
service_name
=
f
'
{
Service
.
FILES
.
prefix
}
_
{
building
}
'
# template
template
=
get_service_template
(
Service
.
FILES
.
prefix
)
# add command that sets base url
template
[
'command'
]
=
f
'-b /
{
service_name
}
'
# only label contraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
template
[
'deploy'
][
'labels'
].
append
(
f
'traefik.backend=
{
service_name
}
'
)
template
[
'deploy'
][
'labels'
].
extend
(
generate_traefik_path_labels
(
service_name
,
segment
=
'main'
,
...
...
@@ -298,38 +299,38 @@ def add_file_service(hostname):
# attach volumes
volume_base
=
'/srv/'
template
[
'volumes'
]
=
get_attachable_volume_list
(
volume_base
,
hostname
)
template
[
'volumes'
]
=
get_attachable_volume_list
(
volume_base
,
building
)
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
def
add_volumerize_service
(
hostname
):
def
add_volumerize_service
(
building
):
"""Generates a volumerize backup entry and adds it to the compose file
:
hostname
: names of host that the services is added to
:
building
: names of host that the services is added to
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# service name
service_name
=
f
'
{
Service
.
BACKUP
.
prefix
}
_
{
hostname
}
'
service_name
=
f
'
{
Service
.
BACKUP
.
prefix
}
_
{
building
}
'
# template
template
=
get_service_template
(
Service
.
BACKUP
.
prefix
)
# only label contraint is building
template
[
'deploy'
][
'placement'
][
'constraints'
][
0
]
=
(
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
hostname
}
"
)
f
"
{
CONSTRAINTS
[
'building'
]
}
==
{
building
}
"
)
# attach volumes
volume_base
=
'/source/'
template
[
'volumes'
].
extend
(
get_attachable_volume_list
(
volume_base
,
hostname
))
get_attachable_volume_list
(
volume_base
,
building
))
# adjust config
config_list
=
template
[
'configs'
]
# get backup entry from configs
index
,
entry
=
next
((
i
,
c
)
for
i
,
c
in
enumerate
(
config_list
)
if
c
[
'source'
]
==
'backup_config'
)
entry
[
'source'
]
=
f
'backup_config_
{
hostname
}
'
entry
[
'source'
]
=
f
'backup_config_
{
building
}
'
template
[
'configs'
][
index
]
=
entry
add_or_update_compose_service
(
compose_path
,
service_name
,
template
)
...
...
@@ -358,8 +359,9 @@ def delete_service(service_name):
# Functions to extract information
def
get_current_services
(
placement
=
None
):
"""Gets a list of currently used services
"""Gets a list of currently used services
may be restricted to a placement
:placement: placement contraint the service shall match
:returns: list of current services
"""
# compose file
...
...
@@ -376,6 +378,26 @@ def get_current_services(placement=None):
return
service_names
def
get_current_building_constraints
():
"""Gets a list of currently used building constraints
:returns: set of current buildings
"""
# compose file
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
with
open
(
compose_path
,
'r'
)
as
compose_f
:
# load compose file
compose
=
yaml
.
load
(
compose_f
)
# generate list of buildings
building_names
=
set
()
for
(
name
,
entry
)
in
compose
[
'services'
].
items
():
building
=
get_building_of_entry
(
entry
)
if
building
:
building_names
.
add
(
building
)
return
building_names
def
get_building_of_entry
(
service_dict
):
"""Extract the configured building constraint from an yaml service entry
...
...
@@ -425,15 +447,15 @@ def get_service_volumes(service_name):
# Helper functions
def
get_attachable_volume_list
(
volume_base
,
host
):
"""Get a list of volumes from a
host
that can be attatched for file acccess
def
get_attachable_volume_list
(
volume_base
,
building
):
"""Get a list of volumes from a
building
that can be attatched for file acccess
:volume_base: Base path of volumes
:
host: host
to consider
:
building: building
to consider
:returns: list of attachable volume entries
"""
volume_list
=
[]
host_services
=
get_current_services
(
host
)
host_services
=
get_current_services
(
building
)
for
host_service
in
host_services
:
name
,
instance
=
get_service_entry_info
(
host_service
)
volume_service
=
Service
.
service_by_prefix
(
name
)
...
...
@@ -713,9 +735,10 @@ def generate_traefik_user_line(username, password):
return
line
def
generate_pb_framr_entry
(
host
,
service
):
def
generate_pb_framr_entry
(
building
,
host
,
service
):
"""Generates a single entry of the framr file
:building: building this entry is intended for
:host: host this entry is intended for
:service: entry from service enum
:returns: a dict fitting the asked entry
...
...
@@ -727,7 +750,7 @@ def generate_pb_framr_entry(host, service):
entry
[
'url'
]
=
f
'http://
{
host
}
/'
pass
else
:
entry
[
'url'
]
=
f
'/
{
service
.
prefix
}
_
{
host
}
/'
entry
[
'url'
]
=
f
'/
{
service
.
prefix
}
_
{
building
}
/'
entry
[
'icon'
]
=
service
.
icon
return
entry
...
...
@@ -852,28 +875,30 @@ def generate_traefik_file(username, password):
create_or_replace_config_file
(
EDIT_FILES
[
'traefik_users'
],
file_content
)
def
generate_volumerize_files
(
hosts
):
def
generate_volumerize_files
(
host
_entrie
s
):
"""Generates config for volumerize backups
:host
s: names of backup host
s
:host
_entries: dickt of host entrie
s
"""
compose_path
=
f
'
{
custom_path
}
/
{
COMPOSE_NAME
}
'
# create one config per host
for
h
in
hosts
:
for
h
in
host
_entrie
s
:
configs
=
[]
# Each host knows other hosts
for
t
in
hosts
:
for
t
in
host
_entrie
s
:
host_config
=
{
'description'
:
f
'Backup Server on
{
t
}
'
,
'url'
:
f
'
sftp://ohadmin@sftp_
{
t
}
:
'
f
'
//home/ohadmin/backup_data/backup/
{
h
}
'
'description'
:
f
"
'Backup Server on
{
t
[
'building_name'
]
}
"
,
'url'
:
f
"
sftp://ohadmin@sftp_
{
t
[
'building_id'
]
}
:
"
f
"
//home/ohadmin/backup_data/backup/
{
h
[
'building_id'
]
}
"
}
configs
.
append
(
host_config
)
config_file
=
f
"
{
EDIT_FILES
[
'backup_config'
]
}
_
{
h
}
.json"
config_file
=
f
"
{
EDIT_FILES
[
'backup_config'
]
}
_
{
h
[
'building_id'
]
}
.json"
create_or_replace_config_file
(
config_file
,
configs
,
json
=
True
)
add_config_entry
(
compose_path
,
f
'backup_config_
{
h
}
'
,
f
"./
{
config_file
}
"
)
compose_path
,
f
"backup_config_
{
h
[
'building_id'
]
}
"
,
f
"./
{
config_file
}
"
)
def
generate_pb_framr_file
(
frames
):
...
...
@@ -885,8 +910,8 @@ def generate_pb_framr_file(frames):
for
f
in
frames
:
building
=
{
'instance'
:
f
[
'building'
],
'entries'
:
[
generate_pb_framr_entry
(
f
[
'host'
],
s
)
'instance'
:
f
[
'building
_name
'
],
'entries'
:
[
generate_pb_framr_entry
(
f
[
'building_id'
],
f
[
'host'
],
s
)
for
s
in
f
[
'services'
]
if
s
.
frontend
]
}
configs
.
append
(
building
)
...
...
@@ -1472,20 +1497,23 @@ def init_menu(args):
generate_postgres_files
(
username
,
password
)
generate_mosquitto_file
(
username
,
password
)
generate_traefik_file
(
username
,
password
)
generate_volumerize_files
(
hosts
)
generate_filebrowser_file
(
username
,
password
)
generate_id_rsa_files
()
generate_host_key_files
(
hosts
)
frames
=
[]
for
i
,
host
in
enumerate
(
hosts
):
building
,
services
=
init_machine_menu
(
host
,
i
)
building
_id
,
building_name
,
services
=
init_machine_menu
(
host
,
i
)
frames
.
append
({
'host'
:
host
,
'building'
:
building
,
'services'
:
services
})
'building_id'
:
building_id
,
'building_name'
:
building_name
,
'services'
:
services
})
# When frames is not empty generate frame config
if
frames
:
generate_pb_framr_file
(
frames
)
generate_volumerize_files
(
frames
)
building_ids
=
[
f
[
'building_id'
]
for
f
in
frames
]
generate_host_key_files
(
building_ids
)
# print(answers)
print
(
f
"Configuration files for
{
stack_name
}
generated in
{
custom_path
}
"
)
...
...
@@ -1503,29 +1531,36 @@ def init_machine_menu(host, increment):
:host: docker-machine host
:increment: incrementing number to ensure ports are unique
:return: choosen building name and services
:return: choosen building
id,
name and services
"""
# Print divider
print
(
'----------'
)
# Prompt for services
building
=
qust
.
text
(
f
'Choose a name for building on server
{
host
}
'
,
default
=
f
'
{
host
}
'
,
style
=
st
).
ask
()
building_id
=
qust
.
text
(
f
'Choose an identifier for the building on server
{
host
}
'
'(lowercase no space)'
,
default
=
f
'
{
host
}
'
,
style
=
st
).
ask
()
building
=
qust
.
text
(
f
'Choose a display name for building on server
{
host
}
'
,
default
=
f
'
{
host
.
capitalize
()
}
'
,
style
=
st
).
ask
()
services
=
qust
.
checkbox
(
f
'What services shall
{
host
}
provide?'
,
choices
=
generate_cb_service_choices
(
checked
=
True
),
style
=
st
).
ask
()
if
Service
.
OPENHAB
in
services
:
add_openhab_service
(
host
)
add_openhab_service
(
building_id
,
host
)
if
Service
.
NODERED
in
services
:
add_nodered_service
(
host
)
add_nodered_service
(
building_id
)
if
Service
.
MQTT
in
services
:
add_mqtt_service
(
host
,
increment
)
add_mqtt_service
(
building_id
,
increment
)
if
Service
.
POSTGRES
in
services
:
add_postgres_service
(
host
)
add_postgres_service
(
building_id
)
if
Service
.
BACKUP
in
services
:
add_volumerize_service
(
host
)
add_volumerize_service
(
building_id
)
if
Service
.
FILES
in
services
:
add_file_service
(
host
)
add_file_service
(
building_id
)
if
Service
.
SFTP
in
services
:
add_sftp_service
(
host
,
increment
)
return
building
,
services
add_sftp_service
(
building_id
,
increment
)
return
building_id
,
building
,
services
# *** Exec Menu Entries ***
...
...
@@ -1779,6 +1814,8 @@ def backup_menu(args):
elif
"Restore"
in
choice
:
restore_backup_menu
()
print
(
"Restore"
)
else
:
print
(
get_current_building_constraints
())
def
execute_backup_menu
():
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment