| | |
| | | #!/usr/bin/python |
| | | #!/usr/bin/python3.5 |
| | | # |
| | | # CDDL HEADER START |
| | | # |
| | |
| | | def __init__(self, config): |
| | | self.description = _( |
| | | "checks Userland packages for common content errors") |
| | | path = os.getenv('PROTO_PATH') |
| | | if path != None: |
| | | self.proto_path = path.split() |
| | | else: |
| | | self.proto_path = None |
| | | # |
| | | # These lists are used to check if a 32/64-bit binary |
| | | # is in a proper 32/64-bit directory. |
| | | # |
| | | self.pathlist32 = [ |
| | | "i86", |
| | | "sparcv7", |
| | | "32", |
| | | "i86pc-solaris-64int", # perl path |
| | | "sun4-solaris-64int" # perl path |
| | | ] |
| | | self.pathlist64 = [ |
| | | "amd64", |
| | | "sparcv9", |
| | | "64", |
| | | "i86pc-solaris-64", # perl path |
| | | "sun4-solaris-64" # perl path |
| | | ] |
| | | self.runpath_re = [ |
| | | re.compile('^/lib(/.*)?$'), |
| | | re.compile('^/usr/'), |
| | | re.compile('^\$ORIGIN/') |
| | | ] |
| | | self.runpath_64_re = [ |
| | | re.compile('^.*/64(/.*)?$'), |
| | | re.compile('^.*/amd64(/.*)?$'), |
| | | re.compile('^.*/sparcv9(/.*)?$'), |
| | | re.compile('^.*/i86pc-solaris-64(/.*)?$'), # perl path |
| | | re.compile('^.*/sun4-solaris-64(/.*)?$') # perl path |
| | | ] |
| | | self.initscript_re = re.compile("^etc/(rc.|init)\.d") |
| | | path = os.getenv('PROTO_PATH') |
| | | if path != None: |
| | | self.proto_path = path.split() |
| | | else: |
| | | self.proto_path = None |
| | | # |
| | | # These lists are used to check if a 32/64-bit binary |
| | | # is in a proper 32/64-bit directory. |
| | | # |
| | | self.pathlist32 = [ |
| | | "i86", |
| | | "sparcv7", |
| | | "32", |
| | | "i86pc-solaris-64int", # perl path |
| | | "sun4-solaris-64int" # perl path |
| | | ] |
| | | self.pathlist64 = [ |
| | | "amd64", |
| | | "sparcv9", |
| | | "64", |
| | | "i86pc-solaris-thread-multi-64", # perl path |
| | | "sun4-solaris-thread-multi-64" # perl path |
| | | ] |
| | | self.runpath_re = [ |
| | | re.compile('^/lib(/.*)?$'), |
| | | re.compile('^/usr/'), |
| | | re.compile('^\$ORIGIN/') |
| | | ] |
| | | self.runpath_64_re = [ |
| | | re.compile('^.*/64(/.*)?$'), |
| | | re.compile('^.*/amd64(/.*)?$'), |
| | | re.compile('^.*/sparcv9(/.*)?$'), |
| | | re.compile('^.*/i86pc-solaris-thread-multi-64(/.*)?$'), # perl path |
| | | re.compile('^.*/sun4-solaris-thread-multi-64(/.*)?$') # perl path |
| | | ] |
| | | self.initscript_re = re.compile("^etc/(rc.|init)\.d") |
| | | |
| | | self.lint_paths = {} |
| | | self.ref_paths = {} |
| | |
| | | target[p] = l |
| | | |
| | | def __realpath(self, path, target): |
| | | """Combine path and target to get the real path.""" |
| | | """Combine path and target to get the real path.""" |
| | | |
| | | result = os.path.dirname(path) |
| | | result = os.path.dirname(path) |
| | | |
| | | for frag in target.split(os.sep): |
| | | if frag == '..': |
| | | result = os.path.dirname(result) |
| | | elif frag == '.': |
| | | pass |
| | | else: |
| | | result = os.path.join(result, frag) |
| | | for frag in target.split(os.sep): |
| | | if frag == '..': |
| | | result = os.path.dirname(result) |
| | | elif frag == '.': |
| | | pass |
| | | else: |
| | | result = os.path.join(result, frag) |
| | | |
| | | return result |
| | | return result |
| | | |
| | | def __elf_aslr_check(self, path, engine): |
| | | result = None |
| | | def __elf_aslr_check(self, path, engine): |
| | | result = None |
| | | |
| | | ei = elf.get_info(path) |
| | | type = ei.get("type"); |
| | | if type != "exe": |
| | | return result |
| | | ei = elf.get_info(path) |
| | | type = ei.get("type"); |
| | | if type != "exe": |
| | | return result |
| | | |
| | | # get the ASLR tag string for this binary |
| | | aslr_tag_process = subprocess.Popen( |
| | | "/usr/bin/elfedit -r -e 'dyn:sunw_aslr' " |
| | | + path, shell=True, |
| | | stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| | | # get the ASLR tag string for this binary |
| | | aslr_tag_process = subprocess.Popen( |
| | | "/usr/bin/elfedit -r -e 'dyn:sunw_aslr' " |
| | | + path, shell=True, |
| | | stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| | | |
| | | # aslr_tag_string will get stdout; err will get stderr |
| | | aslr_tag_string, err = aslr_tag_process.communicate() |
| | | # aslr_tag_string will get stdout; err will get stderr |
| | | aslr_tag_string, err = aslr_tag_process.communicate() |
| | | |
| | | # No ASLR tag was found; everthing must be tagged |
| | | if aslr_tag_process.returncode != 0: |
| | | engine.error( |
| | | _("'%s' is not tagged for aslr") % (path), |
| | | msgid="%s%s.5" % (self.name, "001")) |
| | | return result |
| | | # No ASLR tag was found; everthing must be tagged |
| | | if aslr_tag_process.returncode != 0: |
| | | engine.error( |
| | | _("'%s' is not tagged for aslr") % (path), |
| | | msgid="%s%s.5" % (self.name, "001")) |
| | | return result |
| | | |
| | | # look for "ENABLE" anywhere in the string; |
| | | # warn about binaries which are not ASLR enabled |
| | | if re.search("ENABLE", aslr_tag_string) is not None: |
| | | return result |
| | | engine.warning( |
| | | _("'%s' does not have aslr enabled") % (path), |
| | | msgid="%s%s.6" % (self.name, "001")) |
| | | return result |
| | | # look for "ENABLE" anywhere in the string; |
| | | # warn about binaries which are not ASLR enabled |
| | | if re.search("ENABLE", aslr_tag_string) is not None: |
| | | return result |
| | | engine.warning( |
| | | _("'%s' does not have aslr enabled") % (path), |
| | | msgid="%s%s.6" % (self.name, "001")) |
| | | return result |
| | | |
| | | def __elf_runpath_check(self, path, engine): |
| | | result = None |
| | | list = [] |
| | | def __elf_runpath_check(self, path, engine): |
| | | result = None |
| | | list = [] |
| | | |
| | | ed = elf.get_dynamic(path) |
| | | ei = elf.get_info(path) |
| | | bits = ei.get("bits") |
| | | for dir in ed.get("runpath", "").split(":"): |
| | | if dir == None or dir == '': |
| | | continue |
| | | ed = elf.get_dynamic(path) |
| | | ei = elf.get_info(path) |
| | | bits = ei.get("bits") |
| | | for dir in ed.get("runpath", "").split(":"): |
| | | if dir == None or dir == '': |
| | | continue |
| | | |
| | | match = False |
| | | for expr in self.runpath_re: |
| | | if expr.match(dir): |
| | | match = True |
| | | break |
| | | match = False |
| | | for expr in self.runpath_re: |
| | | if expr.match(dir): |
| | | match = True |
| | | break |
| | | |
| | | # The RUNPATH shouldn't contain any runtime linker |
| | | # default paths (or the /64 equivalent link) |
| | | if dir in ['/lib', '/lib/64', |
| | | '/lib/amd64', '/lib/sparcv9', |
| | | '/usr/lib', '/usr/lib/64', |
| | | '/usr/lib/amd64', '/usr/lib/sparcv9' ]: |
| | | list.append(dir) |
| | | # The RUNPATH shouldn't contain any runtime linker |
| | | # default paths (or the /64 equivalent link) |
| | | if dir in ['/lib', '/lib/64', |
| | | '/lib/amd64', '/lib/sparcv9', |
| | | '/usr/lib', '/usr/lib/64', |
| | | '/usr/lib/amd64', '/usr/lib/sparcv9' ]: |
| | | list.append(dir) |
| | | |
| | | if match == False: |
| | | list.append(dir) |
| | | if match == False: |
| | | list.append(dir) |
| | | |
| | | if bits == 32: |
| | | for expr in self.runpath_64_re: |
| | | if expr.search(dir): |
| | | engine.warning( |
| | | _("64-bit runpath in 32-bit binary, '%s' includes '%s'") % (path, dir), |
| | | msgid="%s%s.3" % (self.name, "001")) |
| | | else: |
| | | match = False |
| | | for expr in self.runpath_64_re: |
| | | if expr.search(dir): |
| | | match = True |
| | | break |
| | | if match == False: |
| | | engine.warning( |
| | | _("32-bit runpath in 64-bit binary, '%s' includes '%s'") % (path, dir), |
| | | msgid="%s%s.3" % (self.name, "001")) |
| | | if len(list) > 0: |
| | | result = _("bad RUNPATH, '%%s' includes '%s'" % |
| | | ":".join(list)) |
| | | if bits == 32: |
| | | for expr in self.runpath_64_re: |
| | | if expr.search(dir): |
| | | engine.warning( |
| | | _("64-bit runpath in 32-bit binary, '%s' includes '%s'") % (path, dir), |
| | | msgid="%s%s.3" % (self.name, "001")) |
| | | else: |
| | | match = False |
| | | for expr in self.runpath_64_re: |
| | | if expr.search(dir): |
| | | match = True |
| | | break |
| | | if match == False: |
| | | engine.warning( |
| | | _("32-bit runpath in 64-bit binary, '%s' includes '%s'") % (path, dir), |
| | | msgid="%s%s.3" % (self.name, "001")) |
| | | if len(list) > 0: |
| | | result = _("bad RUNPATH, '%%s' includes '%s'" % |
| | | ":".join(list)) |
| | | |
| | | return result |
| | | return result |
| | | |
| | | def __elf_wrong_location_check(self, path): |
| | | result = None |
| | | def __elf_wrong_location_check(self, path): |
| | | result = None |
| | | |
| | | ei = elf.get_info(path) |
| | | bits = ei.get("bits") |
| | | type = ei.get("type"); |
| | | ei = elf.get_info(path) |
| | | bits = ei.get("bits") |
| | | type = ei.get("type"); |
| | | elems = os.path.dirname(path).split("/") |
| | | |
| | | path64 = False |
| | | for p in self.pathlist64: |
| | | if (p in elems): |
| | | path64 = True |
| | | for p in self.pathlist64: |
| | | if (p in elems): |
| | | path64 = True |
| | | |
| | | path32 = False |
| | | for p in self.pathlist32: |
| | | if (p in elems): |
| | | path32 = True |
| | | path32 = False |
| | | for p in self.pathlist32: |
| | | if (p in elems): |
| | | path32 = True |
| | | |
| | | # ignore 64-bit executables in normal (non-32-bit-specific) |
| | | # locations, that's ok now. |
| | | if (type == "exe" and bits == 64 and path32 == False and path64 == False): |
| | | return result |
| | | # ignore 64-bit executables in normal (non-32-bit-specific) |
| | | # locations, that's ok now. |
| | | if (type == "exe" and bits == 64 and path32 == False and path64 == False): |
| | | return result |
| | | |
| | | if bits == 32 and path64: |
| | | result = _("32-bit object '%s' in 64-bit path") |
| | | elif bits == 64 and not path64: |
| | | result = _("64-bit object '%s' in 32-bit path") |
| | | return result |
| | | if bits == 32 and path64: |
| | | result = _("32-bit object '%s' in 64-bit path") |
| | | elif bits == 64 and not path64: |
| | | result = _("64-bit object '%s' in 32-bit path") |
| | | return result |
| | | |
| | | def file_action(self, action, manifest, engine, pkglint_id="001"): |
| | | """Checks for existence in the proto area.""" |
| | | def file_action(self, action, manifest, engine, pkglint_id="001"): |
| | | """Checks for existence in the proto area.""" |
| | | |
| | | if action.name not in ["file"]: |
| | | return |
| | | if action.name not in ["file"]: |
| | | return |
| | | |
| | | path = action.hash |
| | | if path == None or path == 'NOHASH': |
| | | path = action.attrs["path"] |
| | | path = action.hash |
| | | if path == None or path == 'NOHASH': |
| | | path = action.attrs["path"] |
| | | |
| | | # check for writable files without a preserve attribute |
| | | if "mode" in action.attrs: |
| | | mode = action.attrs["mode"] |
| | | # check for writable files without a preserve attribute |
| | | if "mode" in action.attrs: |
| | | mode = action.attrs["mode"] |
| | | |
| | | if (int(mode, 8) & 0222) != 0 and "preserve" not in action.attrs: |
| | | engine.error( |
| | | _("%(path)s is writable (%(mode)s), but missing a preserve" |
| | | " attribute") % {"path": path, "mode": mode}, |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | elif "preserve" in action.attrs: |
| | | if "mode" in action.attrs: |
| | | mode = action.attrs["mode"] |
| | | if (int(mode, 8) & 0222) == 0: |
| | | engine.error( |
| | | _("%(path)s has a preserve action, but is not writable (%(mode)s)") % {"path": path, "mode": mode}, |
| | | msgid="%s%s.4" % (self.name, pkglint_id)) |
| | | else: |
| | | engine.error( |
| | | _("%(path)s has a preserve action, but no mode") % {"path": path, "mode": mode}, |
| | | msgid="%s%s.3" % (self.name, pkglint_id)) |
| | | if (int(mode, 8) & 0o222) != 0 and "preserve" not in action.attrs: |
| | | engine.error( |
| | | _("%(path)s is writable (%(mode)s), but missing a preserve" |
| | | " attribute") % {"path": path, "mode": mode}, |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | elif "preserve" in action.attrs: |
| | | if "mode" in action.attrs: |
| | | mode = action.attrs["mode"] |
| | | if (int(mode, 8) & 0o222) == 0: |
| | | engine.error( |
| | | _("%(path)s has a preserve action, but is not writable (%(mode)s)") % {"path": path, "mode": mode}, |
| | | msgid="%s%s.4" % (self.name, pkglint_id)) |
| | | else: |
| | | engine.error( |
| | | _("%(path)s has a preserve action, but no mode") % {"path": path, "mode": mode}, |
| | | msgid="%s%s.3" % (self.name, pkglint_id)) |
| | | |
| | | # checks that require a physical file to look at |
| | | if self.proto_path is not None: |
| | | for directory in self.proto_path: |
| | | fullpath = directory + "/" + path |
| | | # checks that require a physical file to look at |
| | | if self.proto_path is not None: |
| | | for directory in self.proto_path: |
| | | fullpath = directory + "/" + path |
| | | |
| | | if os.path.exists(fullpath): |
| | | break |
| | | if os.path.exists(fullpath): |
| | | break |
| | | |
| | | if not os.path.exists(fullpath): |
| | | engine.info( |
| | | _("%s missing from proto area, skipping" |
| | | " content checks") % path, |
| | | msgid="%s%s.1" % (self.name, pkglint_id)) |
| | | elif elf.is_elf_object(fullpath): |
| | | # 32/64 bit in wrong place |
| | | result = self.__elf_wrong_location_check(fullpath) |
| | | if result != None: |
| | | engine.error(result % path, |
| | | msgid="%s%s.2" % (self.name, pkglint_id)) |
| | | result = self.__elf_runpath_check(fullpath, engine) |
| | | if result != None: |
| | | engine.error(result % path, |
| | | msgid="%s%s.3" % (self.name, pkglint_id)) |
| | | # illumos does not support ASLR |
| | | #result = self.__elf_aslr_check(fullpath, engine) |
| | | if not os.path.exists(fullpath): |
| | | engine.info( |
| | | _("%s missing from proto area, skipping" |
| | | " content checks") % path, |
| | | msgid="%s%s.1" % (self.name, pkglint_id)) |
| | | elif elf.is_elf_object(fullpath): |
| | | # 32/64 bit in wrong place |
| | | result = self.__elf_wrong_location_check(fullpath) |
| | | if result != None: |
| | | engine.error(result % path, |
| | | msgid="%s%s.2" % (self.name, pkglint_id)) |
| | | result = self.__elf_runpath_check(fullpath, engine) |
| | | if result != None: |
| | | engine.error(result % path, |
| | | msgid="%s%s.3" % (self.name, pkglint_id)) |
| | | # illumos does not support ASLR |
| | | #result = self.__elf_aslr_check(fullpath, engine) |
| | | |
| | | file_action.pkglint_desc = _("Paths should exist in the proto area.") |
| | | file_action.pkglint_desc = _("Paths should exist in the proto area.") |
| | | |
| | | def link_resolves(self, action, manifest, engine, pkglint_id="002"): |
| | | """Checks for link resolution.""" |
| | | def link_resolves(self, action, manifest, engine, pkglint_id="002"): |
| | | """Checks for link resolution.""" |
| | | |
| | | if action.name not in ["link", "hardlink"]: |
| | | return |
| | | if action.name not in ["link", "hardlink"]: |
| | | return |
| | | |
| | | path = action.attrs["path"] |
| | | target = action.attrs["target"] |
| | | realtarget = self.__realpath(path, target) |
| | | path = action.attrs["path"] |
| | | target = action.attrs["target"] |
| | | realtarget = self.__realpath(path, target) |
| | | |
| | | # Check against the target image (ref_paths), since links might |
| | | # resolve outside the packages delivering a particular |
| | | # component. |
| | | # Check against the target image (ref_paths), since links might |
| | | # resolve outside the packages delivering a particular |
| | | # component. |
| | | |
| | | # links to files should directly match a patch in the reference |
| | | # repo. |
| | | if self.ref_paths.get(realtarget, None): |
| | | return |
| | | # links to files should directly match a patch in the reference |
| | | # repo. |
| | | if self.ref_paths.get(realtarget, None): |
| | | return |
| | | |
| | | # If it didn't match a path in the reference repo, it may still |
| | | # be a link to a directory that has no action because it uses |
| | | # the default attributes. Look for a path that starts with |
| | | # this value plus a trailing slash to be sure this it will be |
| | | # resolvable on a fully installed system. |
| | | realtarget += '/' |
| | | for key in self.ref_paths: |
| | | if key.startswith(realtarget): |
| | | return |
| | | # If it didn't match a path in the reference repo, it may still |
| | | # be a link to a directory that has no action because it uses |
| | | # the default attributes. Look for a path that starts with |
| | | # this value plus a trailing slash to be sure this it will be |
| | | # resolvable on a fully installed system. |
| | | realtarget += '/' |
| | | for key in self.ref_paths: |
| | | if key.startswith(realtarget): |
| | | return |
| | | |
| | | engine.error(_("%s %s has unresolvable target '%s'") % |
| | | (action.name, path, target), |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | engine.error(_("%s %s has unresolvable target '%s'") % |
| | | (action.name, path, target), |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | |
| | | link_resolves.pkglint_desc = _("links should resolve.") |
| | | link_resolves.pkglint_desc = _("links should resolve.") |
| | | |
| | | def init_script(self, action, manifest, engine, pkglint_id="003"): |
| | | """Checks for SVR4 startup scripts.""" |
| | | def init_script(self, action, manifest, engine, pkglint_id="003"): |
| | | """Checks for SVR4 startup scripts.""" |
| | | |
| | | if action.name not in ["file", "dir", "link", "hardlink"]: |
| | | return |
| | | if action.name not in ["file", "dir", "link", "hardlink"]: |
| | | return |
| | | |
| | | path = action.attrs["path"] |
| | | if self.initscript_re.match(path): |
| | | engine.warning( |
| | | _("SVR4 startup '%s', deliver SMF" |
| | | " service instead") % path, |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | path = action.attrs["path"] |
| | | if self.initscript_re.match(path): |
| | | engine.warning( |
| | | _("SVR4 startup '%s', deliver SMF" |
| | | " service instead") % path, |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | |
| | | init_script.pkglint_desc = _( |
| | | "SVR4 startup scripts should not be delivered.") |
| | | init_script.pkglint_desc = _( |
| | | "SVR4 startup scripts should not be delivered.") |
| | | |
| | | class UserlandManifestChecker(base.ManifestChecker): |
| | | """An opensolaris.org-specific class to check manifests.""" |
| | | |
| | | name = "userland.manifest" |
| | | |
| | | def __init__(self, config): |
| | | super(UserlandManifestChecker, self).__init__(config) |
| | | def __init__(self, config): |
| | | super(UserlandManifestChecker, self).__init__(config) |
| | | |
| | | def forbidden_publisher(self, manifest, engine, pkglint_id="1001"): |
| | | if not os.environ.get("ENCUMBERED"): |
| | | for action in manifest.gen_actions_by_type("depend"): |
| | | for f in action.attrlist("fmri"): |
| | | pkg_name=pkg.fmri.PkgFmri(f).pkg_name |
| | | info_needed = pkg.client.api.PackageInfo.ALL_OPTIONS - \ |
| | | (pkg.client.api.PackageInfo.ACTION_OPTIONS | |
| | | frozenset([pkg.client.api.PackageInfo.LICENSES])) |
| | | progtracker = pkg.client.progress.NullProgressTracker() |
| | | interface=pkg.client.api.ImageInterface("/", pkg.client.api.CURRENT_API_VERSION, progtracker, lambda x: False, None,None) |
| | | ret = interface.info([pkg_name],True,info_needed) |
| | | if ret[pkg.client.api.ImageInterface.INFO_FOUND]: |
| | | allowed_pubs = engine.get_param("%s.allowed_pubs" % self.name).split(" ") + ["openindiana.org","on-nightly"] |
| | | for i in ret[pkg.client.api.ImageInterface.INFO_FOUND]: |
| | | if i.publisher not in allowed_pubs: |
| | | engine.error(_("package %(pkg)s depends on %(name)s, which comes from forbidden publisher %(publisher)s") % |
| | | {"pkg":manifest.fmri,"name":pkg_name,"publisher":i.publisher}, msgid="%s%s.1" % (self.name, pkglint_id)) |
| | | def forbidden_publisher(self, manifest, engine, pkglint_id="1001"): |
| | | if not os.environ.get("ENCUMBERED"): |
| | | for action in manifest.gen_actions_by_type("depend"): |
| | | for f in action.attrlist("fmri"): |
| | | pkg_name=pkg.fmri.PkgFmri(f).pkg_name |
| | | info_needed = pkg.client.api.PackageInfo.ALL_OPTIONS - \ |
| | | (pkg.client.api.PackageInfo.ACTION_OPTIONS | |
| | | frozenset([pkg.client.api.PackageInfo.LICENSES])) |
| | | progtracker = pkg.client.progress.NullProgressTracker() |
| | | interface=pkg.client.api.ImageInterface("/", pkg.client.api.CURRENT_API_VERSION, progtracker, lambda x: False, None,None) |
| | | ret = interface.info([pkg_name],True,info_needed) |
| | | if ret[pkg.client.api.ImageInterface.INFO_FOUND]: |
| | | allowed_pubs = engine.get_param("%s.allowed_pubs" % self.name).split(" ") + ["openindiana.org","on-nightly"] |
| | | for i in ret[pkg.client.api.ImageInterface.INFO_FOUND]: |
| | | if i.publisher not in allowed_pubs: |
| | | engine.error(_("package %(pkg)s depends on %(name)s, which comes from forbidden publisher %(publisher)s") % |
| | | {"pkg":manifest.fmri,"name":pkg_name,"publisher":i.publisher}, msgid="%s%s.1" % (self.name, pkglint_id)) |
| | | |
| | | forbidden_publisher.pkglint_desc = _( |
| | | "Dependencies should come from standard publishers" ) |
| | | forbidden_publisher.pkglint_desc = _( |
| | | "Dependencies should come from standard publishers" ) |
| | | |
| | | def component_check(self, manifest, engine, pkglint_id="001"): |
| | | manifest_paths = [] |
| | | files = False |
| | | license = False |
| | | def component_check(self, manifest, engine, pkglint_id="001"): |
| | | manifest_paths = [] |
| | | files = False |
| | | license = False |
| | | |
| | | for action in manifest.gen_actions_by_type("file"): |
| | | files = True |
| | | break |
| | | for action in manifest.gen_actions_by_type("file"): |
| | | files = True |
| | | break |
| | | |
| | | if files == False: |
| | | return |
| | | if files == False: |
| | | return |
| | | |
| | | for action in manifest.gen_actions_by_type("license"): |
| | | if not action.attrs['license']: |
| | | engine.error( _("missing vaue for action license attribute 'license' like 'CDDL','MIT','GPL'..."), |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | else: |
| | | license = True |
| | | break |
| | | for action in manifest.gen_actions_by_type("license"): |
| | | if not action.attrs['license']: |
| | | engine.error( _("missing vaue for action license attribute 'license' like 'CDDL','MIT','GPL'..."), |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | else: |
| | | license = True |
| | | break |
| | | |
| | | if license == False: |
| | | engine.error( _("missing license action"), |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | if license == False: |
| | | engine.error( _("missing license action"), |
| | | msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | |
| | | # if 'org.opensolaris.arc-caseid' not in manifest: |
| | | # engine.error( _("missing ARC data (org.opensolaris.arc-caseid)"), |
| | | # msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | # if 'org.opensolaris.arc-caseid' not in manifest: |
| | | # engine.error( _("missing ARC data (org.opensolaris.arc-caseid)"), |
| | | # msgid="%s%s.0" % (self.name, pkglint_id)) |
| | | |
| | | component_check.pkglint_desc = _( |
| | | "license actions and ARC information are required if you deliver files.") |
| | | component_check.pkglint_desc = _( |
| | | "license actions and ARC information are required if you deliver files.") |
| | | |
| | | def publisher_in_fmri(self, manifest, engine, pkglint_id="002"): |
| | | allowed_pubs = engine.get_param( |
| | |
| | | manifest.fmri, |
| | | msgid="%s%s.2" % (self.name, pkglint_id)) |
| | | |
| | | publisher_in_fmri.pkglint_desc = _( |
| | | "extra publisher set" ) |
| | | publisher_in_fmri.pkglint_desc = _( |
| | | "extra publisher set" ) |