-
Notifications
You must be signed in to change notification settings - Fork 68
Distro Inconsistencies Framework #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5cb2526
228caa3
e295fef
7f6050b
0287e62
0fa8d9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -842,13 +842,13 @@ def _get_os_release_info(self): | |
| Returns: | ||
| A dictionary containing all information items. | ||
| """ | ||
| if os.path.isfile(self.os_release_file): | ||
| try: | ||
| with open(self.os_release_file) as release_file: | ||
| return self._parse_os_release_content(release_file) | ||
| return {} | ||
| except (OSError, IOError): | ||
| return {} | ||
|
|
||
| @staticmethod | ||
| def _parse_os_release_content(lines): | ||
| def _parse_os_release_content(self, lines): | ||
| """ | ||
| Parse the lines of an os-release file. | ||
|
|
||
|
|
@@ -898,7 +898,7 @@ def _parse_os_release_content(lines): | |
| codename = codename.strip('()') | ||
| codename = codename.strip(',') | ||
| codename = codename.strip() | ||
| # codename appears within paranthese. | ||
| # codename appears within parenthesis. | ||
| props['codename'] = codename | ||
| else: | ||
| props['codename'] = '' | ||
|
|
@@ -1074,7 +1074,71 @@ def _parse_distro_release_content(line): | |
| return distro_info | ||
|
|
||
|
|
||
| _distro = LinuxDistribution() | ||
| def _normalize_id(distro_id, table): | ||
| """ Helper function which normalizes a distro id value. """ | ||
| distro_id = distro_id.lower().replace(' ', '_') | ||
| return table.get(distro_id, distro_id) | ||
|
|
||
|
|
||
| class LinuxMintDistribution(LinuxDistribution): | ||
| """ LinuxMint will have the same /etc/os-release file | ||
| as it's upstream Ubuntu so we should not use any info | ||
| from that file except `ID_LIKE`. """ | ||
| def os_release_attr(self, attribute): | ||
| if attribute == 'id_like': | ||
| v = super(LinuxMintDistribution, self).os_release_attr(attribute) | ||
| return v | ||
| return '' | ||
|
|
||
|
|
||
| class CloudLinuxDistribution(LinuxDistribution): | ||
| def id(self): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if class CloudLinuxDistribution(LinuxDistribution):
id = 'cloudlinux'
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we changing
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm in favor of keeping
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, it should be canonical. yet, these are all constants.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They happen to be constants for I know we can just use the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's my point (not concerning a particular class, but in general) - all these values are constants during runtime, especially from the client code's perspective.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you're proposing caching the value? There's nothing wrong with a function returning something that is actually a constant. See the class of functions this library is aiming to replace:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i mean both: changing the design and as a side-effect to 'cache'. def _get_id():
…
ID = _get_id()
__all__ = ['ID']though i'd argue that no uppercase reads cleaner in the client code: @nir0s shall i open an issue regarding the design discussion? though i can't promise to layout a detailed proposal soon, i see the opportunity to introduce breaking changes with a new major release. sorry for bloating this up here.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is probably going to be a little trickier to test compared to our current model of doing things. Agree on keeping things lower-cased. |
||
| """ CloudLinux <7 doesn't provide an lsb-release or | ||
| os-release file, only a redhat-release file so it's id | ||
| is incorrectly detected as `rhel`. """ | ||
| return 'cloudlinux' | ||
|
|
||
|
|
||
| class DebianStretchDistribution(LinuxDistribution): | ||
| def _parse_os_release_content(self, lines): | ||
| """ Debian 9 (stretch) does not have the codename | ||
| in parenthesis or with a comma unlike all other | ||
| distributions. This stub """ | ||
| props = (super(DebianStretchDistribution, self). | ||
| _parse_os_release_content(lines)) | ||
| if 'codename' not in props and props.get('pretty_name', ''): | ||
| pretty_name = props['pretty_name'] | ||
|
|
||
| # Remove the NAME from the PRETTY_NAME entry to prevent getting | ||
| # a codename of 'GNU/Linux'. | ||
| pretty_name = pretty_name.replace(props.get('name', ''), '') | ||
|
|
||
| match = re.search(r'\s([^\s\d]+)$', pretty_name) | ||
| if match: | ||
| props['codename'] = match.group(1) | ||
| return props | ||
|
|
||
|
|
||
| def get_distribution(*args): | ||
| """ Gets the proper implementation of LinuxDistribution after attempting | ||
| to detect distro inconsistencies. Passes all args through to the resulting | ||
| LinuxDistribution object. """ | ||
| ld = LinuxDistribution(*args) | ||
| os_release_id = _normalize_id(ld.os_release_attr('id'), NORMALIZED_OS_ID) | ||
| lsb_release_id = _normalize_id(ld.lsb_release_attr('distributor_id'), | ||
| NORMALIZED_LSB_ID) | ||
|
|
||
| if os_release_id == 'ubuntu' and lsb_release_id == 'linuxmint': | ||
| return LinuxMintDistribution(*args) | ||
| elif ld.id() == 'rhel' and 'CloudLinux' in ld.name(): | ||
| return CloudLinuxDistribution(*args) | ||
| elif ld.id() == 'debian' and ld.codename() == '': | ||
| return DebianStretchDistribution(*args) | ||
| else: | ||
| return ld | ||
|
|
||
|
|
||
| _distro = get_distribution() | ||
|
|
||
|
|
||
| def main(): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| PRETTY_NAME="Debian GNU/Linux stretch/sid" | ||
| NAME="Debian GNU/Linux" | ||
| ID=debian | ||
| HOME_URL="https://www.debian.org/" | ||
| SUPPORT_URL="https://www.debian.org/support" | ||
| BUG_REPORT_URL="https://bugs.debian.org/" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| PRETTY_NAME="Debian GNU/Linux" | ||
| NAME="Debian GNU/Linux" | ||
| ID=debian | ||
| HOME_URL="https://www.debian.org/" | ||
| SUPPORT_URL="https://www.debian.org/support" | ||
| BUG_REPORT_URL="https://bugs.debian.org/" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for the symbol
vhere.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line length constraints. :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use a line-break in the return statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm aware, I just thought this looked better than this
or this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather
i actually don't know whether the current state would be optimized upon bytecode-compilation. if so, it doesn't matter anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would create a linting error because there is a hanging indent that has a multiple of 4 spaces that's not a code indent.
This type of thing isn't optimized away in byte-code, two extra codes for
STORE FASTandLOAD FASTbefore the return.