def do_register(rt, name, fqdn): global n global s log.info("Registering Ferry Node") n = rt.nodes.where({"name": name}) try: n = next(n) except StopIteration: n = Node() n.name = name rt.insert(n, commit=True) rt.flush() s = rt.services.where({"runningOn": n}) try: s = next(s) except (StopIteration, AttributeError): s = DLNFerry() s.runningOn = n s.serviceType = "datalogistics:wdln:base" s.name = name s.accessPoint = "ibp://{}:6714".format(fqdn) s.unis_url = "http://{}:{}".format(fqdn, LOCAL_UNIS_PORT) s.status = "READY" s.ttl = 600 # 10m rt.insert(s, commit=True) rt.flush()
def main(): parser = argparse.ArgumentParser(description="DLN Base Station Agent") parser.add_argument('-H', '--host', type=str, default=UNIS_URL, help='UNIS instance for registration and metadata') parser.add_argument('-n', '--name', type=str, default=None, help='Set base node name (ignore system hostname)') parser.add_argument('-v', '--verbose', action='store_true', help='Produce verbose output from the script') parser.add_argument('-q', '--quiet', action='store_true', help='Quiet mode, no logging output') args = parser.parse_args() # configure logging level level = logging.DEBUG if args.verbose else logging.INFO level = logging.CRITICAL if args.quiet else level log.setLevel(level) name = socket.gethostname() fqdn = socket.getfqdn() log.info("Base Station \"{}\" reporting for duty".format(name)) if args.name: name = args.name log.info("Setting base name to \"{}\"".format(name)) # use fqdn to determine local endpoints LOCAL_DEPOT = {"ibp://{}:6714".format(fqdn): {"enabled": True}} # allow an alternative UNIS instance (non-ferry) in local mode if (args.host != UNIS_URL): LOCAL_UNIS = args.host else: LOCAL_UNIS = "http://{}:{}".format(fqdn, LOCAL_UNIS_PORT) # get our initial UNIS-RT and libdlt sessions rt = init_runtime(LOCAL_UNIS) # Start the registration loop # returns handles to the node and service objects register(rt, name, fqdn) # start base-ferry sync BaseFerrySync(rt, name) run_base(rt)
def query(self): if not self.sock: if self.gps_box: min_x, min_y, max_x, max_y = self.gps_box.bounds pt = Point([ random.uniform(min_x, max_x), random.uniform(min_y, max_y) ]) log.info('Location identified as %f,%f' % (pt.x, pt.y)) return (pt.x, pt.y) return (GPS_DEFAULT[0], GPS_DEFAULT[1]) lack_lat = True lack_long = True lack_alt = True for new_data in self.sock: latitude = 'n/a' longitude = 'n/a' altitude = 'n/a' if new_data: self.stream.unpack(new_data) self.read_count = self.read_count + 1 latitude = self.stream.TPV['lat'] longitude = self.stream.TPV['lon'] altitude = self.stream.TPV['alt'] if lack_lat and latitude != 'n/a' and type(latitude) == float: latitude = float(latitude) lack_lat = False if lack_long and longitude != 'n/a' and type(longitude) == float: longitude = float(longitude) lack_long = False if lack_alt and altitude != 'n/a' and type(altitude) == float: altitude = float(altitude) lack_alt = False if not lack_lat and not lack_long: # optional: and not lack_alt log.info('Location identified as %f,%f' % (latitude, longitude)) return (latitude, longitude) if self.read_count > GPS_DEV_READ_LEN: break # only return default if socket is dead # otherwise location will jump if GPS signal is lost return (None, None) return (None, None)
def on_any_event(self, event): if event.is_directory: return None if event.event_type == 'moved': if not os.path.basename(event.src_path).startswith("."): return fname = os.path.basename(event.src_path) dname = os.path.dirname(event.src_path) npath = os.path.join(dname, fname[1:]) dpath = os.path.join(DOWNLOAD_DIR, fname[1:]) if os.path.getsize(npath) > 0: log.info("Handling new file upload: %s" % npath) self._do_upload(npath) os.rename(npath, dpath)
def run_remote(sess, rt): i = 0 while True: with slock: (i % 5) or log.info("[{}]Waiting for some remote action...".format( s.status)) if s.status == "UPDATE": dl_list = s.new_exnodes log.info("Caught UPDATE status with {} new exnodes".format( len(dl_list))) local_download(sess, dl_list) time.sleep(1) s.status = "READY" rt.flush() i += 1 time.sleep(1)
def local_download(sess, exnodes): for f in exnodes: if not len(f.extents): continue fpath = os.path.join(DOWNLOAD_DIR, f.name) if os.path.exists(fpath) and os.path.getsize(fpath) == f.size: log.debug("File exists: {}, skipping!".format(f.name)) continue log.info("Downloading: {} ({} bytes)".format(f.name, f.size)) try: result = sess.download(f.selfRef, fpath) res, diff, dsize = result.exnode, result.time, result.t_size except Exception as e: log.error("Could not download file: {}".format(e)) continue if dsize != res.size: log.warn("WARNING: {}: transferred {} of {} bytes \ (check depot file)".format(res.name, dsize, res.size)) else: log.info("{0} ({1} {2:.2f} MB/s) {3}".format( res.name, res.size, res.size / 1e6 / diff, res.selfRef))
def __init__(self): self.sock = gps3.GPSDSocket() self.stream = gps3.DataStream() # GPS3 throws no exceptions and returns no status, # so we have to capture stdout and do string matching, sigh f = io.StringIO() with redirect_stderr(f): self.sock.connect() if "Connection refused" in f.getvalue(): log.warn( "Could not connect to GPSD socket, continuing with GPS_BOX") self.sock = None else: log.info("Connected to GPSD socket") self.sock.watch() # we will use the GPS_BOX setting to determine if # queries will return locations within a specified range if len(GPS_BOX) == 4: self.gps_box = box(GPS_BOX[0], GPS_BOX[1], GPS_BOX[2], GPS_BOX[3]) log.info("Created GPS box") else: log.warn("Invalid GPS_BOX size, using GPS_DEFAULT")
def run_base(rt): i = 0 while True: (i % 5) or log.info("Waiting for something to do...") i += 1 time.sleep(1)
def update_ibp_server(self, istr): cmdstr = "sudo sed -i 's/^interfaces=.*$/interfaces=" + istr + "/g' " + self.cfg subprocess.run(shlex.split(cmdstr)) cmdstr = "sudo /etc/init.d/ibp-server restart" subprocess.run(shlex.split(cmdstr), stdout=subprocess.DEVNULL) log.info("Detected interface change, restarted ibp-server")
def main(): global DOWNLOAD_DIR global sess parser = argparse.ArgumentParser(description="DLN Mobile Ferry Agent") parser.add_argument('-H', '--host', type=str, default=UNIS_URL, help='UNIS instance for registration and metadata') parser.add_argument('-n', '--name', type=str, default=None, help='Set ferry node name (ignore system hostname)') parser.add_argument('-d', '--download', type=str, default=DOWNLOAD_DIR, help='Set local download directory') parser.add_argument('-u', '--upload', type=str, default=UPLOAD_DIR, help='Set local upload directory') parser.add_argument('-l', '--local', action='store_true', help='Run using only local UNIS instance (on-ferry)') parser.add_argument( '-i', '--ibp', action='store_true', help='Update IBP config to reflect interface changes on system') parser.add_argument('-v', '--verbose', action='store_true', help='Produce verbose output from the script') parser.add_argument('-q', '--quiet', action='store_true', help='Quiet mode, no logging output') args = parser.parse_args() # configure logging level level = logging.DEBUG if args.verbose else logging.INFO level = logging.CRITICAL if args.quiet else level log.setLevel(level) name = socket.gethostname() fqdn = socket.getfqdn() log.info("Ferry \"{}\" reporting for duty".format(name)) if args.name: name = args.name log.info("Setting ferry name to \"{}\"".format(name)) DOWNLOAD_DIR = args.download try: os.makedirs(DOWNLOAD_DIR) except FileExistsError: pass except OSError as exp: raise exp # use fqdn to determine local endpoints LOCAL_DEPOT = {"ibp://{}:6714".format(fqdn): {"enabled": True}} # allow an alternative UNIS instance (non-ferry) in local mode if (args.local and args.host != UNIS_URL): LOCAL_UNIS = args.host else: LOCAL_UNIS = "http://{}:{}".format(fqdn, LOCAL_UNIS_PORT) # get our initial UNIS-RT and libdlt sessions rt = init_runtime(args.host, LOCAL_UNIS, args.local) sess = libdlt.Session(rt, bs="5m", depots=LOCAL_DEPOT, threads=1) # Start the registration loop register(rt, name, fqdn) # Start the iface watcher for IBP config if args.ibp: IBPWatcher() # Start the upload dir watcher #UploadWatcher(s, LOCAL_UNIS) # Start uploader thread run_uploader(args.upload) # run our main loop if args.local: run_local(sess, rt) else: run_remote(sess, rt)
def run_local(sess, rt): i = 0 while True: (i % 5) or log.info("Waiting for some local action...") i += 1 time.sleep(1)