augeasproviders_grub
Version information
This version is compatible with:
- Puppet Enterprise 2023.8.x, 2023.7.x, 2023.6.x, 2023.5.x, 2023.4.x, 2023.3.x, 2023.2.x, 2023.1.x, 2023.0.x, 2021.7.x, 2021.6.x, 2021.5.x, 2021.4.x, 2021.3.x, 2021.2.x, 2021.1.x, 2021.0.x
- Puppet >= 7.0.0 < 9.0.0
- , , , , , ,
Start using this module
Add this module to your Puppetfile:
mod 'puppet-augeasproviders_grub', '5.1.2'
Learn more about managing modules with a PuppetfileDocumentation
grub: type/provider for grub files for Puppet
This module provides a new type/provider for Puppet to read and modify grub config files using the Augeas configuration library.
The advantage of using Augeas over the default Puppet parsedfile
implementations is that Augeas will go to great lengths to preserve file
formatting and comments, while also failing safely when needed.
This provider will hide all of the Augeas commands etc., you don't need to know anything about Augeas to make use of it.
Requirements
Ensure both Augeas and ruby-augeas 0.3.0+ bindings are installed and working as normal.
See Puppet/Augeas pre-requisites.
WARNING Your system must be able to run the grub mkconfig scripts with BLS support if you are on a systen that uses BLS!
Installing
On Puppet 2.7.14+, the module can be installed easily (documentation):
puppet module install puppet/augeasproviders_grub
You may see an error similar to this on Puppet 2.x (#13858):
Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error ArgumentError: Invalid resource type `kernel_parameter` at ...
Ensure the module is present in your puppetmaster's own environment (it doesn't
have to use it) and that the master has pluginsync enabled. Run the agent on
the puppetmaster to cause the custom types to be synced to its local libdir
(puppet master --configprint libdir
) and then restart the puppetmaster so it
loads them.
Compatibility
Puppet versions
Minimum of Puppet 2.7.
Augeas versions
Augeas Versions | 0.10.0 | 1.0.0 | 1.1.0 | 1.2.0 |
---|---|---|---|---|
PROVIDERS | ||||
kernel_parameter (grub) | yes | yes | yes | yes |
kernel_parameter (grub2) | yes | yes | yes | yes |
grub_config (grub) | yes | yes | yes | yes |
grub_config (grub2) | yes | yes | yes | yes |
grub_menuentry (grub) | yes | yes | yes | yes |
grub_menuentry (grub2) | N/A | N/A | N/A | N/A |
grub_user (grub2) | N/A | N/A | N/A | N/A |
Note: grub_menuentry and grub_user for GRUB2 do not use Augeas at this time due to lack of available lenses.
Documentation and examples
Type documentation can be generated with puppet doc -r type
or viewed on the
Puppet Forge page.
kernel_parameter provider
This is a custom type and provider supplied by augeasproviders
. It supports
both GRUB Legacy (0.9x) and GRUB 2 configurations.
manage parameter without value
kernel_parameter { "quiet":
ensure => present,
}
manage parameter with value
kernel_parameter { "elevator":
ensure => present,
value => "deadline",
}
manage parameter with multiple values
kernel_parameter { "rd_LVM_LV":
ensure => present,
value => ["vg/lvroot", "vg/lvvar"],
}
manage parameter on certain boot types
Bootmode defaults to "all", so settings are applied for all boot types usually.
Apply only to the default boot:
kernel_parameter { "quiet":
ensure => present,
bootmode => "default",
}
Apply only to normal boots. In GRUB legacy, normal boots consist of the default boot plus non-recovery ones. In GRUB2, normal bootmode is just an alias for default.
kernel_parameter { "quiet":
ensure => present,
bootmode => "normal",
}
Only recovery mode boots (unsupported with GRUB 2):
kernel_parameter { "quiet":
ensure => present,
bootmode => "recovery",
}
delete entry
kernel_parameter { "rhgb":
ensure => absent,
}
manage parameter in another config location
kernel_parameter { "elevator":
ensure => present,
value => "deadline",
target => "/mnt/boot/grub/menu.lst",
}
grub_config provider
This custom type manages GRUB Legacy and GRUB2 global configuration parameters.
In GRUB Legacy, the global items at the top of the grub.conf
file are managed.
In GRUB2, the parameters in /etc/defaults/grub
are managed.
When using GRUB2, take care that you aren't conflicting with an option later
specified by grub_menuentry
. Also, be aware that, in GRUB2, any global items
here will not be referenced unless you reference them by variable name per Bash
semantics.
change the default legacy GRUB timeout
This will set the timeout
global value in the Legacy GRUB configuration.
grub_config { 'timeout':
value => '1'
}
change the default GRUB2 timeout
This will set the GRUB_TIMEOUT
global value in the GRUB2 configuration.
grub_config { 'GRUB_TIMEOUT':
value => '1'
}
grub_menuentry provider
This is a custom type to manage GRUB Legacy and GRUB2 menu entries.
The GRUB Legacy provider utlizes Augeas under the hood but GRUB2 did not have an available Lens and was written in Ruby.
This will not allow for modifying dynamically generated system entries. You will need to remove some of the native GRUB2 configuration scripts to be fully independent of the default system values.
The GRUB2 output of this provider will be saved, by default, in
/etc/grub.d/05_puppet_managed_<random_string>
where the random_string
is a
hash of the resource name
.
new entry preserving all existing values
This will create a new menu entry and copy over any default values if present. If the entry currently exists, it will preserve all values and not overwrite them with the default system values.
grub_menuentry { 'new_entry':
root => '(hd0,0)',
kernel => ':preserve:',
initrd => ':preserve:',
kernel_options => [':preserve:']
}
kernel option lines
There are many methods for identifying and manipulating kernel option lines and so a method was developed for handling the most common scenarios. You can, of course, simply denote every option, but this is cumbersome and prone to error over time.
The following format is supported for the new options:
':defaults:' => Copy defaults from the default GRUB entry
':preserve:' => Preserve all existing options (if present)
Note: ':defaults:' and ':preserve:' are mutually exclusive.
All of the options below supersede any items affected by the above
'entry(=.*)?' => Ensure that `entry` exists *as entered*; replaces all
other options with the same name
'!:entry(=.*)?' => Add this option to the end of the arguments
preserving any other options of the same name
'-:entry' => Ensure that all instances of `entry` do not exist
'-:entry=foo' => Ensure that only instances of `entry` with value `foo` do not exist
Note: Option removals and additions have higher precedence than preservation
grub_user provider
This type manages GRUB2 users and superusers.
The output of this provider is stored, by default, in /etc/grub.d/01_puppet_managed_users
.
Any plain text passwords are automatically converted into the appropriate GRUB PBKDF2 format.
Note: If no users are defined as superusers, then GRUB2 will not enforce user restrictions on your entries.
user with a plain text password
grub_user { 'test_user':
password => 'plain text password'
}
user with a pre-hashed password
grub_user { 'test_user':
password => 'grub.pbkdf2.sha512.10000.REALLY_LONG_STRING'
}
user that is a superuser with a plain text password and 20000 rounds
grub_user { 'test_user':
password => 'plain text password',
superuser => true,
rounds => '20000'
}
Issues
Please file any issues or suggestions on GitHub.
Transfer Notice
This module was originally authored by hercules-team. The maintainer preferred that Vox Pupuli take ownership of the module for future improvement and maintenance. Existing pull requests and issues were transferred over, please fork and continue to contribute here.
Previously: https://github.com/hercules-team/augeasproviders_grub
Reference
Table of Contents
Resource types
grub_config
: Manages global GRUB configuration parametersgrub_menuentry
: Manages menu entries in the GRUB and GRUB2 systems. NOTE: This may not cover all possible options and some options may apply to eithergrub_user
: Manages GRUB2 Users - Does not apply to GRUB Legacy Note: This type compares against the active GRUB configuration. The contents of the makernel_parameter
: Manages kernel parameters stored in bootloaders.
Resource types
grub_config
Manages global GRUB configuration parameters
Properties
The following properties are available in the grub_config
type.
ensure
Valid values: present
, absent
The basic property that the resource should be in.
Default value: present
value
Value of the GRUB parameter.
Parameters
The following parameters are available in the grub_config
type.
name
namevar
The parameter that you wish to set.
GRUB < 2
In the case of GRUB < 2, this will be something like 'default', 'timeout', etc...
See info grub
for additional information.
GRUB >= 2
With GRUB >= 2, this will be 'GRUB_DEFAULT', 'GRUB_SAVEDEFAULT', etc..
See info grub2
for additional information.
provider
The specific backend to use for this grub_config
resource. You will seldom need to specify this --- Puppet will
usually discover the appropriate provider for your platform.
target
The bootloader configuration file, if in a non-default location for the provider.
grub_menuentry
Manages menu entries in the GRUB and GRUB2 systems.
NOTE: This may not cover all possible options and some options may apply to either GRUB or GRUB2!
Properties
The following properties are available in the grub_menuentry
type.
bls
Valid values: true
, false
Explicitly enable, or disable, BLS support for this resource.
Has on effect on systems that are not BLS enabled.
classes
Add this Array of classes to the menuentry.
default_entry
Valid values: true
, false
If set, make this menu entry the default entry.
If more than one of these is set to true
across all :menuentry
resources, this is an error.
In GRUB2, there is no real guarantee that this will stick since entries further down the line may have custom scripts which alter the default.
NOTE: You should not use this in conjunction with using the :grub_config type to set the system default.
ensure
Valid values: present
, absent
The basic property that the resource should be in.
Default value: present
initrd
Valid values: %r{^(/.*|:(default|preserve):)}
The path to the initrd image.
Set this to ':default:' to copy the default kernel initrd if one exists.
Set this to ':preserve:' to preserve the current entry. If a current entry does not exist, the default will be copied. If there is no default, this is an error.
kernel
Valid values: %r{^(/.*|:(default|preserve):)}
The path to the kernel that you wish to boot.
Set this to ':default:' to copy the default kernel if one exists.
Set this to ':preserve:' to preserve the current entry. If a current entry does not exist, the default will be copied. If there is no default, this is an error.
kernel_options
An array of kernel options to apply to the :kernel property.
The following format is supported for the new options: ':defaults:' => Copy defaults from the default GRUB entry ':preserve:' => Preserve all existing options (if present)
Note: ':defaults:' and ':preserve:' are mutually exclusive.
All of the options below supersede any items affected by the above
'entry(=.)?' => Ensure that entry
exists as entered; replaces all
other options with the same name
'!:entry(=.)?' => Add this option to the end of the arguments
preserving any other options of the same name
'-:entry' => Ensure that all instances of entry
do not exist
'-:entry=foo' => Ensure that only instances of entry
with value foo
do not exist
Note: Option removals and additions have higher precedence than preservation
Default value: :preserve:
load_16bit
Valid values: true
, false
If set, ensure that linux16
and initrd16
are used for the kernel entries.
Will default to true
unless the entry is a BLS entry.
load_video
Valid values: true
, false
If true, add the load_video
command to the menuentry.
Will default to true
unless the entry is a BLS entry.
makeactive
Valid values: true
, false
In Legacy GRUB, having this set will add a 'makeactive' entry to the menuentry.
Default value: false
modules
An Array of module entry Arrays that apply to the given entry. Since each Multiboot format boot image is unique, you must know what you wish to pass to the module lines.
The one exception to this is that many of the linux multiboot settings require the kernel and initrd to be passed to them. If you set the ':defaults:' value anywhere in the options array, the default kernel options will be copied to that location in the output.
The following format is supported for the new options: ':defaults:' => Copy default options from the default kernel GRUB entry ':preserve:' => Preserve all existing options (if present)
Note: ':defaults:' and ':preserve:' are mutually exclusive.
All of the options below supersede any items affected by the above
'entry(=.*)?' => Ensure that `entry` exists *as entered*; replaces all
other options with the same name
'!:entry(=.*)?' => Add this option to the end of the arguments
preserving any other options of the same name
'-:entry' => Ensure that all instances of `entry` do not exist
'-:entry=foo' => Ensure that only instances of `entry` with value `foo` do not exist
Note: Option removals and additions have higher precedence than preservation
Example: modules => [ ['/vmlinuz.1.2.3.4','ro'], ['/initrd.1.2.3.4'] ]
plugins
An Array of plugins that should be included in this menuentry.
Will default to ['gzio','part_msdos','xfs','ext2']
unless the entry is a BLS entry.
root
Valid values: %r{\(.*\)}
The filesystem root.
users
In GRUB2, having this set will add a requirement for the listed users to authenticate to the system in order to utilize the menu entry.
Default value: [:unrestricted]
Parameters
The following parameters are available in the grub_menuentry
type.
add_defaults_on_creation
Valid values: true
, false
, yes
, no
If set, when using the ':preserve:' option in kernel_options
or
modules
will add the system defaults if the entry is being first
created. This is the same technique that grub2-mkconfig uses when
procesing entries.
Default value: true
name
namevar
The name of the menu entry.
provider
The specific backend to use for this grub_menuentry
resource. You will seldom need to specify this --- Puppet will
usually discover the appropriate provider for your platform.
target
The bootloader configuration file, if in a non-default location for the provider.
grub_user
Manages GRUB2 Users - Does not apply to GRUB Legacy
Note: This type compares against the active GRUB configuration. The contents of the management file will not be updated unless the active configuration is out of sync with the expected configuration.
Properties
The following properties are available in the grub_user
type.
ensure
Valid values: present
, absent
The basic property that the resource should be in.
Default value: present
password
The user's password. If the password is not already in a GRUB2 compatible form, it will be automatically converted.
purge
Valid values: true
, false
Purge all unmanaged users.
This does not affect any users that are not defined by Puppet! There is no way to reliably eliminate the items from all other scripts without potentially severely damaging the GRUB2 build scripts.
Default value: false
Parameters
The following parameters are available in the grub_user
type.
name
namevar
The username of the GRUB2 user to be managed.
provider
The specific backend to use for this grub_user
resource. You will seldom need to specify this --- Puppet will usually
discover the appropriate provider for your platform.
report_unmanaged
Valid values: true
, false
Report any unmanaged users as a warning during the Puppet run.
Default value: false
rounds
Valid values: %r{^\d+$}
The rounds to use when hashing the password.
Default value: 10_000
superuser
Valid values: true
, false
If set, add this user to the 'superusers' list, if no superusers are set, but grub_user resources have been declared, a compile error will be raised.
Default value: false
target
The file to which to write the user information.
Must be an absolute path.
Default value: /etc/grub.d/02_puppet_managed_users
kernel_parameter
Manages kernel parameters stored in bootloaders.
Properties
The following properties are available in the kernel_parameter
type.
ensure
Valid values: present
, absent
The basic property that the resource should be in.
Default value: present
value
Value of the parameter if applicable. Many parameters are just keywords so this must be left blank, while others (e.g. 'vga') will take a value.
Parameters
The following parameters are available in the kernel_parameter
type.
bootmode
Valid values: all
, default
, normal
, recovery
Boot mode(s) to apply the parameter to. Either 'all' (default) to use the parameter on all boots (normal and recovery mode), 'default' for just the default boot entry, 'normal' for just normal boots or 'recovery' for just recovery boots.
Default value: all
name
namevar
The parameter name, e.g. 'quiet' or 'vga'.
provider
The specific backend to use for this kernel_parameter
resource. You will seldom need to specify this --- Puppet will
usually discover the appropriate provider for your platform.
target
The bootloader configuration file, if in a non-default location for the provider.
Changelog
All notable changes to this project will be documented in this file. Each new release typically also includes the latest modulesync defaults. These should not affect the functionality of the module.
v5.1.2 (2024-08-22)
Fixed bugs:
v5.1.1 (2024-07-09)
Fixed bugs:
- RHEL >= 9.3 -
grub2-mkconfig
does not update BLS kernel options anymore per default #95 - Update BLS kernel options on EL >= 9.3 #98 (silug)
v5.1.0 (2023-10-30)
Implemented enhancements:
- Add EL9 support #92 (bastelfreak)
- Add AlmaLinux/Rocky support #91 (bastelfreak)
- Add Ubuntu 22.04 support #90 (bastelfreak)
- Add Debian 12 support #89 (bastelfreak)
Merged pull requests:
v5.0.1 (2023-10-15)
Fixed bugs:
- v4.0.0: Standard error of
grub-mkconfig
written togrub.cfg
#74
Merged pull requests:
v5.0.0 (2023-06-22)
Breaking changes:
- Debian: Drop 9, add support for 10 & 11 #82 (bastelfreak)
- Drop Puppet 6 support #77 (bastelfreak)
Implemented enhancements:
- puppet/augeasproviders_core: Allow 4.x #80 (bastelfreak)
Merged pull requests:
- Add puppet 8 support #79 (bastelfreak)
- Add RHEL 9 to supported OS #76 (tuxmea)
- Fix broken Apache-2 license #73 (bastelfreak)
v4.0.0 (2022-07-29)
Breaking changes:
- Call grub2-mkconfig on all targets #57 (traylenator)
Fixed bugs:
- grub_menuentry resource fail if directory /boot/grub doe not exist #53
- grub.cfg isn't being properly updated on EFI systems running CentOS 7 #4
- Fix grub_menuentry issues #56 (trevor-vaughan)
Closed issues:
- The mkconfig update in #4 needs to be ported to the other providers #63
- kernel_parameters set incorrectly on CentOS 8 #58
- Typo in provider grub for custom type grub_menuentry #54
- Kernel_parameter subscribe executes on every run #41
- More informative error message for missing dependency #34
- Support for Puppet 4 #26
- Issue w/Puppet 2016.x #24
Merged pull requests:
- Update augeasproviders_core version #67 (sazzle2611)
- Fix mkconfig calls #64 (trevor-vaughan)
- error message improvement: specify that it's a missing module #61 (kenyon)
- Fix typo in grub_menuentry provider #55 (trevor-vaughan)
3.2.0 (2020-03-31)
Fixed bugs:
- grub_menuentry is broken in EL8 and Fedora 30+ #49
Closed issues:
- grub_config values with spaces cause augeas errors #44
- Absent GRUB_CMDLINE_LINUX_DEFAULT can result in duplicated kernel parameters. #38
- The grub2 system should update both the EFI and non-EFI configurations when triggered #37
Merged pull requests:
- Add BLS support to grub_menuentry #50 (trevor-vaughan)
- Fixed the EFI code for grub_config and grub_menuentry #48 (tparkercbn)
- Fix String value issues in grub_config #46 (trevor-vaughan)
- Puppet6 #42 (raphink)
3.1.0 (2019-02-28)
Closed issues:
- Hard dependency on grub2-tools on CentOS7 missing #20
Merged pull requests:
3.0.1 (2018-05-09)
Closed issues:
- EFI support for all oses, not only fedora #27
Merged pull requests:
- Grub2 grub_user fix #32 (trevor-vaughan)
- Update grub2.rb for EFI systems #29 (cohdjn)
3.0.0 (2017-08-29)
Closed issues:
- Unable to set/determine correct provider on Arch Linux #22
Merged pull requests:
- Add Global EFI support #28 (trevor-vaughan)
- Raise exception on missing augeasproviders_core #25 (igalic)
2.4.0 (2016-05-03)
Implemented enhancements:
- Requesting support for grub 'module' statements #10
- Confine GRUB providers to presence of menus, prefer GRUB 2 #8 (ckoenig)
Closed issues:
- Fails on CentOS 6 #6
Merged pull requests:
- Update grub2.rb to add On UEFI Systems, grub.cfg #21 (stivesso)
- Updated the Changelog #19 (trevor-vaughan)
- Added support for global GRUB configuration #18 (trevor-vaughan)
2.3.0 (2016-02-18)
Closed issues:
- wrong version of grub detection on Ubuntu Trusty #13
- Grub2 does not add the /files/etc/default/grub/GRUB_CMDLINE_LINUX_DEFAULT path if it is missing #11
Merged pull requests:
- adding 2 defaults for grub 2 #17 (wanix)
- add grub.cfg location for grub2 on UEFI systems #16 (tedwardia)
- Fix GRUB_CMDLINE_LINUX_DEFAULT #14 (trevor-vaughan)
2.2.0 (2016-01-04)
2.1.0 (2015-11-17)
Closed issues:
Merged pull requests:
2.0.1 (2014-12-10)
Closed issues:
- Undefined method "provider" on Centos 6.5 #2
2.0.0 (2014-08-11)
* This Changelog was automatically generated by github_changelog_generator
Dependencies
- puppet/augeasproviders_core (>=2.4.0 < 5.0.0)
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.