def update(silent=False, **kwargs): """ Update Contiki-OS and RPL Attacks Framework. """ for folder, repository in zip([CONTIKI_FOLDER, FRAMEWORK_FOLDER], ["Contiki-OS", "RPL Attacks Framework"]): with hide(*HIDDEN_ALL): with lcd(folder): uptodate = "branch is up-to-date" in local( 'git checkout master', capture=True).strip().split('\n')[-1] if not uptodate: logger.warn( "You are about to loose any custom change made to {} ;" .format(repository)) if silent or std_input( "Proceed anyway ? (yes|no) [default: no] ", 'yellow') == 'yes': local('git submodule update --init') local('git fetch --all') local('git reset --hard origin/master') local('git pull') logger.debug(" > {} {}".format(repository, ["updated", "already up-to-date"][uptodate])) if repository == "Contiki-OS" and not uptodate: setup(silent=True)
def setup(silent=False, **kwargs): """ Setup the framework. """ recompile = False # install Cooja modifications if not check_cooja(COOJA_FOLDER): logger.debug(" > Installing Cooja add-ons...") # modify Cooja.java and adapt build.xml and ~/.cooja.user.properties modify_cooja(COOJA_FOLDER) update_cooja_build(COOJA_FOLDER) update_cooja_user_properties() recompile = True # install VisualizerScreenshot plugin in Cooja visualizer = join(COOJA_FOLDER, 'apps', 'visualizer_screenshot') if not exists(visualizer): logger.debug(" > Installing VisualizerScreenshot Cooja plugin...") copy_folder('src/visualizer_screenshot', visualizer) recompile = True # recompile Cooja for making the changes take effect if recompile: with lcd(COOJA_FOLDER): logger.debug(" > Recompiling Cooja...") with settings(warn_only=True): local("ant clean") local("ant jar") else: logger.debug(" > Cooja is up-to-date") # install imagemagick with hide(*HIDDEN_ALL): imagemagick_apt_output = local('apt-cache policy imagemagick', capture=True) if 'Unable to locate package' in imagemagick_apt_output: logger.debug(" > Installing imagemagick package...") sudo("apt-get install imagemagick -y &") else: logger.debug(" > Imagemagick is installed") # install msp430 (GCC) upgrade with hide(*HIDDEN_ALL): msp430_version_output = local('msp430-gcc --version', capture=True) if 'msp430-gcc (GCC) 4.7.0 20120322' not in msp430_version_output: txt = "In order to extend msp430x memory support, it is necessary to upgrade msp430-gcc.\n" \ "Would you like to upgrade it now ? (yes|no) [default: no] " answer = std_input(txt, 'yellow') if answer == "yes": logger.debug(" > Upgrading msp430-gcc from version 4.6.3 to 4.7.0...") logger.warning("If you encounter problems with this upgrade, please refer to:\n" "https://github.com/contiki-os/contiki/wiki/MSP430X") with lcd('src/'): logger.warning(" > Upgrade now starts, this may take up to 30 minutes...") sudo('./upgrade-msp430.sh') sudo('rm -r tmp/') local('export PATH=/usr/local/msp430/bin:$PATH') register_new_path_in_profile() else: logger.warning("Upgrade of library msp430-gcc aborted") logger.warning("You may experience problems of mote memory size at compilation") else: logger.debug(" > Library msp430-gcc is up-to-date (version 4.7.0)")
def wrapper(*args, **kwargs): """ This is the wrapper for the 'command' decorator, handling the following execution flow : - It first determines if this command is used with a console - In case of console, it performs a lexical analysis - Anyway, it performs a signature checking - It handles 'expand' parameter - It then handles 'exists' and 'not_exists' (in this order) - It finally selects the right behavior using 'behavior' """ # specific argument existence check through the 'not_exists' and 'exists' attributes def get_ask(): if attrs['on_boolean'] in kwargs.keys(): return kwargs[attrs['on_boolean']] try: param = sig.parameters[attrs['on_boolean']] try: return args[list(sig.parameters.values()).index(param)] except ( IndexError, ValueError ): # occurs if 'ask' was not specified in the arguments ; # in this case, take the default value from the signature return param.default except KeyError: # occurs if no 'ask' parameter is in the signature return False # log message formatting with specified arguments from 'args' or 'kwargs' def log_msg(lvl, msg): if kwargs.get('silent'): return if isinstance(msg, tuple): values = [] for a in msg[1:]: try: values.append(args[list( sig.parameters.keys()).index(a)]) except KeyError: value = kwargs.get(a) if value is not None: values.append(value) getattr(logger, lvl)(msg[0].format(*values)) else: getattr(logger, lvl)(msg) console = args[0] if len(args) > 0 and isinstance(args[0], Cmd) else None if console is not None: kwargs['console'] = console # lexical analysis if len(args) > 1 and console is not None: line = args[1] kwargs_tmp = {k: v for k, v in kwargs.items()} args, kwargs = lexer.analyze(line) if args is None and kwargs is None: print( console.badcmd_msg.format( "Invalid", '{} {}'.format(f.__name__, line))) return kwargs.update(kwargs_tmp) # bad signature check sig = signature(f) args = () if args == ( '', ) else args # occurs in case of Cmd ; an empty 'line' can be passed if a # command is called without any argument # - first, exclude variable arguments and keyword-arguments no_var_args = [ p for p in list(sig.parameters.values()) if not str(p).startswith('*') ] # - then, retrieve arguments without default values no_def_args = [p for p in no_var_args if p.default is not p.empty] # - now, if less input arguments are provided than the number of arguments without default value, # display an error if len(args) < len(no_var_args) - len(no_def_args): logger.critical("Bad input arguments !") logger.info( "This command has the following signature: {}{}".format( f.__name__, str(sig).replace(', **kwargs', ''))) logger.info( "Please check the documentation for more information.") return # expand a specified argument to a path if hasattr(f, 'expand'): arg, attrs = f.expand arg_idx = list(sig.parameters.keys()).index(arg) try: expanded = expanduser(join(attrs['into'], args[arg_idx])) except IndexError: # occurs when arg_idx out of range of args, meaning that the argument to be # expanded was not provided return # if an extension was provided and the file path does not end with it, just append it if attrs.get('ext') and not expanded.endswith("." + attrs['ext']): expanded += "." + attrs['ext'] # the expanded argument must not be saved to a new argument name, just replace its old value if attrs.get('new_arg') is None: args = tuple([ a if i != arg_idx else expanded for i, a in enumerate(args) ]) # otherwise, create the new argument if the name is not used yet elif attrs['new_arg'] not in list(sig.parameters.keys()): kwargs[attrs['new_arg']] = expanded if attrs.get( 'apply') is None else attrs['apply'](expanded) # when no 'path' kwarg is set, it must be added based on the direcotory name of the expanded arg if 'path' not in kwargs.keys(): kwargs['path'] = dirname(expanded) # if next commands require sudo, prompt now for privilege elevation if getattr(f, 'requires_sudo', False): system('sudo ls > /dev/null') # check for existence (or not) and ask for a confirmation to continue if required for fattr in ['exists', 'not_exists']: if hasattr(f, fattr): arg, attrs = getattr(f, fattr) try: arg_val = args[list(sig.parameters.keys()).index(arg)] except ValueError: arg_val = kwargs[arg] if (fattr == 'exists' and exists(arg_val)) or (fattr == 'not_exists' and not exists(arg_val)): if 'loglvl' in attrs.keys() and 'msg' in attrs.keys(): log_msg(attrs['loglvl'], attrs['msg']) if attrs.get('loglvl') in ('error', 'critical') or \ ((attrs.get('loglvl') in ('warning', 'info') or fattr == 'exists') and get_ask() and attrs.get('confirm') is not None and not std_input(attrs['confirm'], 'yellow') == 'yes'): return # run the command and catch exception if any if console is not None and len(args) > 0: console.clean_tasks() pending_tasks = { i['name']: str(o) for o, i in console.tasklist.items() if i['status'] == 'PENDING' } if args[0] not in pending_tasks.keys(): if hasattr(f, 'start_msg'): log_msg('info', f.start_msg) kwargs['task'] = f.__name__.lstrip('_') f.behavior( console, f.__base__ if f.behavior is MultiprocessedCommand else f, args[0], kwargs.get('path')).run(*args, **kwargs) else: logger.warning( "A task is still pending on this experiment ({})". format(pending_tasks[args[0]])) else: if hasattr(f, 'start_msg'): log_msg('info', f.start_msg) f(*args, **kwargs)
def wrapper(*args, **kwargs): """ This is the wrapper for the 'command' decorator, handling the following execution flow : - It first determines if this command is used with a console - In case of console, it performs a lexical analysis - Anyway, it performs a signature checking - It handles 'expand' parameter - It then handles 'exists' and 'not_exists' (in this order) - It finally selects the right behavior using 'behavior' """ # specific argument existence check through the 'not_exists' and 'exists' attributes def get_ask(): if attrs['on_boolean'] in kwargs.keys(): return kwargs[attrs['on_boolean']] try: param = sig.parameters[attrs['on_boolean']] try: return args[list(sig.parameters.values()).index(param)] except (IndexError, ValueError): # occurs if 'ask' was not specified in the arguments ; # in this case, take the default value from the signature return param.default except KeyError: # occurs if no 'ask' parameter is in the signature return False # log message formatting with specified arguments from 'args' or 'kwargs' def log_msg(lvl, msg): if kwargs.get('silent'): return if isinstance(msg, tuple): values = [] for a in msg[1:]: try: values.append(args[list(sig.parameters.keys()).index(a)]) except KeyError: value = kwargs.get(a) if value is not None: values.append(value) getattr(logger, lvl)(msg[0].format(*values)) else: getattr(logger, lvl)(msg) console = args[0] if len(args) > 0 and isinstance(args[0], Cmd) else None if console is not None: kwargs['console'] = console # lexical analysis if len(args) > 1 and console is not None: line = args[1] kwargs_tmp = {k: v for k, v in kwargs.items()} args, kwargs = lexer.analyze(line) if args is None and kwargs is None: print(console.badcmd_msg.format("Invalid", '{} {}'.format(f.__name__, line))) return kwargs.update(kwargs_tmp) # bad signature check sig = signature(f) args = () if args == ('',) else args # occurs in case of Cmd ; an empty 'line' can be passed if a # command is called without any argument # - first, exclude variable arguments and keyword-arguments no_var_args = [p for p in list(sig.parameters.values()) if not str(p).startswith('*')] # - then, retrieve arguments without default values no_def_args = [p for p in no_var_args if p.default is not p.empty] # - now, if less input arguments are provided than the number of arguments without default value, # display an error if len(args) < len(no_var_args) - len(no_def_args): logger.critical("Bad input arguments !") logger.info("This command has the following signature: {}{}" .format(f.__name__, str(sig).replace(', **kwargs', ''))) logger.info("Please check the documentation for more information.") return # expand a specified argument to a path if hasattr(f, 'expand'): arg, attrs = f.expand arg_idx = list(sig.parameters.keys()).index(arg) try: expanded = expanduser(join(attrs['into'], args[arg_idx])) except IndexError: # occurs when arg_idx out of range of args, meaning that the argument to be # expanded was not provided return if attrs.get('ext') and not expanded.endswith("." + attrs['ext']): expanded += "." + attrs['ext'] if attrs.get('new_arg') is None: args = tuple([a if i != arg_idx else expanded for i, a in enumerate(args)]) elif attrs['new_arg'] not in list(sig.parameters.keys()): kwargs[attrs['new_arg']] = expanded if attrs.get('apply') is None else attrs['apply'](expanded) # check for existence (or not) and ask for a confirmation to continue if required for fattr in ['exists', 'not_exists']: if hasattr(f, fattr): arg, attrs = getattr(f, fattr) try: arg_val = args[list(sig.parameters.keys()).index(arg)] except ValueError: arg_val = kwargs[arg] if (fattr == 'exists' and exists(arg_val)) or (fattr == 'not_exists' and not exists(arg_val)): if 'loglvl' in attrs.keys() and 'msg' in attrs.keys(): log_msg(attrs['loglvl'], attrs['msg']) if attrs.get('loglvl') in ('error', 'critical') or \ ((attrs.get('loglvl') in ('warning', 'info') or fattr == 'exists') and get_ask() and attrs.get('confirm') is not None and not std_input(attrs['confirm'], 'yellow') == 'yes'): return # run the command and catch exception if any if console is not None and len(args) > 0: console.clean_tasks() pending_tasks = {i['name']: str(o) for o, i in console.tasklist.items() if i['status'] == 'PENDING'} if args[0] not in pending_tasks.keys(): if hasattr(f, 'start_msg'): log_msg('info', f.start_msg) f.behavior(console, f.__base__ if f.behavior is MultiprocessedCommand else f, args[0]) \ .run(*args, **kwargs) else: logger.warning("A task is still pending on this experiment ({})".format(pending_tasks[args[0]])) else: if hasattr(f, 'start_msg'): log_msg('info', f.start_msg) f(*args, **kwargs)
def setup(silent=False, **kwargs): """ Setup the framework. """ recompile = False # adapt IPv6 debug mode modify_ipv6_debug(CONTIKI_FOLDER) # install Cooja modifications if not check_cooja(COOJA_FOLDER): logger.debug(" > Installing Cooja add-ons...") # modify Cooja.java and adapt build.xml and ~/.cooja.user.properties modify_cooja(COOJA_FOLDER) update_cooja_build(COOJA_FOLDER) update_cooja_user_properties() recompile = True # install VisualizerScreenshot plugin in Cooja visualizer = join(COOJA_FOLDER, 'apps', 'visualizer_screenshot') if not exists(visualizer): logger.debug(" > Installing VisualizerScreenshot Cooja plugin...") copy_folder('src/visualizer_screenshot', visualizer) recompile = True # recompile Cooja for making the changes take effect if recompile: with lcd(CONTIKI_FOLDER): local('git submodule update --init') with lcd(COOJA_FOLDER): logger.debug(" > Recompiling Cooja...") with hide(*HIDDEN_ALL): for cmd in ["clean", "jar"]: output = local("ant {}".format(cmd), capture=True) info, error = False, False for line in output.split('\n'): if line.strip() == "": info, error = False, False elif line.startswith("BUILD"): info, error = "SUCCESSFUL" in line, "FAILED" in line if info or error: getattr( logger, "debug" if info else "error" if error else "warn")(line) else: logger.debug(" > Cooja is up-to-date") # install imagemagick with hide(*HIDDEN_ALL): imagemagick_apt_output = local('apt-cache policy imagemagick', capture=True) if 'Unable to locate package' in imagemagick_apt_output: logger.debug(" > Installing imagemagick package...") local('sudo apt-get install imagemagick -y &') else: logger.debug(" > Imagemagick is installed") # install msp430 (GCC) upgrade with hide(*HIDDEN_ALL): msp430_version_output = local('msp430-gcc --version', capture=True) if 'msp430-gcc (GCC) 4.7.0 20120322' not in msp430_version_output: txt = "In order to extend msp430x memory support, it is necessary to upgrade msp430-gcc.\n" \ "Would you like to upgrade it now ? (yes|no) [default: no] " if silent or std_input(txt, 'yellow') == "yes": logger.debug( " > Upgrading msp430-gcc from version 4.6.3 to 4.7.0...") logger.warning( "If you encounter problems with this upgrade, please refer to:\n" "https://github.com/contiki-os/contiki/wiki/MSP430X") with lcd('src/'): logger.warning( " > Upgrade now starts, this may take up to 30 minutes...") local('sudo ./upgrade-msp430.sh') local('sudo rm -r tmp/') local('export PATH=/usr/local/msp430/bin:$PATH') register_new_path_in_profile() else: logger.warning("Upgrade of library msp430-gcc aborted") logger.warning( "You may experience problems of mote memory size at compilation" ) else: logger.debug(" > Library msp430-gcc is up-to-date (version 4.7.0)") # create a new desktop shortcut for the framework desktop = expanduser('~/Desktop') shortcut = join(desktop, 'rpl-attacks-framework.desktop') if not exists(desktop): makedirs(desktop) if not exists(shortcut): with hide(*HIDDEN_ALL): local('sudo cp {} /usr/share/icons/hicolor/scalable/apps/'.format( join(FRAMEWORK_FOLDER, 'src/rpla-icon.svg'))) local('sudo gtk-update-icon-cache /usr/share/icons/hicolor') with open(shortcut, 'w+') as f: f.write(SHORTCUT.format(path=FRAMEWORK_FOLDER)) chmod(shortcut, int('775', 8)) logger.debug(" > Desktop shortcut created") else: logger.debug(" > Desktop shortcut already exists")
def setup(silent=False, **kwargs): """ Setup the framework. """ recompile = False # install Cooja modifications if not check_cooja(COOJA_FOLDER): logger.debug(" > Installing Cooja add-ons...") # modify Cooja.java and adapt build.xml and ~/.cooja.user.properties modify_cooja(COOJA_FOLDER) update_cooja_build(COOJA_FOLDER) update_cooja_user_properties() recompile = True # install VisualizerScreenshot plugin in Cooja visualizer = join(COOJA_FOLDER, 'apps', 'visualizer_screenshot') if not exists(visualizer): logger.debug(" > Installing VisualizerScreenshot Cooja plugin...") copy_folder('src/visualizer_screenshot', visualizer) recompile = True # recompile Cooja for making the changes take effect if recompile: with lcd(COOJA_FOLDER): logger.debug(" > Recompiling Cooja...") with settings(warn_only=True): local("ant clean") local("ant jar") else: logger.debug(" > Cooja is up-to-date") # install imagemagick with hide(*HIDDEN_ALL): imagemagick_apt_output = local('apt-cache policy imagemagick', capture=True) if 'Unable to locate package' in imagemagick_apt_output: logger.debug(" > Installing imagemagick package...") sudo("apt-get install imagemagick -y &") else: logger.debug(" > Imagemagick is installed") # install msp430 (GCC) upgrade with hide(*HIDDEN_ALL): msp430_version_output = local('msp430-gcc --version', capture=True) if 'msp430-gcc (GCC) 4.7.0 20120322' not in msp430_version_output: txt = "In order to extend msp430x memory support, it is necessary to upgrade msp430-gcc.\n" \ "Would you like to upgrade it now ? (yes|no) [default: no] " answer = std_input(txt, 'yellow') if answer == "yes": logger.debug( " > Upgrading msp430-gcc from version 4.6.3 to 4.7.0...") logger.warning( "If you encounter problems with this upgrade, please refer to:\n" "https://github.com/contiki-os/contiki/wiki/MSP430X") with lcd('src/'): logger.warning( " > Upgrade now starts, this may take up to 30 minutes...") sudo('./upgrade-msp430.sh') sudo('rm -r tmp/') local('export PATH=/usr/local/msp430/bin:$PATH') register_new_path_in_profile() else: logger.warning("Upgrade of library msp430-gcc aborted") logger.warning( "You may experience problems of mote memory size at compilation" ) else: logger.debug(" > Library msp430-gcc is up-to-date (version 4.7.0)")