Package config_management :: Module rpc_repository
[hide private]
[frames] | no frames]

Source Code for Module config_management.rpc_repository

  1  # 
  2  # Copyright (c) 2008--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15   
 16  import os 
 17  import sys 
 18  import tempfile 
 19  from spacewalk.common.usix import raise_with_tb 
 20   
 21  try: # python2 
 22      import xmlrpclib 
 23  except ImportError: # python3 
 24      import xmlrpc.client as xmlrpclib 
 25   
 26   
 27  from config_common import cfg_exceptions, repository, utils, file_utils 
 28  from config_common.rhn_log import log_debug 
 29   
30 -class Repository(repository.RPC_Repository):
31 _session_file = '.rhncfg-manager-session'
32 - def __init__(self, setup_network=1):
33 log_debug(2) 34 repository.RPC_Repository.__init__(self, setup_network) 35 36 self.files_to_delete = [] 37 38 self.username = None 39 self.password = None 40 41 self.session = None
42
43 - def login(self, username=None, password=None):
44 45 self._get_session() 46 47 if not self.session and not (username and password): 48 raise cfg_exceptions.InvalidSession() 49 50 if self.session and not username: 51 test = self.rpc_call('config.test_session', 52 {'session' : self.session}) 53 if not test: 54 raise cfg_exceptions.InvalidSession('Session is either expired or invalid') 55 56 else: 57 self.username = username 58 self.password = password 59 60 try: 61 self.session = self.rpc_call('config.rhn_login', { 62 'username' : self.username, 63 'password' : self.password, 64 }) 65 except xmlrpclib.Fault: 66 e = sys.exc_info()[1] 67 fault_code, fault_string = e.faultCode, e.faultString 68 if fault_code == -2: 69 raise_with_tb(cfg_exceptions.AuthenticationError( 70 "Invalid username or incorrect password"), sys.exc_info()[2]) 71 raise_with_tb(cfg_exceptions.InvalidSession(fault_code, fault_string), sys.exc_info()[2]) 72 73 self._save_session() 74 75 if not self.session: 76 raise cfg_exceptions.InvalidSession 77 78 self.assert_repo_health()
79 80
81 - def cleanup(self):
82 log_debug(4) 83 for file in self.files_to_delete: 84 if not os.path.isdir(file): 85 os.unlink(file)
86
87 - def get_raw_file_info(self, config_channel, repopath, revision=None):
88 """ given a namepath, return the raw data passed by the server """ 89 log_debug(5) 90 params = { 91 'session' : self.session, 92 'config_channel' : config_channel, 93 'path' : repopath, 94 } 95 if revision is not None: 96 params['revision'] = revision 97 try: 98 result = self.rpc_call('config.management.get_file', params) 99 except xmlrpclib.Fault: 100 e = sys.exc_info()[1] 101 if e.faultCode == -4011: 102 # File not present 103 raise_with_tb(cfg_exceptions.RepositoryFileMissingError(config_channel, 104 repopath), sys.exc_info()[2]) 105 raise 106 return result
107
108 - def get_file_info(self, config_channel, repopath, revision=None, auto_delete=1, dest_directory=tempfile.gettempdir()):
109 """ 110 given a namepath, return the filename and the rest of the info passed 111 by the server 112 """ 113 result = self.get_raw_file_info(config_channel, repopath, revision) 114 115 fp = file_utils.FileProcessor() 116 fullpath, dirs_created = fp.process(result, directory=dest_directory, strict_ownership=0) 117 118 if auto_delete: 119 self.files_to_delete.append(fullpath) 120 121 del result['file_contents'] 122 123 return fullpath, result, dirs_created
124 125
126 - def has_file(self, config_channel, repopath):
127 params = { 128 'session' : self.session, 129 'config_channel' : config_channel, 130 'path' : repopath, 131 } 132 return self.rpc_call('config.management.has_file', params)
133
134 - def remove_file(self, config_channel, repopath):
135 """ remove a given file from the repo """ 136 log_debug(4) 137 params = { 138 'session' : self.session, 139 'config_channel' : config_channel, 140 'path' : repopath, 141 } 142 return self.rpc_call('config.management.remove_file', params)
143
144 - def put_file(self, config_channel, repopath, localfile=None, 145 is_first_revision=None, old_revision=None, delim_start=None, 146 delim_end=None, selinux_ctx=None):
147 """ 148 Insert a given file into the repo, overwriting if necessary. 149 localfile defaults to the repopath 150 """ 151 log_debug(4) 152 153 params = self._make_file_info(repopath, localfile, 154 delim_start=delim_start, delim_end=delim_end) 155 156 max_file_size = self.get_maximum_file_size() 157 158 if params['size'] > max_file_size: 159 error_msg = "%s too large (%s bytes, %s bytes max allowed)" 160 raise cfg_exceptions.ConfigFileTooLargeError(error_msg % (localfile, params['size'], max_file_size)) 161 162 if selinux_ctx is not None: 163 params.update({ 164 'selinux_ctx' : selinux_ctx, 165 }) 166 167 params.update({ 168 'session' : self.session, 169 'config_channel' : config_channel, 170 }) 171 if is_first_revision: 172 params['is_first_revision'] = 1 173 elif old_revision: 174 params['old_revision'] = int(old_revision) 175 176 try: 177 result = self.rpc_call('config.management.put_file', params) 178 179 except xmlrpclib.Fault: 180 e = sys.exc_info()[1] 181 fault_code, fault_string = e.faultCode, e.faultString 182 183 if is_first_revision and fault_code == -4013: 184 raise_with_tb(cfg_exceptions.RepositoryFileExistsError(fault_string), sys.exc_info()[2]) 185 186 if old_revision and fault_code == -4012: 187 raise_with_tb(cfg_exceptions.RepositoryFileVersionMismatchError(fault_string), sys.exc_info()[2]) 188 189 if fault_code == -4003: 190 raise_with_tb(cfg_exceptions.ConfigFileTooLargeError(fault_string), sys.exc_info()[2]) 191 192 if fault_code == -4014: 193 raise_with_tb(cfg_exceptions.QuotaExceeded(fault_string), sys.exc_info()[2]) 194 195 raise_with_tb(cfg_exceptions.RepositoryFilePushError(fault_code, fault_string), sys.exc_info()[2]) 196 197 return result
198 199
200 - def config_channel_exists(self, config_channel):
201 log_debug(4, config_channel) 202 return (config_channel in self.list_config_channels())
203
204 - def list_files(self, config_channel, repopath = None, recurse = 1):
205 """ 206 list files in a repo, recursing if requested; 207 repopath is not used yet 208 """ 209 log_debug(4) 210 files = self.rpc_call('config.management.list_files', 211 {'session' : self.session, 'config_channel' : config_channel}) 212 213 return [p['path'] for p in files]
214
215 - def get_file_revisions(self, config_channel, repopath):
216 """ 217 Fetch the file's revisions 218 """ 219 log_debug(4) 220 params = { 221 'session' : self.session, 222 'config_channel' : config_channel, 223 'path' : repopath, 224 } 225 try: 226 revisions = self.rpc_call('config.management.list_file_revisions', 227 params) 228 except xmlrpclib.Fault: 229 e = sys.exc_info()[1] 230 if e.faultCode == -4011: 231 # File not present 232 raise_with_tb(cfg_exceptions.RepositoryFileMissingError( 233 config_channel, repopath), sys.exc_info()[2]) 234 raise 235 return revisions
236
237 - def list_config_channels(self):
238 "List config channels" 239 log_debug(4) 240 if hasattr(self, 'config_channels'): 241 return self.config_channels 242 243 self.config_channels = self.rpc_call( 244 'config.management.list_config_channels', {'session' : self.session} 245 ) or [] 246 247 return self.config_channels
248
249 - def create_config_channel(self, config_channel):
250 "creates a configuration channel" 251 log_debug(4, config_channel) 252 try: 253 return self.rpc_call('config.management.create_config_channel', 254 {'session' : self.session, 'config_channel' : config_channel}) 255 except xmlrpclib.Fault: 256 e = sys.exc_info()[1] 257 if e.faultCode == -4010: 258 raise_with_tb(cfg_exceptions.ConfigChannelAlreadyExistsError(config_channel), sys.exc_info()[2]) 259 raise
260
261 - def remove_config_channel(self, config_channel):
262 "Removes a configuration channel" 263 log_debug(4, config_channel) 264 try: 265 return self.rpc_call('config.management.remove_config_channel', 266 {'session' : self.session, 'config_channel' : config_channel}) 267 except xmlrpclib.Fault: 268 e = sys.exc_info()[1] 269 if e.faultCode == -4009: 270 raise_with_tb(cfg_exceptions.ConfigChannelNotInRepo(config_channel), sys.exc_info()[2]) 271 if e.faultCode == -4005: 272 raise_with_tb(cfg_exceptions.ConfigChannelNotEmptyError(config_channel), sys.exc_info()[2]) 273 raise
274
275 - def _get_default_delimiters(self):
276 "retrieves the default delimiters from the server" 277 log_debug(4) 278 result = self.rpc_call('config.management.get_default_delimiters', 279 {'session' : self.session}) 280 return result.get('delim_start'), result.get('delim_end')
281
282 - def _get_maximum_file_size(self):
283 "get the maximum file size from the server" 284 log_debug(4) 285 result = self.rpc_call('config.management.get_maximum_file_size', 286 {'session' : self.session}) 287 return result
288
289 - def assert_repo_health(self):
290 log_debug(4) 291 pass
292
293 - def diff_file_revisions(self, path, config_channel_src, revision_src, 294 config_channel_dst, revision_dst):
295 log_debug(4) 296 params = { 297 'session' : self.session, 298 'path' : path, 299 'config_channel_src': config_channel_src, 300 'revision_src' : revision_src, 301 } 302 if config_channel_dst is not None: 303 params['config_channel_dst'] = config_channel_dst 304 if revision_dst is not None: 305 params['revision_dst'] = revision_dst 306 try: 307 ret = self.rpc_call('config.management.diff', params) 308 except xmlrpclib.Fault: 309 e = sys.exc_info()[1] 310 if e.faultCode == -4011: 311 # File not present 312 raise_with_tb(cfg_exceptions.RepositoryFileMissingError(e.faultString), sys.exc_info()[2]) 313 if e.faultCode == -4004: 314 # Binary file requested 315 raise_with_tb(cfg_exceptions.BinaryFileDiffError(e.faultString), sys.exc_info()[2]) 316 raise 317 return ret
318
319 - def _get_session(self):
320 session_path = self._get_session_path() 321 322 try: 323 fh = open(session_path, 'r') 324 self.session = fh.read() 325 fh.close() 326 except IOError: 327 # session file not there... 328 self.session = None 329 330 return self.session
331
332 - def _save_session(self):
333 if not self.session: 334 self._remove_session() 335 336 session_path = self._get_session_path() 337 338 fh = open(session_path, "w+") 339 fh.write(self.session) 340 fh.close()
341
342 - def _remove_session(self):
343 p = self._get_session_path() 344 try: 345 os.unlink(p) 346 except OSError: 347 pass
348
349 - def _get_session_path(self):
350 return os.path.join(utils.get_home_dir(), self._session_file)
351