repository.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/usr/bin/env python
  2. """
  3. Licensed to the Apache Software Foundation (ASF) under one
  4. or more contributor license agreements. See the NOTICE file
  5. distributed with this work for additional information
  6. regarding copyright ownership. The ASF licenses this file
  7. to you under the Apache License, Version 2.0 (the
  8. "License"); you may not use this file except in compliance
  9. with the License. You may obtain a copy of the License at
  10. http://www.apache.org/licenses/LICENSE-2.0
  11. Unless required by applicable law or agreed to in writing, software
  12. distributed under the License is distributed on an "AS IS" BASIS,
  13. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. See the License for the specific language governing permissions and
  15. limitations under the License.
  16. Ambari Agent
  17. """
  18. import os
  19. import filecmp
  20. import tempfile
  21. from ambari_commons import OSCheck
  22. from resource_management.core.resources import Execute
  23. from resource_management.core.resources import File
  24. from resource_management.core.providers import Provider
  25. from resource_management.core.source import Template
  26. from resource_management.core.source import StaticFile
  27. from resource_management.libraries.functions.format import format
  28. from resource_management.core.environment import Environment
  29. from resource_management.core.shell import checked_call
  30. import re
  31. class RhelSuseRepositoryProvider(Provider):
  32. def action_create(self):
  33. with Environment.get_instance_copy() as env:
  34. repo_file_name = self.resource.repo_file_name
  35. repo_dir = get_repo_dir()
  36. repo_template = self.resource.repo_template
  37. new_content = Template(repo_template, repo_id=self.resource.repo_id, repo_file_name=self.resource.repo_file_name,
  38. base_url=self.resource.base_url, mirror_list=self.resource.mirror_list)
  39. repo_file_path = format("{repo_dir}/{repo_file_name}.repo")
  40. if self.resource.append_to_file and os.path.isfile(repo_file_path):
  41. with open(repo_file_path, 'a') as repo_file:
  42. repo_file.write('\n' + new_content.get_content())
  43. else:
  44. File(repo_file_path, content=new_content)
  45. def action_remove(self):
  46. with Environment.get_instance_copy() as env:
  47. repo_file_name = self.resource.repo_file_name
  48. repo_dir = get_repo_dir()
  49. File(format("{repo_dir}/{repo_file_name}.repo"),
  50. action = "delete")
  51. def get_repo_dir():
  52. if OSCheck.is_redhat_family():
  53. return '/etc/yum.repos.d'
  54. elif OSCheck.is_suse_family():
  55. return '/etc/zypp/repos.d'
  56. class UbuntuRepositoryProvider(Provider):
  57. package_type = "deb"
  58. repo_dir = "/etc/apt/sources.list.d"
  59. update_cmd = ['apt-get', 'update', '-qq', '-o', 'Dir::Etc::sourcelist=sources.list.d/{repo_file_name}', '-o', 'APT::Get::List-Cleanup=0']
  60. missing_pkey_regex = "The following signatures couldn't be verified because the public key is not available: NO_PUBKEY ([A-Z0-9]+)"
  61. add_pkey_cmd = "apt-key adv --recv-keys --keyserver keyserver.ubuntu.com {pkey}"
  62. def action_create(self):
  63. with Environment.get_instance_copy() as env:
  64. with tempfile.NamedTemporaryFile() as tmpf:
  65. repo_file_name = format("{repo_file_name}.list",repo_file_name = self.resource.repo_file_name)
  66. repo_file_path = format("{repo_dir}/{repo_file_name}", repo_dir = self.repo_dir)
  67. new_content = Template(self.resource.repo_template, package_type=self.package_type,
  68. base_url=self.resource.base_url,
  69. components=' '.join(self.resource.components)).get_content()
  70. old_content = ''
  71. if self.resource.append_to_file and os.path.isfile(repo_file_path):
  72. with open(repo_file_path) as repo_file:
  73. old_content = repo_file.read() + '\n'
  74. File(tmpf.name, content=old_content+new_content)
  75. if not os.path.isfile(repo_file_path) or not filecmp.cmp(tmpf.name, repo_file_path):
  76. File(repo_file_path,
  77. content = StaticFile(tmpf.name)
  78. )
  79. update_cmd_formatted = [format(x) for x in self.update_cmd]
  80. # this is time expensive
  81. retcode, out = checked_call(update_cmd_formatted, sudo=True)
  82. # add public keys for new repos
  83. missing_pkeys = set(re.findall(self.missing_pkey_regex, out))
  84. for pkey in missing_pkeys:
  85. Execute(format(self.add_pkey_cmd),
  86. timeout = 15, # in case we are on the host w/o internet (using localrepo), we should ignore hanging
  87. ignore_failures = True
  88. )
  89. def action_remove(self):
  90. with Environment.get_instance_copy() as env:
  91. repo_file_name = format("{repo_file_name}.list",repo_file_name = self.resource.repo_file_name)
  92. repo_file_path = format("{repo_dir}/{repo_file_name}", repo_dir = self.repo_dir)
  93. if os.path.isfile(repo_file_path):
  94. File(repo_file_path,
  95. action = "delete")
  96. # this is time expensive
  97. update_cmd_formatted = [format(x) for x in self.update_cmd]
  98. Execute(update_cmd_formatted)