def test_delete_repo(self): """ Tests removing an existing repo is correctly saved and loaded """ # Setup repo1 = Repo('test-repo-1') repo2 = Repo('test-repo-2') repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.add_repo(repo1) repo_file.add_repo(repo2) repo_file.save() # Test repo_file.remove_repo_by_name('test-repo-1') repo_file.save() # Verify loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() self.assertEqual(1, len(loaded.all_repos())) self.assertTrue(loaded.get_repo('test-repo-1') is None) self.assertTrue(loaded.get_repo('test-repo-2') is not None)
def test_update_repo(self): """ Tests that updating an existing repo is correctly saved. """ # Setup repo1 = Repo('test-repo-1') repo1['baseurl'] = 'http://localhost/repo1' repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.add_repo(repo1) repo_file.save() # Test repo1['baseurl'] = 'http://localhost/repo-updated' repo_file.update_repo(repo1) repo_file.save() # Verify loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() found_repo = loaded.get_repo('test-repo-1') self.assertEqual(found_repo['baseurl'], 'http://localhost/repo-updated')
def test_multiple_repos(self): """ Tests saving and loading multiple repos. """ # Setup repo1 = Repo('test-repo-1') repo1['baseurl'] = 'http://localhost/repo1' repo2 = Repo('test-repo-2') repo2['baseurl'] = 'http://localhost/repo2' repo_file = RepoFile(TEST_REPO_FILENAME) # Test repo_file.add_repo(repo1) repo_file.add_repo(repo2) repo_file.save() # Verify loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() self.assertEqual(2, len(loaded.all_repos())) found_repo1 = loaded.get_repo('test-repo-1') self.assertTrue(found_repo1 is not None) self.assertTrue(_repo_eq(repo1, found_repo1)) found_repo2 = loaded.get_repo('test-repo-2') self.assertTrue(found_repo2 is not None) self.assertTrue(_repo_eq(repo2, found_repo2))
def test_unbind_repo_exists(self): """ Tests the normal case of unbinding a repo that exists in the repo file. """ # Setup repoid = 'test-unbind-repo' repo_file = RepoFile(self.TEST_REPO_FILENAME) repo_file.add_repo(Repo(repoid)) repo_file.save() # Test repolib.unbind(self.TEST_REPO_FILENAME, self.TEST_MIRROR_LIST_FILENAME, self.TEST_KEYS_DIR, self.TEST_CERT_DIR, 'test-unbind-repo', self.LOCK) # verify repo_file = RepoFile(self.TEST_REPO_FILENAME) repo_file.load( allow_missing=False) # the file should still be there, so error if it doesn't self.assertEqual(0, len(repo_file.all_repos())) certdir = os.path.join(self.TEST_CERT_DIR, repoid) self.assertFalse(os.path.exists(certdir))
def test_one_repo_save_and_load(self): """ Tests the normal flow of saving and loading, using only one repo to minimize complications. """ # Setup add_me = Repo('test-repo-1') add_me['baseurl'] = 'http://localhost/repo' add_me['enabled'] = 1 add_me['gpgkey'] = '/tmp/key' add_me['sslverify'] = 1 add_me['gpgcheck'] = 0 add_me['sslcacert'] = '/tmp/sslcacert' add_me['sslclientcert'] = '/tmp/clientcert' repo_file = RepoFile(TEST_REPO_FILENAME) # Test Save repo_file.add_repo(add_me) repo_file.save() # Verify Save self.assertTrue(os.path.exists(TEST_REPO_FILENAME)) # Test Load loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() # Verify Load self.assertEqual(1, len(loaded.all_repos())) found_repo = loaded.get_repo('test-repo-1') self.assertTrue(found_repo is not None) self.assertTrue(_repo_eq(add_me, found_repo))
def test_no_repos_save_load(self): """ Tests that saving and loading a file with no repos is successful. """ # Test repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.save() # Verify loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() # Verify self.assertEqual(0, len(loaded.all_repos()))
def test_header(self): """ Tests that the pulp header is properly written in the generated file. """ # Setup repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.save() # Test f = open(TEST_REPO_FILENAME, 'r') contents = f.read() f.close() # Verify self.assertTrue(contents.startswith(RepoFile.FILE_HEADER))
def test_delete_repofile(self): """ Tests that deleting a RepoFile correctly deletes the file on disk. """ # Setup self.assertTrue(not os.path.exists(TEST_REPO_FILENAME)) repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.save() self.assertTrue(os.path.exists(TEST_REPO_FILENAME)) # Test repo_file.delete() # Verify self.assertTrue(not os.path.exists(TEST_REPO_FILENAME))
def test_baseurl_not_mirrorlist(self): """ Tests that if a baseurl is specified, a mirrorlist entry isn't written to the saved repo file. """ # Setup repo = Repo('test-repo-1') repo['baseurl'] = 'http://localhost' repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.add_repo(repo) repo_file.save() # Test loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() loaded_repo = loaded.get_repo('test-repo-1') self.assertEqual(loaded_repo['baseurl'], 'http://localhost') self.assertTrue('mirrorlist' not in loaded_repo)
def test_mirrorlist_not_baseurl(self): """ Tests that if a mirrorlist is specified, a baseurl entry isn't written to the saved repo file. """ # Setup repo = Repo('test-repo-1') repo['mirrorlist'] = 'file://etc/pulp/mirrorlist' repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.add_repo(repo) repo_file.save() # Test loaded = RepoFile(TEST_REPO_FILENAME) loaded.load() loaded_repo = loaded.get_repo('test-repo-1') self.assertEqual(loaded_repo['mirrorlist'], 'file://etc/pulp/mirrorlist') self.assertTrue('baseurl' not in loaded_repo)
def test_bind_existing_file(self): """ Tests binding a new repo when the underlying file exists and has repos in it (the existing repo shouldn't be deleted). """ # Setup repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.add_repo(Repo('existing-repo-1')) repo_file.save() # Test url_list = ['http://pulpserver'] repolib.bind(TEST_REPO_FILENAME, TEST_MIRROR_LIST_FILENAME, TEST_KEYS_DIR, TEST_CERT_DIR, REPO_ID, REPO_NAME, url_list, {}, None, None, ENABLED, LOCK) # Verify self.assertTrue(os.path.exists(TEST_REPO_FILENAME)) repo_file = RepoFile(TEST_REPO_FILENAME) repo_file.load() self.assertEqual(2, len(repo_file.all_repos()))
def test_bind_existing_file(self): """ Tests binding a new repo when the underlying file exists and has repos in it (the existing repo shouldn't be deleted). """ # Setup repo_file = RepoFile(self.TEST_REPO_FILENAME) repo_file.add_repo(Repo('existing-repo-1')) repo_file.save() # Test url_list = ['http://pulpserver'] repolib.bind(self.TEST_REPO_FILENAME, self.TEST_MIRROR_LIST_FILENAME, self.TEST_KEYS_DIR, self.TEST_CERT_DIR, REPO_ID, REPO_NAME, url_list, {}, None, ENABLED, self.LOCK) # Verify self.assertTrue(os.path.exists(self.TEST_REPO_FILENAME)) repo_file = RepoFile(self.TEST_REPO_FILENAME) repo_file.load() self.assertEqual(2, len(repo_file.all_repos()))
def bind(repo_filename, mirror_list_filename, keys_root_dir, cert_root_dir, repo_id, repo_name, url_list, gpg_keys, clientcert, enabled, lock=None, verify_ssl=True, ca_path=DEFAULT_CA_PATH): """ Uses the given data to safely bind a repo to a repo file. This call will determine the best method for representing the repo given the data in the repo object as well as the list of URLs where the repo can be found. The default lock is defined at the module level and is used to ensure that concurrent access to the give files is prevented. Specific locks can be passed in for testing purposes to circumvent the default location of the lock which requires root access. :param repo_filename: full path to the location of the repo file in which the repo will be bound; this file does not need to exist prior to this call :type repo_filename: string :param mirror_list_filename: full path to the location of the mirror list file that should be written for the given repo if necessary; this should be unique for the given repo :type mirror_list_filename: string :param keys_root_dir: absolute path to the root directory in which the keys for all repos will be stored :type keys_root_dir: string :param cert_root_dir: absolute path to the root directory in which the certs for all repos will be stored :type cert_root_dir: string :param repo_id: uniquely identifies the repo being updated :type repo_id: string :param repo_name: the repo name :type repo_name: str :param url_list: list of URLs that will be used to access the repo; this call will determine the best way to represent the URL list in the repo definition :type url_list: list of strings :param gpg_keys: mapping of key name to contents for GPG keys to be used when verifying packages from this repo :type gpg_keys: dict {string: string} :param clientcert: The client certificate (PEM). :type clientcert: str :param lock: if the default lock is unacceptble, it may be overridden in this variable :type lock: L{Lock} :param verify_ssl: Whether the repo file should be configured to validate CA trust. Defaults to True. :type verify_ssl: bool :param ca_path: Absolute path to a directory that contains trusted CA certificates. Defaults to pulp.bindings.server.DEFAULT_CA_PATH. :type ca_path: basestring """ if not lock: lock = Lock(LOCK_FILE) lock.acquire() try: log.info('Binding repo [%s]' % repo_id) repo_file = RepoFile(repo_filename) repo_file.load() # In the case of an update, only the changed values will have been sent. # Therefore, any of the major data components (repo data, url list, keys) # may be None. if repo_name is not None: repo = _convert_repo(repo_id, enabled, repo_name) else: repo = repo_file.get_repo(repo_id) if gpg_keys is not None: _handle_gpg_keys(repo, gpg_keys, keys_root_dir) _handle_client_cert(repo, cert_root_dir, clientcert) if verify_ssl: repo['sslverify'] = '1' repo['sslcacert'] = ca_path else: repo['sslverify'] = '0' if url_list is not None: _handle_host_urls(repo, url_list, mirror_list_filename) if repo_file.get_repo(repo.id): log.info('Updating existing repo [%s]' % repo.id) repo_file.update_repo(repo) else: log.info('Adding new repo [%s]' % repo.id) repo_file.add_repo(repo) repo_file.save() finally: lock.release()
def unbind(repo_filename, mirror_list_filename, keys_root_dir, cert_root_dir, repo_id, lock=None): """ Removes the repo identified by repo_id from the given repo file. If the repo is not bound, this call has no effect. If the mirror list file exists, it will be deleted. The default lock is defined at the module level and is used to ensure that concurrent access to the give files is prevented. Specific locks can be passed in for testing purposes to circumvent the default location of the lock which requires root access. @param repo_filename: full path to the location of the repo file in which the repo will be removed; if this file does not exist this call has no effect @type repo_filename: string @param mirror_list_filename: full path to the location of the mirror list file that may exist for the given repo; if the file does not exist this field will be ignored @type mirror_list_filename: string @param keys_root_dir: absolute path to the root directory in which the keys for all repos will be stored @type keys_root_dir: string @param cert_root_dir: absolute path to the root directory in which the certs for all repos will be stored @type cert_root_dir: string @param repo_id: identifies the repo in the repo file to delete @type repo_id: string @param lock: if the default lock is unacceptable, it may be overridden in this variable @type lock: L{Lock} """ if not lock: lock = Lock(LOCK_FILE) lock.acquire() try: log.info('Unbinding repo [%s]' % repo_id) if not os.path.exists(repo_filename): return # Repo file changes repo_file = RepoFile(repo_filename) repo_file.load() repo_file.remove_repo_by_name(repo_id) # will not throw an error if repo doesn't exist repo_file.save() # Mirror list removal if os.path.exists(mirror_list_filename): os.remove(mirror_list_filename) # Keys removal repo_keys = RepoKeyFiles(keys_root_dir, repo_id) repo_keys.update_filesystem() # cert removal certificates = CertFiles(cert_root_dir, repo_id) certificates.apply() finally: lock.release()
def bind(repo_filename, mirror_list_filename, keys_root_dir, cert_root_dir, repo_id, repo_name, url_list, gpg_keys, clientcert, enabled, lock=None, verify_ssl=True, ca_path=DEFAULT_CA_PATH): """ Uses the given data to safely bind a repo to a repo file. This call will determine the best method for representing the repo given the data in the repo object as well as the list of URLs where the repo can be found. The default lock is defined at the module level and is used to ensure that concurrent access to the give files is prevented. Specific locks can be passed in for testing purposes to circumvent the default location of the lock which requires root access. :param repo_filename: full path to the location of the repo file in which the repo will be bound; this file does not need to exist prior to this call :type repo_filename: string :param mirror_list_filename: full path to the location of the mirror list file that should be written for the given repo if necessary; this should be unique for the given repo :type mirror_list_filename: string :param keys_root_dir: absolute path to the root directory in which the keys for all repos will be stored :type keys_root_dir: string :param cert_root_dir: absolute path to the root directory in which the certs for all repos will be stored :type cert_root_dir: string :param repo_id: uniquely identifies the repo being updated :type repo_id: string :param repo_name: the repo name :type repo_name: str :param url_list: list of URLs that will be used to access the repo; this call will determine the best way to represent the URL list in the repo definition :type url_list: list of strings :param gpg_keys: mapping of key name to contents for GPG keys to be used when verifying packages from this repo :type gpg_keys: dict {string: string} :param clientcert: The client certificate (PEM). :type clientcert: str :param enabled: Whether or not the repository is set to 'enabled' :type enabled: bool :param lock: if the default lock is unacceptble, it may be overridden in this variable :type lock: L{Lock} :param verify_ssl: Whether the repo file should be configured to validate CA trust. Defaults to True. :type verify_ssl: bool :param ca_path: Absolute path to a directory that contains trusted CA certificates. Defaults to pulp.bindings.server.DEFAULT_CA_PATH. :type ca_path: basestring """ if not lock: lock = Lock(LOCK_FILE) lock.acquire() try: log.info('Binding repo [%s]' % repo_id) repo_file = RepoFile(repo_filename) repo_file.load() # In the case of an update, only the changed values will have been sent. # Therefore, any of the major data components (repo data, url list, keys) # may be None. repo = repo_file.get_repo(repo_id) if not repo: # if no repo name is provided for a new repo, use the id for the name repo = Repo(repo_id) if repo_name is None: repo['name'] = repo_id else: repo['name'] = repo_name repo['enabled'] = str(int(enabled)) if repo_name: repo['name'] = repo_name if gpg_keys is not None: _handle_gpg_keys(repo, gpg_keys, keys_root_dir) _handle_client_cert(repo, cert_root_dir, clientcert) if verify_ssl: repo['sslverify'] = '1' repo['sslcacert'] = ca_path else: repo['sslverify'] = '0' if url_list is not None: _handle_host_urls(repo, url_list, mirror_list_filename) if repo_file.get_repo(repo.id): log.info('Updating existing repo [%s]' % repo.id) repo_file.update_repo(repo) else: log.info('Adding new repo [%s]' % repo.id) repo_file.add_repo(repo) repo_file.save() finally: lock.release()