diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1173a44..cf6824c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,69 +1,69 @@ name: "release" on: push: branches: - 'release' jobs: LitmusAcceptancePuppet5: env: HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6 HONEYCOMB_DATASET: litmus tests runs-on: self-hosted strategy: matrix: ruby_version: [2.5.x] puppet_gem_version: [~> 6.0] platform: [release_checks_5] agent_family: ['puppet5'] steps: - uses: actions/checkout@v1 - name: Litmus Parallel - uses: puppetlabs/action-litmus_parallel@master + uses: puppetlabs/action-litmus_parallel@main with: platform: ${{ matrix.platform }} agent_family: ${{ matrix.agent_family }} LitmusAcceptancePuppet6: env: HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6 HONEYCOMB_DATASET: litmus tests runs-on: self-hosted strategy: matrix: ruby_version: [2.5.x] puppet_gem_version: [~> 6.0] platform: [release_checks_6] agent_family: ['puppet6'] steps: - uses: actions/checkout@v1 - name: Litmus Parallel - uses: puppetlabs/action-litmus_parallel@master + uses: puppetlabs/action-litmus_parallel@main with: platform: ${{ matrix.platform }} agent_family: ${{ matrix.agent_family }} Spec: runs-on: self-hosted strategy: matrix: check: [parallel_spec, 'syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop'] ruby_version: [2.5.x] puppet_gem_version: [~> 5.0, ~> 6.0] exclude: - puppet_gem_version: ~> 5.0 check: 'syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop' - ruby_version: 2.5.x puppet_gem_version: ~> 5.0 steps: - uses: actions/checkout@v1 - name: Spec Tests - uses: puppetlabs/action-litmus_spec@master + uses: puppetlabs/action-litmus_spec@main with: puppet_gem_versionm: ${{ matrix.puppet_gem_version }} check: ${{ matrix.check }} diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index afc1f70..2616a60 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -1,64 +1,64 @@ name: "weekly" on: schedule: - cron: '0 5 * * 6' jobs: LitmusAcceptancePuppet5: env: HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6 HONEYCOMB_DATASET: litmus tests runs-on: self-hosted strategy: matrix: ruby_version: [2.5.x] puppet_gem_version: [~> 6.0] platform: [release_checks_5] agent_family: ['puppet5'] steps: - uses: actions/checkout@v1 - name: Litmus Parallel - uses: puppetlabs/action-litmus_parallel@master + uses: puppetlabs/action-litmus_parallel@main with: platform: ${{ matrix.platform }} agent_family: ${{ matrix.agent_family }} LitmusAcceptancePuppet6: env: HONEYCOMB_WRITEKEY: 7f3c63a70eecc61d635917de46bea4e6 HONEYCOMB_DATASET: litmus tests runs-on: self-hosted strategy: matrix: ruby_version: [2.5.x] puppet_gem_version: [~> 6.0] platform: [release_checks_6] agent_family: ['puppet6'] steps: - uses: actions/checkout@v1 - name: Litmus Parallel - uses: puppetlabs/action-litmus_parallel@master + uses: puppetlabs/action-litmus_parallel@main with: platform: ${{ matrix.platform }} agent_family: ${{ matrix.agent_family }} Spec: runs-on: self-hosted strategy: matrix: check: [parallel_spec, 'syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop'] ruby_version: [2.5.x] puppet_gem_version: [~> 5.0, ~> 6.0] exclude: - puppet_gem_version: ~> 5.0 check: 'syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop' - ruby_version: 2.5.x puppet_gem_version: ~> 5.0 steps: - uses: actions/checkout@v1 - name: Spec Tests - uses: puppetlabs/action-litmus_spec@master + uses: puppetlabs/action-litmus_spec@main with: puppet_gem_version: ${{ matrix.puppet_gem_version }} check: ${{ matrix.check }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a9fb3a..9c171f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,271 +1,271 @@ # Contributing to Puppet modules So you want to contribute to a Puppet module: Great! Below are some instructions to get you started doing that very thing while setting expectations around code quality as well as a few tips for making the process as easy as possible. ### Table of Contents 1. [Getting Started](#getting-started) 1. [Commit Checklist](#commit-checklist) 1. [Submission](#submission) 1. [More about commits](#more-about-commits) 1. [Testing](#testing) - [Running Tests](#running-tests) - [Writing Tests](#writing-tests) 1. [Get Help](#get-help) ## Getting Started - Fork the module repository on GitHub and clone to your workspace - Make your changes! ## Commit Checklist ### The Basics - [x] my commit is a single logical unit of work - [x] I have checked for unnecessary whitespace with "git diff --check" - [x] my commit does not include commented out code or unneeded files ### The Content - [x] my commit includes tests for the bug I fixed or feature I added - [x] my commit includes appropriate documentation changes if it is introducing a new feature or changing existing functionality - [x] my code passes existing test suites ### The Commit Message - [x] the first line of my commit message includes: - [x] an issue number (if applicable), e.g. "(MODULES-xxxx) This is the first line" - [x] a short description (50 characters is the soft limit, excluding ticket number(s)) - [x] the body of my commit message: - [x] is meaningful - [x] uses the imperative, present tense: "change", not "changed" or "changes" - [x] includes motivation for the change, and contrasts its implementation with the previous behavior ## Submission ### Pre-requisites - Make sure you have a [GitHub account](https://github.com/join) - [Create a ticket](https://tickets.puppet.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppet.com/browse/) you are patching for. ### Push and PR - Push your changes to your fork - [Open a Pull Request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) against the repository in the puppetlabs organization ## More about commits 1. Make separate commits for logically separate changes. Please break your commits down into logically consistent units which include new or changed tests relevant to the rest of the change. The goal of doing this is to make the diff easier to read for whoever is reviewing your code. In general, the easier your diff is to read, the more likely someone will be happy to review it and get it into the code base. If you are going to refactor a piece of code, please do so as a separate commit from your feature or bug fix changes. We also really appreciate changes that include tests to make sure the bug is not re-introduced, and that the feature is not accidentally broken. Describe the technical detail of the change(s). If your description starts to get too long, that is a good sign that you probably need to split up your commit into more finely grained pieces. Commits which plainly describe the things which help reviewers check the patch and future developers understand the code are much more likely to be merged in with a minimum of bike-shedding or requested changes. Ideally, the commit message would include information, and be in a form suitable for inclusion in the release notes for the version of Puppet that includes them. Please also check that you are not introducing any trailing whitespace or other "whitespace errors". You can do this by running "git diff --check" on your changes before you commit. 2. Sending your patches To submit your changes via a GitHub pull request, we _highly_ recommend that you have them on a topic branch, instead of - directly on "master". + directly on "main". It makes things much easier to keep track of, especially if you decide to work on another thing before your first change is merged in. GitHub has some pretty good [general documentation](http://help.github.com/) on using their site. They also have documentation on [creating pull requests](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). In general, after pushing your topic branch up to your repository on GitHub, you can switch to the branch in the GitHub UI and click "Pull Request" towards the top of the page in order to open a pull request. 3. Update the related JIRA issue. If there is a JIRA issue associated with the change you submitted, then you should update the ticket to include the location of your branch, along with any other commentary you may wish to make. # Testing ## Getting Started Our Puppet modules provide [`Gemfile`](./Gemfile)s, which can tell a Ruby package manager such as [bundler](http://bundler.io/) what Ruby packages, or Gems, are required to build, develop, and test this software. Please make sure you have [bundler installed](http://bundler.io/#getting-started) on your system, and then use it to install all dependencies needed for this project in the project root by running ```shell % bundle install --path .bundle/gems Fetching gem metadata from https://rubygems.org/........ Fetching gem metadata from https://rubygems.org/.. Using rake (10.1.0) Using builder (3.2.2) -- 8><-- many more --><8 -- Using rspec-system-puppet (2.2.0) Using serverspec (0.6.3) Using rspec-system-serverspec (1.0.0) Using bundler (1.3.5) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. ``` NOTE: some systems may require you to run this command with sudo. If you already have those gems installed, make sure they are up-to-date: ```shell % bundle update ``` ## Running Tests With all dependencies in place and up-to-date, run the tests: ### Unit Tests ```shell % bundle exec rake spec ``` This executes all the [rspec tests](http://rspec-puppet.com/) in the directories defined [here](https://github.com/puppetlabs/puppetlabs_spec_helper/blob/699d9fbca1d2489bff1736bb254bb7b7edb32c74/lib/puppetlabs_spec_helper/rake_tasks.rb#L17) and so on. rspec tests may have the same kind of dependencies as the module they are testing. Although the module defines these dependencies in its [metadata.json](./metadata.json), rspec tests define them in [.fixtures.yml](./fixtures.yml). ### Acceptance Tests Some Puppet modules also come with acceptance tests, which use [beaker][]. These tests spin up a virtual machine under [VirtualBox](https://www.virtualbox.org/), controlled with [Vagrant](http://www.vagrantup.com/), to simulate scripted test scenarios. In order to run these, you need both Virtualbox and Vagrant installed on your system. Run the tests by issuing the following command ```shell % bundle exec rake spec_clean % bundle exec rspec spec/acceptance ``` This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml), install Puppet, copy this module, and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb) and then run all the tests under [spec/acceptance](./spec/acceptance). ## Writing Tests ### Unit Tests When writing unit tests for Puppet, [rspec-puppet][] is your best friend. It provides tons of helper methods for testing your manifests against a catalog (e.g. contain_file, contain_package, with_params, etc). It would be ridiculous to try and top rspec-puppet's [documentation][rspec-puppet_docs] but here's a tiny sample: Sample manifest: ```puppet file { "a test file": ensure => present, path => "/etc/sample", } ``` Sample test: ```ruby it 'does a thing' do expect(subject).to contain_file("a test file").with({:path => "/etc/sample"}) end ``` ### Acceptance Tests Writing acceptance tests for Puppet involves [beaker][] and its cousin [beaker-rspec][]. A common pattern for acceptance tests is to create a test manifest, apply it twice to check for idempotency or errors, then run expectations. ```ruby it 'does an end-to-end thing' do pp = <<-EOF file { 'a test file': ensure => present, path => "/etc/sample", content => "test string", } apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_changes => true) end describe file("/etc/sample") do it { is_expected.to contain "test string" } end ``` # If you have commit access to the repository Even if you have commit access to the repository, you still need to go through the process above, and have someone else review and merge in your changes. The rule is that **all changes must be reviewed by a project developer that did not write the code to ensure that all changes go through a code review process.** The record of someone performing the merge is the record that they performed the code review. Again, this should be someone other than the author of the topic branch. # Get Help ### On the web * [Puppet help messageboard](http://puppet.com/community/get-help) * [Writing tests](https://docs.puppet.com/guides/module_guides/bgtm.html#step-three-module-testing) * [General GitHub documentation](http://help.github.com/) * [GitHub pull request documentation](http://help.github.com/send-pull-requests/) ### On chat * Slack (slack.puppet.com) #forge-modules, #puppet-dev, #windows, #voxpupuli * IRC (freenode) #puppet-dev, #voxpupuli [rspec-puppet]: http://rspec-puppet.com/ [rspec-puppet_docs]: http://rspec-puppet.com/documentation/ [beaker]: https://github.com/puppetlabs/beaker [beaker-rspec]: https://github.com/puppetlabs/beaker-rspec diff --git a/README.md b/README.md index b6264b2..bf25076 100644 --- a/README.md +++ b/README.md @@ -1,646 +1,646 @@ # mysql #### Table of Contents 1. [Module Description - What the module does and why it is useful](#module-description) 2. [Setup - The basics of getting started with mysql](#setup) * [Beginning with mysql](#beginning-with-mysql) 3. [Usage - Configuration options and additional functionality](#usage) * [Customize server options](#customize-server-options) * [Create a database](#create-a-database) * [Customize configuration](#customize-configuration) * [Work with an existing server](#work-with-an-existing-server) * [Specify passwords](#specify-passwords) * [Install Percona server on CentOS](#install-percona-server-on-centos) * [Install MariaDB on Ubuntu](#install-mariadb-on-ubuntu) * [Install Plugins](#install-plugins) * [Use Percona XtraBackup](#use-percona-xtrabackup) 4. [Reference - An under-the-hood peek at what the module is doing and how](REFERENCE.md) 5. [Limitations - OS compatibility, etc.](#limitations) 6. [Development - Guide for contributing to the module](#development) ## Module Description The mysql module installs, configures, and manages the MySQL service. This module manages both the installation and configuration of MySQL, as well as extending Puppet to allow management of MySQL resources, such as databases, users, and grants. ## Setup ### Beginning with mysql To install a server with the default options: `include '::mysql::server'`. To customize options, such as the root password or `/etc/my.cnf` settings, you must also pass in an override hash: ```puppet class { '::mysql::server': root_password => 'strongpassword', remove_default_accounts => true, restart => true, override_options => $override_options } ``` Nota bene: Configuration changes will only be applied to the running MySQL server if you pass true as restart to mysql::server. See [**Customize Server Options**](#customize-server-options) below for examples of the hash structure for $override_options. ## Usage All interaction for the server is done via `mysql::server`. To install the client, use `mysql::client`. To install bindings, use `mysql::bindings`. ### Customize server options To define server options, structure a hash structure of overrides in `mysql::server`. This hash resembles a hash in the my.cnf file: ```puppet $override_options = { 'section' => { 'item' => 'thing', } } ``` For options that you would traditionally represent in this format: ``` [section] thing = X ``` Entries can be created as `thing => true`, `thing => value`, or `thing => ""` in the hash. Alternatively, you can pass an array as `thing => ['value', 'value2']` or list each `thing => value` separately on individual lines. You can pass a variable in the hash without setting a value for it; the variable would then use MySQL's default settings. To exclude an option from the `my.cnf` file --- for example, when using `override_options` to revert to a default value --- pass `thing => undef`. If an option needs multiple instances, pass an array. For example, ```puppet $override_options = { 'mysqld' => { 'replicate-do-db' => ['base1', 'base2'], } } ``` produces ```puppet [mysqld] replicate-do-db = base1 replicate-do-db = base2 ``` To implement version specific parameters, specify the version, such as [mysqld-5.5]. This allows one config for different versions of MySQL. If you don’t want to use the default configuration, you can also supply your options to the `$options` parameter instead of `$override_options`. Please note that `$options` and `$override_options` are mutually exclusive, you can only use one of them. ### Create a database To create a database with a user and some assigned privileges: ```puppet mysql::db { 'mydb': user => 'myuser', password => 'mypass', host => 'localhost', grant => ['SELECT', 'UPDATE'], } ``` To use a different resource name with exported resources: ```puppet @@mysql::db { "mydb_${fqdn}": user => 'myuser', password => 'mypass', dbname => 'mydb', host => ${fqdn}, grant => ['SELECT', 'UPDATE'], tag => $domain, } ``` Then you can collect it on the remote DB server: ```puppet Mysql::Db <<| tag == $domain |>> ``` If you set the sql parameter to a file when creating a database, the file is imported into the new database. For large sql files, increase the `import_timeout` parameter, which defaults to 300 seconds. If you have installed the mysql client in a non standard bin/sbin path you can set this with `mysql_exec_path` . ```puppet mysql::db { 'mydb': user => 'myuser', password => 'mypass', host => 'localhost', grant => ['SELECT', 'UPDATE'], sql => '/path/to/sqlfile.gz', import_cat_cmd => 'zcat', import_timeout => 900, mysql_exec_path => '/opt/rh/rh-myql57/root/bin' } ``` ### Customize configuration To add custom MySQL configuration, place additional files into `includedir`. This allows you to override settings or add additional ones, which is helpful if you don't use `override_options` in `mysql::server`. The `includedir` location is by default set to `/etc/mysql/conf.d`. ### Work with an existing server To instantiate databases and users on an existing MySQL server, you need a `.my.cnf` file in `root`'s home directory. This file must specify the remote server address and credentials. For example: ```puppet [client] user=root host=localhost password=secret ``` This module uses the `mysqld_version` fact to discover the server version being used. By default, this is set to the output of `mysqld -V`. If you're working with a remote MySQL server, you may need to set a custom fact for `mysqld_version` to ensure correct behaviour. When working with a remote server, do *not* use the `mysql::server` class in your Puppet manifests. ### Specify passwords In addition to passing passwords as plain text, you can input them as hashes. For example: ```puppet mysql::db { 'mydb': user => 'myuser', password => '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4', host => 'localhost', grant => ['SELECT', 'UPDATE'], } ``` If required, the password can also be an empty string to allow connections without an password. ### Create login paths This feature works only for the MySQL Community Edition >= 5.6.6. A login path is a set of options (host, user, password, port and socket) that specify which MySQL server to connect to and which account to authenticate as. The authentication credentials and the other options are stored in an encrypted login file named .mylogin.cnf typically under the users home directory. More information about MySQL login paths: https://dev.mysql.com/doc/refman/8.0/en/mysql-config-editor.html. Some example for login paths: ```puppet mysql_login_path { 'client': owner => root, host => 'localhost', user => 'root', password => Sensitive('secure'), socket => '/var/run/mysqld/mysqld.sock', ensure => present, } mysql_login_path { 'remote_db': owner => root, host => '10.0.0.1', user => 'network', password => Sensitive('secure'), port => 3306, ensure => present, } ``` See examples/mysql_login_path.pp for further examples. ### Install Percona server on CentOS This example shows how to do a minimal installation of a Percona server on a CentOS system. This sets up the Percona server, client, and bindings (including Perl and Python bindings). You can customize this usage and update the version as needed. This usage has been tested on Puppet 4.4, 5.5 and 6.3.0 / CentOS 7 / Percona Server 5.7. **Note:** The installation of the yum repository is not part of this package and is here only to show a full example of how you can install. ```puppet yumrepo { 'percona': descr => 'CentOS $releasever - Percona', baseurl => 'http://repo.percona.com/percona/yum/release/$releasever/RPMS/$basearch', gpgkey => 'https://repo.percona.com/yum/PERCONA-PACKAGING-KEY', enabled => 1, gpgcheck => 1, } class {'mysql::server': package_name => 'Percona-Server-server-57', service_name => 'mysql', config_file => '/etc/my.cnf', includedir => '/etc/my.cnf.d', root_password => 'PutYourOwnPwdHere', override_options => { mysqld => { log-error => '/var/log/mysqld.log', pid-file => '/var/run/mysqld/mysqld.pid', }, mysqld_safe => { log-error => '/var/log/mysqld.log', }, } } # Note: Installing Percona-Server-server-57 also installs Percona-Server-client-57. # This shows how to install the Percona MySQL client on its own class {'mysql::client': package_name => 'Percona-Server-client-57' } # These packages are normally installed along with Percona-Server-server-57 # If you needed to install the bindings, however, you could do so with this code class { 'mysql::bindings': client_dev_package_name => 'Percona-Server-shared-57', client_dev => true, daemon_dev_package_name => 'Percona-Server-devel-57', daemon_dev => true, perl_enable => true, perl_package_name => 'perl-DBD-MySQL', python_enable => true, python_package_name => 'MySQL-python', } # Dependencies definition Yumrepo['percona']-> Class['mysql::server'] Yumrepo['percona']-> Class['mysql::client'] Yumrepo['percona']-> Class['mysql::bindings'] ``` ### Install MariaDB on Ubuntu #### Optional: Install the MariaDB official repo In this example, we'll use the latest stable (currently 10.3) from the official MariaDB repository, not the one from the distro repository. You could instead use the package from the Ubuntu repository. Make sure you use the repository corresponding to the version you want. **Note:** `sfo1.mirrors.digitalocean.com` is one of many mirrors available. You can use any official mirror. ```puppet include apt apt::source { 'mariadb': location => 'http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu', release => $::lsbdistcodename, repos => 'main', key => { id => '177F4010FE56CA3336300305F1656F24C74CD1D8', server => 'hkp://keyserver.ubuntu.com:80', }, include => { src => false, deb => true, }, } ``` #### Install the MariaDB server This example shows MariaDB server installation on Ubuntu Xenial. Adjust the version and the parameters of `my.cnf` as needed. All parameters of the `my.cnf` can be defined using the `override_options` parameter. The folders `/var/log/mysql` and `/var/run/mysqld` are created automatically, but if you are using other custom folders, they should exist as prerequisites for this code. All the values set here are an example of a working minimal configuration. Specify the version of the package you want with the `package_ensure` parameter. ```puppet class {'::mysql::server': package_name => 'mariadb-server', package_ensure => '1:10.3.21+maria~xenial', service_name => 'mysqld', root_password => 'AVeryStrongPasswordUShouldEncrypt!', override_options => { mysqld => { 'log-error' => '/var/log/mysql/mariadb.log', 'pid-file' => '/var/run/mysqld/mysqld.pid', }, mysqld_safe => { 'log-error' => '/var/log/mysql/mariadb.log', }, } } # Dependency management. Only use that part if you are installing the repository # as shown in the Preliminary step of this example. Apt::Source['mariadb'] ~> Class['apt::update'] -> Class['::mysql::server'] ``` #### Install the MariaDB client This example shows how to install the MariaDB client and all of the bindings at once. You can do this installation separately from the server installation. Specify the version of the package you want with the `package_ensure` parameter. ```puppet class {'::mysql::client': package_name => 'mariadb-client', package_ensure => '1:10.3.21+maria~xenial', bindings_enable => true, } # Dependency management. Only use that part if you are installing the repository as shown in the Preliminary step of this example. Apt::Source['mariadb'] ~> Class['apt::update'] -> Class['::mysql::client'] ``` ### Install MySQL Community server on CentOS You can install MySQL Community Server on CentOS using the mysql module and Hiera. This example was tested with the following versions: * MySQL Community Server 5.6 * Centos 7.3 * Puppet 3.8.7 using Hiera * puppetlabs-mysql module v3.9.0 In Puppet: ```puppet include ::mysql::server create_resources(yumrepo, hiera('yumrepo', {})) Yumrepo['repo.mysql.com'] -> Anchor['mysql::server::start'] Yumrepo['repo.mysql.com'] -> Package['mysql_client'] create_resources(mysql::db, hiera('mysql::server::db', {})) ``` In Hiera: ```yaml --- # Centos 7.3 yumrepo: 'repo.mysql.com': baseurl: "http://repo.mysql.com/yum/mysql-5.6-community/el/%{::operatingsystemmajrelease}/$basearch/" descr: 'repo.mysql.com' enabled: 1 gpgcheck: true gpgkey: 'http://repo.mysql.com/RPM-GPG-KEY-mysql' mysql::client::package_name: "mysql-community-client" # required for proper MySQL installation mysql::server::package_name: "mysql-community-server" # required for proper MySQL installation mysql::server::package_ensure: 'installed' # do not specify version here, unfortunately yum fails with error that package is already installed mysql::server::root_password: "change_me_i_am_insecure" mysql::server::manage_config_file: true mysql::server::service_name: 'mysqld' # required for puppet module mysql::server::override_options: 'mysqld': 'bind-address': '127.0.0.1' 'log-error': '/var/log/mysqld.log' # required for proper MySQL installation 'mysqld_safe': 'log-error': '/var/log/mysqld.log' # required for proper MySQL installation # create database + account with access, passwords are not encrypted mysql::server::db: "dev": user: "dev" password: "devpass" host: "127.0.0.1" grant: - "ALL" ``` ### Install Plugins Plugins can be installed by using the `mysql_plugin` defined type. See `examples/mysql_plugin.pp` for futher examples. ### Use Percona XtraBackup This example shows how to configure MySQL backups with Percona XtraBackup. This sets up a weekly cronjob to perform a full backup and additional daily cronjobs for incremental backups. Each backup will create a new directory. A cleanup job will automatically remove backups that are older than 15 days. ```puppet yumrepo { 'percona': descr => 'CentOS $releasever - Percona', baseurl => 'http://repo.percona.com/release/$releasever/RPMS/$basearch', gpgkey => 'https://www.percona.com/downloads/RPM-GPG-KEY-percona https://repo.percona.com/yum/PERCONA-PACKAGING-KEY', enabled => 1, gpgcheck => 1, } class { 'mysql::server::backup': backupuser => 'myuser', backuppassword => 'mypassword', backupdir => '/tmp/backups', provider => 'xtrabackup', backuprotate => 15, execpath => '/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin', time => ['23', '15'], } ``` If the daily or weekly backup was successful, then the empty file `/tmp/mysqlbackup_success` is created, which makes it easy to monitor the status of the database backup. After two weeks the backup directory should look similar to the example below. ``` /tmp/backups/2019-11-10_full /tmp/backups/2019-11-11_23-15-01 /tmp/backups/2019-11-13_23-15-01 /tmp/backups/2019-11-13_23-15-02 /tmp/backups/2019-11-14_23-15-01 /tmp/backups/2019-11-15_23-15-02 /tmp/backups/2019-11-16_23-15-01 /tmp/backups/2019-11-17_full /tmp/backups/2019-11-18_23-15-01 /tmp/backups/2019-11-19_23-15-01 /tmp/backups/2019-11-20_23-15-02 /tmp/backups/2019-11-21_23-15-01 /tmp/backups/2019-11-22_23-15-02 /tmp/backups/2019-11-23_23-15-01 ``` A drawback of using incremental backups is the need to keep at least 7 days of backups, otherwise the full backups is removed early and consecutive incremental backups will fail. Furthermore an incremental backups becomes obsolete once the required full backup was removed. The next example uses XtraBackup with incremental backups disabled. In this case the daily cronjob will always perform a full backup. ```puppet class { 'mysql::server::backup': backupuser => 'myuser', backuppassword => 'mypassword', backupdir => '/tmp/backups', provider => 'xtrabackup', incremental_backups => false, backuprotate => 5, execpath => '/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin', time => ['23', '15'], } ``` ## Reference ### Classes #### Public classes * [`mysql::server`](#mysqlserver): Installs and configures MySQL. * [`mysql::server::monitor`](#mysqlservermonitor): Sets up a monitoring user. * [`mysql::server::mysqltuner`](#mysqlservermysqltuner): Installs MySQL tuner script. * [`mysql::server::backup`](#mysqlserverbackup): Sets up MySQL backups via cron. * [`mysql::bindings`](#mysqlbindings): Installs various MySQL language bindings. * [`mysql::client`](#mysqlclient): Installs MySQL client (for non-servers). #### Private classes * `mysql::server::install`: Installs packages. * `mysql::server::installdb`: Implements setup of mysqld data directory (e.g. /var/lib/mysql) * `mysql::server::config`: Configures MYSQL. * `mysql::server::service`: Manages service. * `mysql::server::account_security`: Deletes default MySQL accounts. * `mysql::server::root_password`: Sets MySQL root password. * `mysql::server::providers`: Creates users, grants, and databases. * `mysql::bindings::client_dev`: Installs MySQL client development package. * `mysql::bindings::daemon_dev`: Installs MySQL daemon development package. * `mysql::bindings::java`: Installs Java bindings. * `mysql::bindings::perl`: Installs Perl bindings. * `mysql::bindings::php`: Installs PHP bindings. * `mysql::bindings::python`: Installs Python bindings. * `mysql::bindings::ruby`: Installs Ruby bindings. * `mysql::client::install`: Installs MySQL client. * `mysql::backup::mysqldump`: Implements mysqldump backups. * `mysql::backup::mysqlbackup`: Implements backups with Oracle MySQL Enterprise Backup. * `mysql::backup::xtrabackup`: Implements backups with XtraBackup from Percona or Mariabackup. ### Parameters #### mysql::server ##### `create_root_user` Whether root user should be created. Valid values are `true`, `false`. Defaults to `true`. This is useful for a cluster setup with Galera. The root user has to be created only once. You can set this parameter true on one node and set it to false on the remaining nodes. ##### `create_root_my_cnf` Whether to create `/root/.my.cnf`. Valid values are `true`, `false`. Defaults to `true`. `create_root_my_cnf` allows creation of `/root/.my.cnf` independently of `create_root_user`. You can use this for a cluster setup with Galera where you want `/root/.my.cnf` to exist on all nodes. ##### `root_password` The MySQL root password. Puppet attempts to set the root password and update `/root/.my.cnf` with it. This is required if `create_root_user` or `create_root_my_cnf` are true. If `root_password` is 'UNSET', then `create_root_user` and `create_root_my_cnf` are assumed to be false --- that is, the MySQL root user and `/root/.my.cnf` are not created. Password changes are supported; however, the old password must be set in `/root/.my.cnf`. Effectively, Puppet uses the old password, configured in `/root/my.cnf`, to set the new password in MySQL, and then updates `/root/.my.cnf` with the new password. ##### `old_root_password` This parameter no longer does anything. It exists only for backwards compatibility. See the `root_password` parameter above for details on changing the root password. ##### `create_root_login_file` Whether to create `/root/.mylogin.cnf` when using mysql 5.6.6+. Valid values are `true`, `false`. Defaults to `false`. `create_root_login_file` will put a copy of your existing `.mylogin.cnf` in the `/root/.mylogin.cnf` location. When set to 'true', this option also requires the `login_file` option. The `login_file` option is required when set to true. #### `login_file` Whether to put the `/root/.mylogin.cnf` in place. You need to create the `.mylogin.cnf` file with `mysql_config_editor`, this tool comes with mysql 5.6.6+. The created .mylogin.cnf needs to be put under files in your module, see example below on how to use this. When the `/root/.mylogin.cnf` exists the environment variable `MYSQL_TEST_LOGIN_FILE` will be set. This is required if `create_root_user` and `create_root_login_file` are true. If `root_password` is 'UNSET', then `create_root_user` and `create_root_login_file` are assumed to be false --- that is, the MySQL root user and `/root/.mylogin.cnf` are not created. ```puppet class { '::mysql::server': root_password => 'password', create_root_my_cnf => false, create_root_login_file => true, login_file => "puppet:///modules/${module_name}/mylogin.cnf", } ``` ##### `override_options` Specifies override options to pass into MySQL. Structured like a hash in the my.cnf file: ```puppet class { 'mysql::server': root_password => 'password' } mysql_plugin { 'auth_pam': ensure => present, soname => 'auth_pam.so', } ``` ### Tasks The MySQL module has an example task that allows a user to execute arbitary SQL against a database. Please refer to to the [PE documentation](https://puppet.com/docs/pe/2017.3/orchestrator/running_tasks.html) or [Bolt documentation](https://puppet.com/docs/bolt/latest/bolt.html) on how to execute a task. ## Limitations -For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-mysql/blob/master/metadata.json) +For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-mysql/blob/main/metadata.json) **Note:** The mysqlbackup.sh does not work and is not supported on MySQL 5.7 and greater. ## Development We are experimenting with a new tool for running acceptance tests. Its name is [puppet_litmus](https://github.com/puppetlabs/puppet_litmus) this replaces beaker as the test runner. To run the acceptance tests follow the instructions from this point [here](https://github.com/puppetlabs/puppet_litmus/wiki/Tutorial:-use-Litmus-to-execute-acceptance-tests-with-a-sample-module-(MoTD)#install-the-necessary-gems-for-the-module). Puppet modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can't access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. Check out our the complete [module contribution guide](https://puppet.com/docs/puppet/latest/contributing.html). ### Authors This module is based on work by David Schmitt. The following contributors have contributed to this module (beyond Puppet Labs): * Larry Ludwig * Christian G. Warden * Daniel Black * Justin Ellison * Lowe Schmidt * Matthias Pigulla * William Van Hevelingen * Michael Arnold * Chris Weyl * Daniël van Eeden * Jan-Otto Kröpke * Timothy Sven Nelson * Andreas Stürz diff --git a/lib/puppet/provider/mysql_login_path/inifile.rb b/lib/puppet/provider/mysql_login_path/inifile.rb index d15632d..d556bd0 100644 --- a/lib/puppet/provider/mysql_login_path/inifile.rb +++ b/lib/puppet/provider/mysql_login_path/inifile.rb @@ -1,632 +1,632 @@ # encoding: UTF-8 -# See: https://github.com/puppetlabs/puppet/blob/master/lib/puppet/util/inifile.rb +# See: https://github.com/puppetlabs/puppet/blob/main/lib/puppet/util/inifile.rb # This class represents the INI file and can be used to parse, modify, # and write INI files. class Puppet::Provider::MysqlLoginPath::IniFile < Puppet::Provider include Enumerable class Error < StandardError; end # VERSION = '3.0.0' # Public: Open an INI file and load the contents. # # filename - The name of the file as a String # opts - The Hash of options (default: {}) # :comment - String containing the comment character(s) # :parameter - String used to separate parameter and value # :encoding - Encoding String for reading / writing # :default - The String name of the default global section # # Examples # # IniFile.load('file.ini') # #=> IniFile instance # # IniFile.load('does/not/exist.ini') # #=> nil # # Returns an IniFile instance or nil if the file could not be opened. def self.load(filename, opts = {}) return unless File.file? filename new(opts.merge(filename: filename)) end # Get and set the filename attr_accessor :filename # Get and set the encoding attr_accessor :encoding # Public: Create a new INI file from the given set of options. If :content # is provided then it will be used to populate the INI file. If a :filename # is provided then the contents of the file will be parsed and stored in the # INI file. If neither the :content or :filename is provided then an empty # INI file is created. # # opts - The Hash of options (default: {}) # :content - The String/Hash containing the INI contents # :comment - String containing the comment character(s) # :parameter - String used to separate parameter and value # :encoding - Encoding String for reading / writing # :default - The String name of the default global section # :filename - The filename as a String # # Examples # # IniFile.new # #=> an empty IniFile instance # # IniFile.new( :content => "[global]\nfoo=bar" ) # #=> an IniFile instance # # IniFile.new( :filename => 'file.ini', :encoding => 'UTF-8' ) # #=> an IniFile instance # # IniFile.new( :content => "[global]\nfoo=bar", :comment => '#' ) # #=> an IniFile instance # def initialize(opts = {}) @comment = opts.fetch(:comment, ';#') @param = opts.fetch(:parameter, '=') @encoding = opts.fetch(:encoding, nil) @default = opts.fetch(:default, 'global') @filename = opts.fetch(:filename, nil) content = opts.fetch(:content, nil) @ini = Hash.new { |h, k| h[k] = {} } if content.is_a?(Hash) then merge!(content) elsif content then parse(content) elsif @filename then read end end # Public: Write the contents of this IniFile to the file system. If left # unspecified, the currently configured filename and encoding will be used. # Otherwise the filename and encoding can be specified in the options hash. # # opts - The default options Hash # :filename - The filename as a String # :encoding - The encoding as a String # # Returns this IniFile instance. def write(opts = {}) filename = opts.fetch(:filename, @filename) encoding = opts.fetch(:encoding, @encoding) mode = encoding ? "w:#{encoding}" : 'w' File.open(filename, mode) do |f| @ini.each do |section, hash| f.puts "[#{section}]" hash.each { |param, val| f.puts "#{param} #{@param} #{escape_value val}" } f.puts end end self end alias save write # Public: Read the contents of the INI file from the file system and replace # and set the state of this IniFile instance. If left unspecified the # currently configured filename and encoding will be used when reading from # the file system. Otherwise the filename and encoding can be specified in # the options hash. # # opts - The default options Hash # :filename - The filename as a String # :encoding - The encoding as a String # # Returns this IniFile instance if the read was successful; nil is returned # if the file could not be read. def read(opts = {}) filename = opts.fetch(:filename, @filename) encoding = opts.fetch(:encoding, @encoding) return unless File.file? filename mode = encoding ? "r:#{encoding}" : 'r' File.open(filename, mode) { |fd| parse fd } self end alias restore read # Returns this IniFile converted to a String. def to_s s = [] @ini.each do |section, hash| s << "[#{section}]" hash.each { |param, val| s << "#{param} #{@param} #{escape_value val}" } s << '' end s.join("\n") end # Returns this IniFile converted to a Hash. def to_h @ini.dup end # Public: Creates a copy of this inifile with the entries from the # other_inifile merged into the copy. # # other - The other IniFile. # # Returns a new IniFile. def merge(other) dup.merge!(other) end # Public: Merges other_inifile into this inifile, overwriting existing # entries. Useful for having a system inifile with user overridable settings # elsewhere. # # other - The other IniFile. # # Returns this IniFile. def merge!(other) return self if other.nil? my_keys = @ini.keys other_keys = case other when IniFile other.instance_variable_get(:@ini).keys when Hash other.keys else raise Error, "cannot merge contents from '#{other.class.name}'" end (my_keys & other_keys).each do |key| case other[key] when Hash @ini[key].merge!(other[key]) when nil nil else raise Error, "cannot merge section #{key.inspect} - unsupported type: #{other[key].class.name}" end end (other_keys - my_keys).each do |key| @ini[key] = case other[key] when Hash other[key].dup when nil {} else raise Error, "cannot merge section #{key.inspect} - unsupported type: #{other[key].class.name}" end end self end # Public: Yield each INI file section, parameter, and value in turn to the # given block. # # block - The block that will be iterated by the each method. The block will # be passed the current section and the parameter/value pair. # # Examples # # inifile.each do |section, parameter, value| # puts "#{parameter} = #{value} [in section - #{section}]" # end # # Returns this IniFile. def each return unless block_given? @ini.each do |section, hash| hash.each do |param, val| yield section, param, val end end self end # Public: Yield each section in turn to the given block. # # block - The block that will be iterated by the each method. The block will # be passed the current section as a Hash. # # Examples # # inifile.each_section do |section| # puts section.inspect # end # # Returns this IniFile. def each_section return unless block_given? @ini.each_key { |section| yield section } self end # Public: Remove a section identified by name from the IniFile. # # section - The section name as a String. # # Returns the deleted section Hash. def delete_section(section) @ini.delete section.to_s end # Public: Get the section Hash by name. If the section does not exist, then # it will be created. # # section - The section name as a String. # # Examples # # inifile['global'] # #=> global section Hash # # Returns the Hash of parameter/value pairs for this section. def [](section) return nil if section.nil? @ini[section.to_s] end # Public: Set the section to a hash of parameter/value pairs. # # section - The section name as a String. # value - The Hash of parameter/value pairs. # # Examples # # inifile['tenderloin'] = { 'gritty' => 'yes' } # #=> { 'gritty' => 'yes' } # # Returns the value Hash. def []=(section, value) @ini[section.to_s] = value end # Public: Create a Hash containing only those INI file sections whose names # match the given regular expression. # # regex - The Regexp used to match section names. # # Examples # # inifile.match(/^tree_/) # #=> Hash of matching sections # # Return a Hash containing only those sections that match the given regular # expression. def match(regex) @ini.dup.delete_if { |section, _| section !~ regex } end # Public: Check to see if the IniFile contains the section. # # section - The section name as a String. # # Returns true if the section exists in the IniFile. def section?(section) @ini.key? section.to_s end # Returns an Array of section names contained in this IniFile. def sections @ini.keys end # Public: Freeze the state of this IniFile object. Any attempts to change # the object will raise an error. # # Returns this IniFile. def freeze super @ini.each_value { |h| h.freeze } @ini.freeze self end # Public: Mark this IniFile as tainted -- this will traverse each section # marking each as tainted. # # Returns this IniFile. def taint super @ini.each_value { |h| h.taint } @ini.taint self end # Public: Produces a duplicate of this IniFile. The duplicate is independent # of the original -- i.e. the duplicate can be modified without changing the # original. The tainted state of the original is copied to the duplicate. # # Returns a new IniFile. def dup other = super other.instance_variable_set(:@ini, Hash.new { |h, k| h[k] = {} }) @ini.each_pair { |s, h| other[s].merge! h } other.taint if tainted? other end # Public: Produces a duplicate of this IniFile. The duplicate is independent # of the original -- i.e. the duplicate can be modified without changing the # original. The tainted state and the frozen state of the original is copied # to the duplicate. # # Returns a new IniFile. def clone other = dup other.freeze if frozen? other end # Public: Compare this IniFile to some other IniFile. For two INI files to # be equivalent, they must have the same sections with the same parameter / # value pairs in each section. # # other - The other IniFile. # # Returns true if the INI files are equivalent and false if they differ. def eql?(other) return true if equal? other return false unless other.instance_of? self.class @ini == other.instance_variable_get(:@ini) end alias == eql? # Escape special characters. # # value - The String value to escape. # # Returns the escaped value. def escape_value(value) value = value.to_s.dup value.gsub!(%r{\\([0nrt])}, '\\\\\1') value.gsub!(%r{\n}, '\n') value.gsub!(%r{\r}, '\r') value.gsub!(%r{\t}, '\t') value.gsub!(%r{\0}, '\0') value end # Parse the given content and store the information in this IniFile # instance. All data will be cleared out and replaced with the information # read from the content. # # content - A String or a file descriptor (must respond to `each_line`) # # Returns this IniFile. def parse(content) parser = Parser.new(@ini, @param, @comment, @default) parser.parse(content) self end # The IniFile::Parser has the responsibility of reading the contents of an # .ini file and storing that information into a ruby Hash. The object being # parsed must respond to `each_line` - this includes Strings and any IO # object. class Parser attr_writer :section attr_accessor :property attr_accessor :value # Create a new IniFile::Parser that can be used to parse the contents of # an .ini file. # # hash - The Hash where parsed information will be stored # param - String used to separate parameter and value # comment - String containing the comment character(s) # default - The String name of the default global section # def initialize(hash, param, comment, default) @hash = hash @default = default comment = comment.to_s.empty? ? '\\z' : "\\s*(?:[#{comment}].*)?\\z" @section_regexp = %r{\A\s*\[([^\]]+)\]#{comment}} @ignore_regexp = %r{\A#{comment}} @property_regexp = %r{\A(.*?)(? true # "false" --> false # "" --> nil # "42" --> 42 # "3.14" --> 3.14 # "foo" --> "foo" # # Returns the typecast value. def typecast(value) case value when %r{\Atrue\z}i then true when %r{\Afalse\z}i then false when %r{\A\s*\z}i then nil else begin begin Integer(value) rescue Float(value) end rescue unescape_value(value) end end end # Unescape special characters found in the value string. This will convert # escaped null, tab, carriage return, newline, and backslash into their # literal equivalents. # # value - The String value to unescape. # # Returns the unescaped value. def unescape_value(value) value = value.to_s value.gsub!(%r{\\[0nrt\\]}) do |char| case char when '\0' then "\0" when '\n' then "\n" when '\r' then "\r" when '\t' then "\t" when '\\\\' then '\\' end end value end end end # IniFile diff --git a/metadata.json b/metadata.json index 76ae0ed..33a7460 100644 --- a/metadata.json +++ b/metadata.json @@ -1,94 +1,94 @@ { "name": "puppetlabs-mysql", "version": "10.8.0", "author": "puppetlabs", "summary": "Installs, configures, and manages the MySQL service.", "license": "Apache-2.0", "source": "git://github.com/puppetlabs/puppetlabs-mysql", "project_page": "http://github.com/puppetlabs/puppetlabs-mysql", "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">= 3.2.0 < 7.0.0" }, { "name": "puppetlabs/translate", "version_requirement": ">= 1.0.0 < 3.0.0" }, { "name": "puppetlabs/resource_api", "version_requirement": ">= 1.0.0 < 2.0.0" } ], "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ "5", "6", "7", "8" ] }, { "operatingsystem": "CentOS", "operatingsystemrelease": [ "5", "6", "7", "8" ] }, { "operatingsystem": "OracleLinux", "operatingsystemrelease": [ "5", "6", "7" ] }, { "operatingsystem": "Scientific", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "SLES", "operatingsystemrelease": [ "11", "12", "15" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "8", "9", "10" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "14.04", "16.04", "18.04", "20.04" ] } ], "requirements": [ { "name": "puppet", "version_requirement": ">= 5.5.10 < 7.0.0" } ], "description": "MySQL module", - "template-url": "https://github.com/puppetlabs/pdk-templates#master", - "template-ref": "heads/master-0-gd610ead", + "template-url": "https://github.com/puppetlabs/pdk-templates#main", + "template-ref": "heads/main-0-gd610ead", "pdk-version": "1.18.1" } diff --git a/readmes/README_ja_JP.md b/readmes/README_ja_JP.md index 4a305da..99d9bd5 100644 --- a/readmes/README_ja_JP.md +++ b/readmes/README_ja_JP.md @@ -1,543 +1,543 @@ # mysql #### 目次 1. [説明 - モジュールの機能とその有益性](#module-description) 2. [セットアップ - mysql導入の基本](#setup) * [mysqlの導入](#beginning-with-mysql) 3. [使用方法 - 設定オプションと追加機能](#usage) * [サーバオプションのカスタマイズ](#customize-server-options) * [データベースを作成します](#create-a-database) * [設定のカスタマイズ](#customize-configuration) * [既存のサーバに対する操作](#work-with-an-existing-server) * [パスワードの指定](#specify-passwords) * [CentOSへのPerconaサーバのインストール](#install-percona-server-on-centos) * [UbuntuへのMariaDBのインストール](#install-mariadb-on-ubuntu) * [プラグインのインストール](#install-plugins) 4. [参考 - モジュールの機能と動作について](REFERENCE.md) 5. [制約 - OS互換性など](#limitations) 6. [開発 - モジュール貢献についてのガイド](#development) ## モジュールの概要 mysqlモジュールは、MySQLサービスをインストール、設定、管理します。 このモジュールは、MySQLのインストールと設定を管理するとともに、データベース、ユーザ、GRANT権限などのMySQLリソースを管理できるようにPuppetの機能を拡張します。 ## セットアップ ### mysqlの導入 デフォルトのオプションを使用してサーバをインストールするには、次のコマンドを使用します。 `include '::mysql::server'`. ルートパスワードや`/etc/my.cnf`の設定値などのオプションをカスタマイズするには、オーバーライドハッシュも渡す必要があります。 ```puppet class { '::mysql::server': root_password => 'strongpassword', remove_default_accounts => true, override_options => $override_options } ``` $override_options用のハッシュ構造体の例については、後述の[**サーバオプションのカスタマイズ**](#サーバオプションのカスタマイズ)を参照してください。 ## 使用 サーバに関するすべてのインタラクションは`mysql::server`を使用して行われ、クライアントのインストールには`mysql::client`が、バインディングのインストールには`mysql::bindings`が使用されます。 ### サーバオプションのカスタマイズ サーバオプションを定義するには、`mysql::server`でオーバーライドのハッシュ構造体を作成します。このハッシュは、my.cnfファイルに含まれているハッシュと似ています。 ```puppet $override_options = { 'section' => { 'item' => 'thing', } } ``` この形式のオプションを従来の方法で示すと次のようになります。 ``` [section] thing = X ``` ハッシュ内では`thing => true`、`thing => value`、または`thing => ""`の形でエントリを作成できます。または、`thing => ['value', 'value2']`の形で配列を渡したり、`thing => value`を独立した行に個別にリストすることもできます。 値を設定せずに変数をハッシュに含めて渡すことができます。この場合、変数にはMySQLのデフォルトの設定値が使用されます。オプションを`my.cnf`ファイルから除外するには(たとえば`override_options`を使用してデフォルト値に戻す場合など)、`thing => undef`を渡します。 オプションに複数のインスタンスが必要な場合は配列を渡します。たとえば次の例の場合は、 ```puppet $override_options = { 'mysqld' => { 'replicate-do-db' => ['base1', 'base2'], } } ``` 次のようになります。 ```puppet [mysqld] replicate-do-db = base1 replicate-do-db = base2 ``` バージョンに固有なパラメータを実装するには、[mysqld-5.5]のようにバージョンを指定します。こうすると、1つのconfigで複数の異なるバージョンのMySQLに対応できます。 ### データベースを作成します ユーザおよび割り当てられたいくつかの権限を含むデータベースを作成するには、次のようにします。 ```puppet mysql::db { 'mydb': user => 'myuser', password => 'mypass', host => 'localhost', grant => ['SELECT', 'UPDATE'], } ``` エクスポートされたリソースを含む別のリソース名を使用するには、次のようにします。 ```puppet @@mysql::db { "mydb_${fqdn}": user => 'myuser', password => 'mypass', dbname => 'mydb', host => ${fqdn}, grant => ['SELECT', 'UPDATE'], tag => $domain, } ``` さらに、これをリモートDBサーバに集めることができます。 ```puppet Mysql::Db <<| tag == $domain |>> ``` データベースの作成時にファイルにsqlパラメータを設定する場合は、新しいデータベースにファイルがインポートされます。 サイズの大きいsqlファイルの場合は、`import_timeout`パラメータの値(デフォルト値300秒)を大きくします。 MySQLクライアントを標準のbin/sbin以外のパスにインストールしている場合、`mysql_exec_path`にこれを設定します。 ```puppet mysql::db { 'mydb': user => 'myuser', password => 'mypass', host => 'localhost', grant => ['SELECT', 'UPDATE'], sql => '/path/to/sqlfile.gz', import_cat_cmd => 'zcat', import_timeout => 900, mysql_exec_path => '/opt/rh/rh-myql57/root/bin' } ``` ### 設定のカスタマイズ MySQLカスタム設定を追加するには、`includedir`にファイルを追加します。こうすると設定値をオーバーライドしたり別の設定値を追加したりすることができ、`mysql::server`で`override_options`を使用しない場合に役立ちます。`includedir`の場所は、デフォルトでは`/etc/mysql/conf.d`に設定されます。 ### 既存のサーバに対する操作 既存のMySQLサーバ上にデータベースとユーザのインスタンスを作成するには、`root`のホームディレクトリに`.my.cnf`ファイルが必要です。次の例のように、このファイルでリモートサーバのアドレスと認証情報を指定する必要があります。 ```puppet [client] user=root host=localhost password=secret ``` このモジュールは、`mysqld_version`ファクトから、使用されているサーバのバージョンを認識します。デフォルトでは、`mysqld_version`は`mysqld -V`の出力に設定されています。リモートMySQLサーバに対する操作を行う場合は、`mysqld_version`に対応するカスタムファクトを設定しないと正常に動作しない可能性があります。 リモートサーバに対する操作を行う際には、Puppetマニフェスト内で`mysql::server`クラスを使用*しない*でください。 ### パスワードの指定 パスワードは、プレーンテキストとして渡せるだけでなく、次のようにハッシュとして入力することもできます。 ```puppet mysql::db { 'mydb': user => 'myuser', password => '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4', host => 'localhost', grant => ['SELECT', 'UPDATE'], } ``` 必要に応じて、パスワードも空文字列とし、パスワードなしで接続を許可することができます。 ### CentOSへのPerconaサーバのインストール 次の例は、CentOSシステムへのPerconaサーバの最小限のインストール方法を示します。この例では、Perconaサーバ、クライアント、バインディング(PerlとPythonのバインディングを含む)がセットアップされます。この方法をカスタマイズして必要に応じバージョンを更新することができます。 この方法は、Puppet 4.4/CentOS 7/Perconaサーバ5.7でテストされています。 注意:** yumレポジトリのインストールはこのパッケージには含まれていません。 ```puppet yumrepo { 'percona': descr => 'CentOS $releasever - Percona', baseurl => 'http://repo.percona.com/centos/$releasever/os/$basearch/', gpgkey => 'http://www.percona.com/downloads/percona-release/RPM-GPG-KEY-percona', enabled => 1, gpgcheck => 1, } class {'mysql::server': package_name => 'Percona-Server-server-57', package_ensure => '5.7.11-4.1.el7', service_name => 'mysql', config_file => '/etc/my.cnf', includedir => '/etc/my.cnf.d', root_password => 'PutYourOwnPwdHere', override_options => { mysqld => { log-error => '/var/log/mysqld.log', pid-file => '/var/run/mysqld/mysqld.pid', }, mysqld_safe => { log-error => '/var/log/mysqld.log', }, } } # 注意:Percona-Server-server-57をインストールするとPercona-Server-client-57もインストールされます。 # 次の例は、Percona MySQLクライアントを単独でインストールする方法を示します。 class {'mysql::client': package_name => 'Percona-Server-client-57', package_ensure => '5.7.11-4.1.el7', } # 通常、以下のパッケージはPercona-Server-server-57とともにインストールされます。 # バインディングもインストールする必要がある場合は、このコードでインストールできます。 class { 'mysql::bindings': client_dev_package_name => 'Percona-Server-shared-57', client_dev_package_ensure => '5.7.11-4.1.el7', client_dev => true, daemon_dev_package_name => 'Percona-Server-devel-57', daemon_dev_package_ensure => '5.7.11-4.1.el7', daemon_dev => true, perl_enable => true, perl_package_name => 'perl-DBD-MySQL', python_enable => true, python_package_name => 'MySQL-python', } # Dependencies definition Yumrepo['percona']-> Class['mysql::server'] Yumrepo['percona']-> Class['mysql::client'] Yumrepo['percona']-> Class['mysql::bindings'] ``` ### UbuntuへのMariaDBのインストール #### オプション:MariaDBの公式のレポジトリのインストール 次の例では、distroレポジトリでなく公式のMariaDBレポジトリの最新の安定版(現在10.1)を使用しています。代わりに、Ubuntuレポジトリのパッケージを使用することもできます。必要に応じた正しいバージョンのレポジトリを使用してください。 **注意:** `sfo1.mirrors.digitalocean.com`は利用可能な多くのミラーの一例であり、公式のミラーであればいずれも使用できます。 ```puppet include apt apt::source { 'mariadb': location => 'http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu', release => $::lsbdistcodename, repos => 'main', key => { id => '199369E5404BD5FC7D2FE43BCBCB082A1BB943DB', server => 'hkp://keyserver.ubuntu.com:80', }, include => { src => false, deb => true, }, } ``` #### MariaDBサーバのインストール 次の例では、Ubuntu TrustyへのMariaDBサーバのインストール方法を示しています。`my.cnf`のバージョンとパラメータは、必要に応じて調整してください。`my.cnf`のパラメータはすべて`override_options`パラメータを使用して定義できます。 フォルダ`/var/log/mysql`と`/var/run/mysqld`は自動的に作成されますが、他のカスタムフォルダを使用する場合は、それらがコードの必須要件になります。 以下に示す値はすべて、最小限の構成にする場合の例です。 必要なパッケージのバージョンを、`package_ensure`パラメータで指定してください。 ```puppet class {'::mysql::server': package_name => 'mariadb-server', package_ensure => '10.1.14+maria-1~trusty', service_name => 'mysql', root_password => 'AVeryStrongPasswordUShouldEncrypt!', override_options => { mysqld => { 'log-error' => '/var/log/mysql/mariadb.log', 'pid-file' => '/var/run/mysqld/mysqld.pid', }, mysqld_safe => { 'log-error' => '/var/log/mysql/mariadb.log', }, } } # 依存関係の管理。レポジトリをインストールする場合はこの例の前のステップで示されている部分だけを使用してください。 Apt::Source['mariadb'] ~> Class['apt::update'] -> Class['::mysql::server'] ``` #### MariaDBクライアントのインストール 次の例は、MariaDBクライアントとすべてのバインディングを一度にインストールする方法を示します。このインストール操作は、サーバのインストール操作とは別に行うことができます。 必要なパッケージのバージョンを、`package_ensure`パラメータで指定してください。 ```puppet class {'::mysql::client': package_name => 'mariadb-client', package_ensure => '10.1.14+maria-1~trusty', bindings_enable => true, } # Dependency management. Only use that part if you are installing the repository as shown in the Preliminary step of this example. Apt::Source['mariadb'] ~> Class['apt::update'] -> Class['::mysql::client'] ``` ### CentOSへのMySQL Communityサーバのインストール MySQLモジュールおよびHieraを使用して、MySQL CommunityサーバーをCentOSにインストールすることができます。この例は以下のバージョンでテスト済みです。 * MySQL Community Server 5.6 * Centos 7.3 * Hieraを使用したPuppet 3.8.7 * puppetlabs-mysqlモジュールv3.9.0 Puppetで: ```puppet include ::mysql::server create_resources(yumrepo, hiera('yumrepo', {})) Yumrepo['repo.mysql.com'] -> Anchor['mysql::server::start'] Yumrepo['repo.mysql.com'] -> Package['mysql_client'] create_resources(mysql::db, hiera('mysql::server::db', {})) ``` Hieraで: ```yaml --- # Centos 7.3 yumrepo: 'repo.mysql.com': baseurl: "http://repo.mysql.com/yum/mysql-5.6-community/el/%{::operatingsystemmajrelease}/$basearch/" descr: 'repo.mysql.com' enabled: 1 gpgcheck: true gpgkey: 'http://repo.mysql.com/RPM-GPG-KEY-mysql' mysql::client::package_name: "mysql-community-client" # 適切なMySQL導入のために必要 mysql::server::package_name: "mysql-community-server" # 適切なMySQL導入のために必要 mysql::server::package_ensure: 'installed' # ここではバージョンを指定しないでください。残念ながら、パッケージがインストールされているエラーでyumは失敗しました。 mysql::server::root_password: "change_me_i_am_insecure" mysql::server::manage_config_file: true mysql::server::service_name: 'mysqld' # Puppetモジュールに必要 mysql::server::override_options: 'mysqld': 'bind-address': '127.0.0.1' 'log-error': '/var/log/mysqld.log' # 適切なMySQL導入のために必要 'mysqld_safe': 'log-error': '/var/log/mysqld.log' # 適切なMySQL導入のために必要 # データベース+アクセスできるアカウント、暗号化されていないパスワードを作成 mysql::server::db: "dev": user: "dev" password: "devpass" host: "127.0.0.1" grant: - "ALL" ``` ### プラグインのインストール プラグインはユーザ定義のタイプ`mysql_plugin` を使用してインストールできます。`examples/mysql_plugin.pp`で、具体的な例を参照してください。 ## リファレンス ### クラス #### パブリッククラス * [`mysql::server`](#mysqlserver):MySQLをインストールして設定します。 * [`mysql::server::monitor`](#mysqlservermonitor):モニタするユーザをセットアップします。 * [`mysql::server::mysqltuner`](#mysqlservermysqltuner):MySQL tunerスクリプトをインストールします。 * [`mysql::server::backup`](#mysqlserverbackup):cronを使用してMySQLバックアップをセットアップします。 * [`mysql::bindings`](#mysqlbindings):さまざまなMySQL言語バインディングをインストールします。 * [`mysql::client`](#mysqlclient):MySQLクライアントをインストールします(サーバ以外)。 #### プライベートクラス * `mysql::server::install`:パッケージをインストールします。 * `mysql::server::installdb`:mysqldデータディレクトリ(/var/lib/mysqlなど)のセットアップを実行します。 * `mysql::server::config`:MySQLを設定します。 * `mysql::server::service`:サービスを管理します。 * `mysql::server::account_security`:デフォルトのMySQLアカウントを削除します。 * `mysql::server::root_password`:MySQLのルートパスワードを設定します。 * `mysql::server::providers`:ユーザ、GRANT権限、データベースを作成します。 * `mysql::bindings::client_dev`:MySQLクライアント開発パッケージをインストールします。 * `mysql::bindings::daemon_dev`:MySQLデーモン開発パッケージをインストールします。 * `mysql::bindings::java`:javaバインディングをインストールします。 * `mysql::bindings::perl`:Perlバインディングをインストールします。 * `mysql::bindings::php`:PHPバインディングをインストールします。 * `mysql::bindings::python`:Pythonバインディングをインストールします。 * `mysql::bindings::ruby`:Rubyバインディングをインストールします。 * `mysql::client::install`:MySQLクライアントをインストールします。 * `mysql::backup::mysqldump`:mysqldumpのバックアップを実行します。 * `mysql::backup::mysqlbackup`:Oracle MySQL Enterprise Backupを使用してバックアップを実行します。 * `mysql::backup::xtrabackup`:PerconaのXtraBackupを使用してバックアップを実行します。 ### パラメータ #### mysql::server ##### `create_root_user` ルートユーザを作成するかどうかを指定します。 有効な値:`true`、`false`。 デフォルト値:`true`。 このパラメータは、Galeraでクラスタをセットアップする場合に役立ちます。ルートユーザの作成が必要なのは一度だけです。このパラメータを、1つのノードに対しtrueに設定し、他のすべてのノードに対してfalseに設定できます。 ##### `create_root_my_cnf` `/root/.my.cnf`を作成するかどうかを指定します。 有効な値:`true`、`false`。 デフォルト値:`true`。 `create_root_my_cnf`を使用すると`create_root_user`に左右されずに`/root/.my.cnf`を作成できます。すべてのノードに`/root/.my.cnf`が存在するようにしたい場合に、Galeraでこの機能を使用してクラスタをセットアップできます。 ##### `root_password` MySQLのルートパスワード。Puppetは、このパラメータを使用して、ルートパスワードの設定や`/root/.my.cnf`の更新を試みます。 `create_root_user`または`create_root_my_cnf`がtrueの場合にこのパラメータが必要です。`root_password`が'UNSET'の場合は`create_root_user`と`create_root_my_cnf`がfalseになります(MySQLルートユーザと`/root/.my.cnf`が作成されません)。 パスワード変更はサポートされますが、`/root/.my.cnf`に旧パスワードが設定されている必要があります。実際には、Puppetは`/root/.my.cnf`に設定されている旧パスワードを使用してMySQLで新しいパスワードを設定してから、`/root/.my.cnf`を新しいパスワードで更新します。 ##### `old_root_password` 現在、このパラメータでは何も行わず、下位互換性を確保するためだけに存在します。ルートパスワードの変更についての詳細は、上記の`root_password`パラメータの説明を参照してください。 ##### `create_root_login_file` mysql 5.6.6以上を使用するときに、`/root/.mylogin.cnf`を作成するかどうかを指定します。 有効な値:`true`、`false`。 デフォルト値:`false`。 `create_root_login_file`は、既存の`.mylogin.cnf`のコピーを`/root/.mylogin.cnf`に作成します。 このオプションを'true'に設定する場合、`login_file`オプションも指定する必要があります。 'true'に設定する場合、`login_file`オプションが必要です。 #### `login_file` `/root/.mylogin.cnf`を規定の位置に配置するかどうかを指定します。 `.mylogin.cnf`ファイルの作成には、`mysql_config_editor`を使用する必要があります。このツールは、mysql 5.6.6+に付属しています。 作成した.mylogin.cnfファイルは、モジュール内のファイルの下に配置する必要があります。使用法については下記の例を参照してください。 `/root/.mylogin.cnf`が存在する場合、環境変数`MYSQL_TEST_LOGIN_FILE`が設定されます。 このパラメータは、`create_root_user`と`create_root_login_file`がどちらもtrueである場合に必要です。`root_password`が'UNSET'である場合、`create_root_user`および`create_root_login_file`はfalseであると見なされます。このため、MySQLのrootユーザと`/root/.mylogin.cnf`は作成されません。 ```puppet class { '::mysql::server': root_password => 'password', create_root_my_cnf => false, create_root_login_file => true, login_file => "puppet:///modules/${module_name}/mylogin.cnf", } ``` ##### `override_options` MySQLに渡すオーバーライドオプションを指定します。構造はmy.cnfファイルのハッシュと同様です。 ```puppet class { 'mysql::server': root_password => 'password' } mysql_plugin { 'auth_pam': ensure => present, soname => 'auth_pam.so', } ``` ### タスク MySQLモジュールにはサンプルタスクがあり、ユーザはデータベースに対して任意のSQLを実行できます。[Puppet Enterpriseマニュアル](https://puppet.com/docs/pe/2017.3/orchestrator/running_tasks.html)または[Boltマニュアル](https://puppet.com/docs/bolt/latest/bolt.html)で、タスクを実行する方法に関する情報を参照してください。 ## 制約事項 -サポートされているオペレーティングシステムの一覧については、[metadata.json](https://github.com/puppetlabs/puppetlabs-mysql/blob/master/metadata.json)を参照してください。 +サポートされているオペレーティングシステムの一覧については、[metadata.json](https://github.com/puppetlabs/puppetlabs-mysql/blob/main/metadata.json)を参照してください。 **注意:** mysqlbackup.shは、MySQL 5.7以降では動作せず、サポートされていません。 ## 開発 Puppet Forge上のPuppetモジュールはオープンプロジェクトであり、その価値を維持するにはコミュニティからの貢献が欠かせません。Puppetが提供する膨大な数のプラットフォームや、無数のハードウェア、ソフトウェア、デプロイ設定に弊社がアクセスすることは不可能です。 弊社は、できるだけ変更に貢献しやすくして、弊社のモジュールがユーザの環境で機能する状態を維持したいと考えています。弊社では、状況を把握できるよう、貢献者に従っていただくべきいくつかのガイドラインを設けています。 弊社の詳細な[モジュール貢献についてのガイドライン](https://docs.puppetlabs.com/forge/contributing.html)をご確認ください。 ### 作成者 このモジュールは、David Schmittが作成したものをベースにして、以下の作成者による貢献内容が加えられています(Puppet Labsを除く)。 * Larry Ludwig * Christian G. Warden * Daniel Black * Justin Ellison * Lowe Schmidt * Matthias Pigulla * William Van Hevelingen * Michael Arnold * Chris Weyl * Daniël van Eeden * Jan-Otto Kröpke * Timothy Sven Nelson