def setConfig(chuteName, sections, filepath): cfgFile = uci.UCIConfig(filepath) # Set the name in the comment field. for config, options in sections: config['comment'] = chuteName oldSections = cfgFile.getChuteConfigs(chuteName) if not uci.chuteConfigsMatch(oldSections, sections): cfgFile.delConfigs(oldSections) cfgFile.addConfigs(sections) cfgFile.save(internalid=chuteName)
def setConfig(chute, old, cacheKeys, filepath): """ Helper function used to modify config file of each various setting in /etc/config/ Returns: True: if it modified a file False: if it did NOT cause any modifications Raises exception if an error occurs. """ # First pull out all the cache keys from the @new chute newconfigs = [] # chute may be None if a chute installation failed and we are backing out. # In that case, newconfigs should be an empty list, meaning there should be # nothing left of the chute in the configuration file after we are done. if chute is not None: for c in cacheKeys: t = chute.getCache(c) if(t): newconfigs += t # Get the chute name. At least one of chute or old should be valid. chute_name = chute.name if chute is not None else old.name # Add comment to each config so we can differentiate between different # chute specific configs. for e in newconfigs: c, o = e c['comment'] = chute_name # Get the old configs from the file for this chute. cfgFile = uci.UCIConfig(filepath) # Get all the configs that existed in the old version. Note we are getting # the old configs from the etc/config/ file instead of the chute object. # This is to improve reliability - sometimes the file isn't changed it # should be because we have reset the board, messed with chutes, etc. and # the new/old chuteobjects are identical. oldconfigs = cfgFile.getChuteConfigs(chute_name) if (uci.chuteConfigsMatch(oldconfigs, newconfigs)): # configs match, skipping reloading # Save a backup in case we need to restore. cfgFile.backup(backupToken="paradrop") return False else: # We need to make changes so delete old configs, load new configs # configs don't match, changing chutes and reloading cfgFile.delConfigs(oldconfigs) cfgFile.addConfigs(newconfigs) cfgFile.save(backupToken="paradrop", internalid=chute_name) return True
def setConfig(update, cacheKeys, filepath): """ Helper function used to modify config file of each various setting in /etc/config/ Returns: True: if it modified a file False: if it did NOT cause any modifications Raises exception if an error occurs. """ # First pull out all the cache keys from the @new chute newconfigs = [] # chute may be None if a chute installation failed and we are backing out. # In that case, newconfigs should be an empty list, meaning there should be # nothing left of the chute in the configuration file after we are done. if update.new is not None: for c in cacheKeys: t = update.cache_get(c) if t is not None: newconfigs.extend(t) # Get the chute name. At least one of chute or old should be valid. chute_name = update.new.name if update.new is not None else update.old.name # Add comment to each config so we can differentiate between different # chute specific configs. for c, o in newconfigs: c['comment'] = chute_name # Get the old configs from the file for this chute. cfgFile = uci.UCIConfig(filepath) # Get all the configs that existed in the old version. Note we are getting # the old configs from the etc/config/ file instead of the chute object. # This is to improve reliability - sometimes the file isn't changed it # should be because we have reset the board, messed with chutes, etc. and # the new/old chuteobjects are identical. oldconfigs = cfgFile.getChuteConfigs(chute_name) if (uci.chuteConfigsMatch(oldconfigs, newconfigs)): # configs match, skipping reloading # Save a backup in case we need to restore. cfgFile.backup(backupToken="paradrop") return False else: # We need to make changes so delete old configs, load new configs # configs don't match, changing chutes and reloading cfgFile.delConfigs(oldconfigs) cfgFile.addConfigs(newconfigs) cfgFile.save(backupToken="paradrop", internalid=chute_name) return True
def setConfig(chuteName, sections, filepath): cfgFile = uci.UCIConfig(filepath) # Set the name in the comment field. for config, options in sections: config['comment'] = chuteName oldSections = cfgFile.getChuteConfigs(chuteName) if not uci.chuteConfigsMatch(oldSections, sections): cfgFile.delConfigs(oldSections) cfgFile.addConfigs(sections) cfgFile.save(backupToken="paradrop", internalid=chuteName) else: # Save a backup of the file even though there were no changes. cfgFile.backup(backupToken="paradrop")
def setConfig(chute, old, cacheKeys, filepath): """ Helper function used to modify config file of each various setting in /etc/config/ Returns: True: if it modified a file False: if it did NOT cause any modifications Raises exception if an error occurs. """ # First pull out all the cache keys from the @new chute newconfigs = [] for c in cacheKeys: t = chute.getCache(c) if (t): newconfigs += t if (len(newconfigs) == 0): out.info('no settings to add %r\n' % (chute)) # We are no longer returning because we need to remove the old configs if necessary # return False # add comment to each config so we can differentiate between different chute specific configs for e in newconfigs: c, o = e c['comment'] = chute.name # Get the old configs from the file for this chuteid # Find the config file cfgFile = uci.UCIConfig(filepath) # Get all the configs that existed in the old version # Note we are getting the old configs from the etc/config/ file instead of the chute object # This is to improve reliability - sometimes the file isn't changed it should be # because we have reset the board, messed with chutes, etc. and the new/old chuteobjects are identical oldconfigs = cfgFile.getChuteConfigs(chute.name) if (uci.chuteConfigsMatch(oldconfigs, newconfigs)): # configs match, skipping reloading # Save a backup in case we need to restore. cfgFile.backup(backupToken="paradrop") return False else: # We need to make changes so delete old configs, load new configs # configs don't match, changing chutes and reloading cfgFile.delConfigs(oldconfigs) cfgFile.addConfigs(newconfigs) cfgFile.save(backupToken="paradrop", internalid=chute.name) return True
def setConfig(chute, old, cacheKeys, filepath): """ Helper function used to modify config file of each various setting in /etc/config/ Returns: True: if it modified a file False: if it did NOT cause any modifications Raises exception if an error occurs. """ # First pull out all the cache keys from the @new chute newconfigs = [] for c in cacheKeys: t = chute.getCache(c) if(t): newconfigs += t if(len(newconfigs) == 0): out.info('no settings to add %r\n' % (chute)) # We are no longer returning because we need to remove the old configs if necessary # return False # add comment to each config so we can differentiate between different chute specific configs for e in newconfigs: c, o = e c['comment'] = chute.name # Get the old configs from the file for this chuteid # Find the config file cfgFile = uci.UCIConfig(filepath) # Get all the configs that existed in the old version # Note we are getting the old configs from the etc/config/ file instead of the chute object # This is to improve reliability - sometimes the file isn't changed it should be # because we have reset the board, messed with chutes, etc. and the new/old chuteobjects are identical oldconfigs = cfgFile.getChuteConfigs(chute.name) if (uci.chuteConfigsMatch(oldconfigs, newconfigs)): # configs match, skipping reloading return False else: # We need to make changes so delete old configs, load new configs # configs don't match, changing chutes and reloading cfgFile.delConfigs(oldconfigs) cfgFile.addConfigs(newconfigs) cfgFile.save(backupToken="paradrop", internalid=chute.name) return True
def test_uci(): """ Test UCI file utility module """ from paradrop.lib.utils import uci from paradrop.lib import settings # Test functions for finding path to UCI files settings.UCI_CONFIG_DIR = "/tmp/config.d" assert uci.getSystemConfigDir() == "/tmp/config.d" assert uci.getSystemPath("network") == "/tmp/config.d/network" # Test stringify function assert uci.stringify("a") == "a" blob = {"a": "b"} assert uci.stringify(blob) == blob blob = {"a": {"b": "c"}} assert uci.stringify(blob) == blob blob = {"a": ["b", "c"]} assert uci.stringify(blob) == blob blob = {"a": 5} strblob = {"a": "5"} assert uci.stringify(blob) == strblob assert uci.isMatch(blob, strblob) # Write a realistic configuration and load with uci module path = writeTempFile(NETWORK_WAN_CONFIG) config = uci.UCIConfig(path) # Test if it found the config section that we know should be there empty = {} assert config.getConfig(empty) == [] match = {"type": "interface", "name": "wan", "comment": "__PARADROP__"} assert len(config.getConfig(match)) == 1 match = {"type": "interface", "name": "wan", "comment": "chute"} assert config.getConfig(match) == [] assert config.getConfigIgnoreComments(empty) == [] assert len(config.getConfigIgnoreComments(match)) == 1 # More existence tests assert not config.existsConfig(empty, empty) match_config = { "type": "interface", "name": "wan", "comment": "__PARADROP__" } match_options = { "ifname": "eth0", "proto": "dhcp" } assert config.existsConfig(match_config, match_options) # Test adding and removing config.delConfigs([(match_config, match_options)]) assert not config.existsConfig(match_config, match_options) config.addConfigs([(match_config, match_options)]) assert config.existsConfig(match_config, match_options) config.delConfig(match_config, match_options) assert not config.existsConfig(match_config, match_options) config.addConfig(match_config, match_options) assert config.existsConfig(match_config, match_options) # Get configuration by chute name assert config.getChuteConfigs("none") == [] assert len(config.getChuteConfigs("__PARADROP__")) == 1 # Test saving and reloading config.save(backupToken="backup") config2 = uci.UCIConfig(path) # Simple test for the equality operators assert config == config2 assert not (config != config2) # Test chuteConfigsMatch function assert not uci.chuteConfigsMatch(config.getChuteConfigs("__PARADROP__"), config2.getChuteConfigs("none")) assert uci.chuteConfigsMatch(config.getChuteConfigs("__PARADROP__"), config2.getChuteConfigs("__PARADROP__")) # Further test the equality operators config2.filepath = "NOMATCH" assert not (config == config2) assert config != config2 config2.filepath = config.filepath config2.myname = "NOMATCH" assert not (config == config2) assert config != config2 config2.myname = config.myname config2.config = [] assert not (config == config2) assert config != config2
def test_uci(): """ Test UCI file utility module """ from paradrop.lib.utils import uci from paradrop.base import settings # Test functions for finding path to UCI files settings.loadSettings(mode="unittest") assert uci.getSystemConfigDir() == "/tmp/.paradrop-test/uci/config.d/" assert uci.getSystemPath( "network") == "/tmp/.paradrop-test/uci/config.d/network" # Test stringify function assert uci.stringify("a") == "a" blob = {"a": "b"} assert uci.stringify(blob) == blob blob = {"a": {"b": "c"}} assert uci.stringify(blob) == blob blob = {"a": ["b", "c"]} assert uci.stringify(blob) == blob blob = {"a": 5} strblob = {"a": "5"} assert uci.stringify(blob) == strblob assert uci.isMatch(blob, strblob) # Write a realistic configuration and load with uci module path = writeTempFile(NETWORK_WAN_CONFIG) config = uci.UCIConfig(path) # Test if it found the config section that we know should be there empty = {} assert config.getConfig(empty) == [] match = {"type": "interface", "name": "wan", "comment": "__PARADROP__"} assert len(config.getConfig(match)) == 1 match = {"type": "interface", "name": "wan", "comment": "chute"} assert config.getConfig(match) == [] assert config.getConfigIgnoreComments(empty) == [] assert len(config.getConfigIgnoreComments(match)) == 1 # More existence tests assert not config.existsConfig(empty, empty) match_config = { "type": "interface", "name": "wan", "comment": "__PARADROP__" } match_options = {"ifname": "eth0", "proto": "dhcp"} assert config.existsConfig(match_config, match_options) # Test adding and removing config.delConfigs([(match_config, match_options)]) assert not config.existsConfig(match_config, match_options) config.addConfigs([(match_config, match_options)]) assert config.existsConfig(match_config, match_options) config.delConfig(match_config, match_options) assert not config.existsConfig(match_config, match_options) config.addConfig(match_config, match_options) assert config.existsConfig(match_config, match_options) # Get configuration by chute name assert config.getChuteConfigs("none") == [] assert len(config.getChuteConfigs("__PARADROP__")) == 1 # Test saving and reloading config.save(backupToken="backup") config2 = uci.UCIConfig(path) # Simple test for the equality operators assert config == config2 assert not (config != config2) # Test chuteConfigsMatch function assert not uci.chuteConfigsMatch(config.getChuteConfigs("__PARADROP__"), config2.getChuteConfigs("none")) assert uci.chuteConfigsMatch(config.getChuteConfigs("__PARADROP__"), config2.getChuteConfigs("__PARADROP__")) # Further test the equality operators config2.filepath = "NOMATCH" assert not (config == config2) assert config != config2 config2.filepath = config.filepath config2.myname = "NOMATCH" assert not (config == config2) assert config != config2 config2.myname = config.myname config2.config = [] assert not (config == config2) assert config != config2