filestorage.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import cPickle as pickle
  4. import logging
  5. import os
  6. import shutil
  7. from .basestorage import BaseStorage
  8. class FileStorage(BaseStorage):
  9. """Provides file-based persistency for BaseStorage"""
  10. __data = None
  11. def __init__(self, storage_dir):
  12. self.logger = logging.getLogger('Storage')
  13. self.storage_dir = storage_dir
  14. self.logger.debug('Using storage at \'{0}\''.format(storage_dir))
  15. self.storage_filename = os.path.join(storage_dir, 'storage.dat')
  16. self.storage_file = None
  17. def open(self):
  18. self.storage_file = open(self.storage_filename, 'a+b')
  19. loaded_data = {}
  20. try:
  21. self.storage_file.seek(0, os.SEEK_SET)
  22. loaded_data = pickle.load(self.storage_file)
  23. except EOFError:
  24. self.logger.warn(
  25. 'The storage file was empty.' +
  26. 'Assuming this is the first start with this storage directory.')
  27. except Exception as err:
  28. self.logger.error(
  29. 'Loading the storage failed. Please resolve the error ' +
  30. 'and/or remove the storage file \'%s\': %s',
  31. self.storage_filename,
  32. str(err),
  33. )
  34. raise err
  35. self.logger.info('Opened storage with %d entries.', len(loaded_data))
  36. self.__data = loaded_data
  37. def save(self):
  38. if self.storage_file is None:
  39. return
  40. self.storage_file.seek(0, os.SEEK_SET)
  41. self.storage_file.truncate()
  42. pickle.dump(self.__data, self.storage_file, protocol=2)
  43. self.storage_file.flush()
  44. # make an auto-backup of the just-written file
  45. shutil.copyfile(
  46. self.storage_filename,
  47. self.storage_filename + '.autobackup')
  48. def close(self):
  49. self.save()
  50. self.storage_file.close()
  51. self.storage_file = None
  52. BaseStorage.close(self)
  53. def get_node(self, id):
  54. """Gets the node by its id, if any."""
  55. return self.__data.get(id)
  56. def get_all_nodes_raw(self):
  57. """Gets all nodes as dict."""
  58. result = {}
  59. for nodeid in self.__data:
  60. if nodeid.startswith('__'):
  61. continue
  62. node = self.__data[nodeid]
  63. result[nodeid] = node
  64. return result
  65. def set_node_data(self, key, data):
  66. self.__data[key] = data
  67. self.save()
  68. def get_vpn_keys(self):
  69. """Gets a list of VPN keys."""
  70. if not self.DATAKEY_VPN in self.__data:
  71. return {}
  72. vpn = [key for key in self.__data[self.DATAKEY_VPN]]
  73. return vpn
  74. def get_vpn_item(self, key, create=False):
  75. """Get the VPN entry with the specified key."""
  76. if not self.DATAKEY_VPN in self.__data:
  77. if not create:
  78. return None
  79. self.__data[self.DATAKEY_VPN] = {}
  80. if not key in self.__data[self.DATAKEY_VPN]:
  81. if not create:
  82. return None
  83. self.__data[self.DATAKEY_VPN][key] = {'active': {}, 'last': {}}
  84. return self.__data[self.DATAKEY_VPN][key]
  85. def store_vpn_item(self, key, data):
  86. if not self.DATAKEY_VPN in self.__data:
  87. self.__data[self.DATAKEY_VPN] = {}
  88. self.__data[self.DATAKEY_VPN][key] = data
  89. self.save()