[RIFT 16413, 16414] Unittest failures fixed for utest_package, utest_publisher_dts
[osm/SO.git] / rwlaunchpad / plugins / rwlaunchpadtasklet / rift / package / script.py
1
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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 #
17
18
19 import re
20 import os.path
21
22 from . import package
23
24
25 class ScriptExtractionError(Exception):
26 pass
27
28
29 class PackageScriptExtractor(object):
30 """ This class is reponsible for extracting scripts to the correct directory
31
32 In order to remain compatible with the existing config manager, we extract the scripts
33 to a known location (RIFT-13282)
34 """
35 DEFAULT_INSTALL_DIR = os.path.join(
36 os.environ["RIFT_INSTALL"],
37 "usr/bin"
38 )
39
40 SCRIPT_REGEX = "{prefix}/?scripts/(?P<script_name>[^/]+)$"
41
42 def __init__(self, log, install_dir=DEFAULT_INSTALL_DIR):
43 self._log = log
44 self._install_dir = install_dir
45
46 def _get_rel_dest_path(self, descriptor_id, script_name):
47 dest_path = os.path.join(self._install_dir, script_name)
48 return dest_path
49
50 @classmethod
51 def package_script_files(cls, package):
52 script_file_map = {}
53
54 for file_name in package.files:
55 match = re.match(
56 cls.SCRIPT_REGEX.format(prefix=package.prefix),
57 file_name,
58 )
59 if match is None:
60 continue
61
62 script_name = match.group("script_name")
63
64 script_file_map[script_name] = file_name
65
66 return script_file_map
67
68 def get_extracted_script_path(self, package_id, script_name):
69 return os.path.join(
70 self._get_rel_dest_path(package_id, script_name),
71 )
72
73 def extract_scripts(self, pkg):
74 descriptor_id = pkg.descriptor_id
75 script_files = PackageScriptExtractor.package_script_files(pkg)
76
77 for script_name, script_file in script_files.items():
78 dest_path = self._get_rel_dest_path(descriptor_id, script_name)
79
80 self._log.debug("Extracting %s script to %s", script_name, dest_path)
81 try:
82 pkg.extract_file(script_file, dest_path)
83 except package.ExtractError as e:
84 raise ScriptExtractionError("Failed to extract script %s" % script_name) from e
85
86 def read_script(self, pkg, filename):
87 script_files = PackageScriptExtractor.package_script_files(pkg)
88
89 for script_name, script_file in script_files.items():
90 if script_name == filename:
91 self._log.debug("Found %s script file in package at %s", filename, script_file)
92
93 try:
94 with pkg.open(script_file) as f:
95 userdata = f.read()
96 self._log.info("Custom script read from file %s", userdata)
97 # File contents are read in binary string, decode to regular string and return
98 return userdata.decode()
99 except package.ExtractError as e:
100 raise ScriptExtractionError("Failed to extract script %s" % script_name) from e
101
102 # If we've reached this point but not found a matching script,
103 # raise an Exception, since we got here only because there was supposed
104 # to be a script in the VDU
105 errmsg = "No script file found in the descriptor package"
106 self._log.error(errmsg)
107 raise ScriptExtractionError(errmsg)
108