/
move_it_client.py
151 lines (117 loc) · 4.66 KB
/
move_it_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012, 2013, 2014, 2015, 2016
#
# Author(s):
#
# Martin Raspaud <martin.raspaud@smhi.se>
# Panu Lahtinen <panu.lahtinen@fmi.fi>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Client for Trollmoves.
Moving and unpacking files
==========================
This program is comprised of two parts: this script and the configuration file.
The usage of this script is quite straightforward, just call it with the name
of the configuration file as argument.
The configuration file is comprised of sections describing the chain of
moving/unpacking.
Installation
------------
This scripts needs pyinotify, argparse, posttroll and trollsift which are available on pypi, or via pip/easy_install
(on redhat systems, install the packages python-inotify.noarch and python-argparse.noarch). Other than this,
the script doesn't need any installation, and can be run as is. If you wish though, you can install it to your
standard python path with::
python setup.py install
Configuration file
------------------
For example::
[eumetcast_hrit]
providers=tellicast_server:9090
destination=/the/directory/you/want/stuff/in /another/directory/you/want/stuff/in
login=username:greatPassword
topic=/1b/hrit/zds
publish_port=0
* 'provider' is the address of the server receiving the data you want.
* 'destinations' is the list of places to put the unpacked data in.
* 'topic' gives the topic to listen to on the provider side.
* 'publish_port' defines on which port to publish incomming files. 0 means random port.
Logging
-------
The logging is done on stdout per default. It is however possible to specify a file to log to (instead of stdout)
with the -l or --log option::
move_it_client --log /path/to/mylogfile.log myconfig.ini
"""
# TODO: implement ping and server selection
import logging
import logging.handlers
import argparse
import signal
import time
from posttroll.publisher import NoisyPublisher
from trollmoves.move_it_base import MoveItBase
from trollmoves.client import StatCollector
LOGGER = logging.getLogger("move_it_client")
LOG_FORMAT = "[%(asctime)s %(levelname)-8s %(name)s] %(message)s"
class MoveItClient(MoveItBase):
"""Trollmoves client class."""
def __init__(self, cmd_args):
"""Initialize client."""
super(MoveItClient, self).__init__(cmd_args, "client")
self._np = NoisyPublisher("move_it_client")
self.sync_publisher = self._np.start()
self.setup_watchers(cmd_args)
def run(self):
"""Start the transfer chains."""
signal.signal(signal.SIGTERM, self.chains_stop)
signal.signal(signal.SIGHUP, self.signal_reload_cfg_file)
self.notifier.start()
self.running = True
while self.running:
time.sleep(1)
self.sync_publisher.heartbeat(30)
for chain_name in self.chains:
if not self.chains[chain_name].is_alive():
self.chains[chain_name] = self.chains[chain_name].restart()
def parse_args():
"""Parse commandline arguments."""
parser = argparse.ArgumentParser()
parser.add_argument("config_file",
help="The configuration file to run on.")
parser.add_argument("-l", "--log",
help="The file to log to. stdout otherwise.")
parser.add_argument("-s", "--stats",
help="Save stats to this file")
parser.add_argument("-v", "--verbose", default=False, action="store_true",
help="Toggle verbose logging")
return parser.parse_args()
def main():
"""Run the Trollmoves Client."""
cmd_args = parse_args()
client = MoveItClient(cmd_args)
try:
if cmd_args.stats:
stat = StatCollector(cmd_args.stats)
client.reload_cfg_file(cmd_args.config_file, callback=stat.collect)
else:
client.reload_cfg_file(cmd_args.config_file)
client.run()
except KeyboardInterrupt:
LOGGER.debug("Interrupting")
finally:
if client.running:
client.chains_stop()
if __name__ == '__main__':
main()