Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split is-installed check into a non-multisite and a mulitsite specific one #1388

Conversation

strarsis
Copy link
Contributor

@strarsis strarsis commented May 31, 2022

(Variant C) This PR splits the WordPress installed? check into two conditional ones,
one for non-multisites and one for multisites.
The temporary PHP file for setting some constants to null/false is then only created/ensured for multisites.
The wp core is-installed invocation also is then different for non-multisites and multisites,
and the PHP warning for strpos() empty needle for a null WPMU_PLUGIN_DIR constant (used in the multisite check)
is ignored (as in the variant B PR #1387).

Edit: Fixes #1385.

Variant A PR: #1386 (Edit: Closed now in favor of this one)
Variant B PR: #1387 (Edit: Closed now in favor of this one)
Variant C PR: (This PR)

@swalkinshaw: IMHO this approach is the best one as it simplifies the check for non-multisite (single) sites,
while allowing the PHP warning for multisites sites.

@swalkinshaw
Copy link
Member

Can these be grouped better using Ansible blocks? They support block names too which can replace the comments.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 1, 2022

@swalkinshaw: The both checks for non-multisite and multisite are now grouped into Ansible blocks.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 1, 2022

One of the checks failed due to unrelated issues:
https://github.com/roots/trellis/runs/6694770848?check_suite_focus=true#step:11:136-146

Edit: Made a small change that triggered new tests that pass.

@swalkinshaw
Copy link
Member

Thanks so much for all this investigation @strarsis (and the PRs!).

I agree this one makes the most sense for now at least 🚀

@swalkinshaw swalkinshaw merged commit e42880d into roots:master Jun 1, 2022
@strarsis strarsis deleted the fix-add-conditional-multi-single-site-installed-checks branch June 2, 2022 02:31
@codepuncher
Copy link

@strarsis Not sure if this is an issue on my end or not, but it only seems to work for singlesites; multisites still have the issue.
Anything I can test/help with here?

@strarsis
Copy link
Contributor Author

strarsis commented Jun 7, 2022

@strarsis Not sure if this is an issue on my end or not, but it only seems to work for singlesites; multisites still have the issue.

For multisite this particular PHP warning is ignored, this preserves the way the constants are currently set and allows deploys. The PHP warning is caused by setting the constant to null. WordPress core since 6.0 doesn't handle this constant being null/empty. This would be the underlying issue. 1. Does that constant still have to set to null? 2. Can a non-null/-empty value be used instead that causes the same behavior (if any in current WordPress)? 3. Should the null value be still required for that constant, then a new a new issue ticket should be created for WordPress core that fixes the PHP warning (see the discourse discussion).
For now the PR allows for functioning deploys of non-multisites and multisites with WordPress 6.0+.

@codepuncher
Copy link

For multisite this particular PHP warning is ignored, this preserves the way the constants are currently set and allows deploys.

It doesn't seem to be "ignoring" the warning or allowing deploys for the multisite I am using this commit on, this is my problem.
Screenshot 2022-06-07 at 12 53 12

Agreed the problem needs fixing upstream in WP Core, though.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 7, 2022

@codepuncher: Can you comment out/remove the non-multisite part and deploy a multisite-site again? To exclude the possibility that this may be used (or is it listed as "skipped")?

A PHP warning Warning: strpos(): Empty needle in /srv/www/[sitename]/releases/[release]/web/wp/wp-includes/link-template.php should be ignored. The PHP warning string you get appears to match this, too.

@codepuncher
Copy link

Gave that a go and had the same problem.

However, I did find that on this particular project roles/deploy/files/tmp_multisite_constants.php was edited and had the MULTISITE AND SUBDOMAIN_INSTALL commented out.
I uncommented that and tried again but am now presented with a different issue:

Log ```log TASK [deploy : Invoke 'wp core is-installed' command] ************************** System info: Ansible 2.12.6; Darwin Trellis version (per changelog): "Add built-in fail2ban filters" --------------------------------------------------- non-zero return code PHP Fatal error: Uncaught Roots\WPConfig\Exceptions\ConstantAlreadyDefinedException: Aborted trying to redefine constant 'MULTISITE'. `define('MULTISITE', ...)` has already been occurred elsewhere. in /www/activatelearningcolleges_710/public/releases/2022 0607133101/vendor/roots/wp-config/src/Config.php:106 Stack trace: #0 /www/activatelearningcolleges_710/public/releases/20220607133101/vendor/ro ots/wp-config/src/Config.php(26): Roots\WPConfig\Config::defined() #1 /www/activatelearningcolleges_710/public/releases/20220607133101/config/ap plication.php(124): Roots\WPConfig\Config::define() #2 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1277) : eval()'d code(7): require_once('/www/activatele...') #3 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1277): eval() #4 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1235): WP_CLI\Runner->load_wordpress() #5 phar:///usr/local/bin/wp/vendor/wp-cli/wp- cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start() #6 ph in /www/activatelearningcolleges_710/public/releases/20220607133101/ven dor/roots/wp-config/src/Config.php on line 106 fatal: [kinsta_staging]: FAILED! => {"changed": false, "cmd": ["wp", "core", "is-installed", "--skip-plugins", "--skip-themes", "--require=/www/activatelearningcolleges_710/public/shared/tmp_multisite_constants.php"], "delta": "0:00:00.155150", "end": "2022-06-07 13:32:43.897521", "failed_when_result": true, "rc": 255, "start": "2022-06-07 13:32:43.742371", "stderr_lines": ["PHP Fatal error: Uncaught Roots\\WPConfig\\Exceptions\\ConstantAlreadyDefinedException: Aborted trying to redefine constant 'MULTISITE'. `define('MULTISITE', ...)` has already been occurred elsewhere. in /www/activatelearningcolleges_710/public/releases/20220607133101/vendor/roots/wp-config/src/Config.php:106", "Stack trace:", "#0 /www/activatelearningcolleges_710/public/releases/20220607133101/vendor/roots/wp-config/src/Config.php(26): Roots\\WPConfig\\Config::defined()", "#1 /www/activatelearningcolleges_710/public/releases/20220607133101/config/application.php(124): Roots\\WPConfig\\Config::define()", "#2 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1277) : eval()'d code(7): require_once('/www/activatele...')", "#3 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1277): eval()", "#4 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1235): WP_CLI\\Runner->load_wordpress()", "#5 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\\Runner->start()", "#6 ph in /www/activatelearningcolleges_710/public/releases/20220607133101/vendor/roots/wp-config/src/Config.php on line 106"], "stdout": "", "stdout_lines": []} ```

So, really, this is a separate issue from what I'm seeing.
The Composer autoloader is not loaded here so we can't just throw in a use for Config::define to get around that nor do I know if that would be a sensible idea to pull in the autoloader just for this.
Not sure if this issue now resides with Trellis, Bedrock or the separate https://github.com/roots/wp-config package.

I've tried a few things such as wrapping the Config::define in config/application.php with an if (! defined()) check, but that doesn't help either.

Removing the --require=.../tmp_multisite_constants.php from the wp core is-installed command will allow deploys to continue, though, so that's what I'll have to do for the time being.

Any ideas at this point @strarsis? Want to make sure I report log this issue in the appropriate repository, too, so where would that sit best @swalkinshaw?

Cheers

@strarsis
Copy link
Contributor Author

strarsis commented Jun 8, 2022

define('MULTISITE', ...)` has already been occurred elsewhere

So according to that PHP error the MULTISITE constant is already defined somewhere else, outside of tmp_multisite_constants.php. Can you grep or somehow find out where the MULTISITE constant else is defined for that site?

@codepuncher
Copy link

That's the only place that constant is defined is within bedrock/config/application.php so this seems to conflict with Config::define('MULTISITE', true);.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 8, 2022

@codepuncher: This may be the underlying reason: Recent Bedrock doesn't set the MULTISITE constant in bedrock/config/application.php: https://github.com/roots/bedrock/blob/master/config/application.php

Edit: Except that maybe Trellis adds this for multisite sites, but I can't find any occurrences of this except for the temporary PHP file used by the multisite is installed check (Edit: which i...

@swalkinshaw
Copy link
Member

🤔 yeah I'm guessing that was manually added at some point? The WP constant is WP_ALLOW_MULTISITE so I'd just remove Config::define('MULTISITE', true); from bedrock/config/application.php

@codepuncher
Copy link

Yeah, default Bedrock does not include the MULTISITE constant. However, the Trellis docs say it is needed.
Additionally, the same problem happens with the SUBDOMAIN_INSTALL constant and removing that is not doable since I need that set to true because it is a subdomain install.

Removing both constants from config/application.php and deploying results in the original issue with strpos(): Empty needle.

Not sure what is going on here at this point 🤔

@strarsis
Copy link
Contributor Author

strarsis commented Jun 8, 2022

@codepuncher: Good point. The Trellis docs state Config::define('MULTISITE', true); should be added, but the tmp_multisite_constants.phpalso defines that constant - which would cause aConstantAlreadyDefinedException`. 😕

But that tmp_multisite_constants.php has been always included, even unnecessarily for non-multisite sites in previous releases of Trellis and that conflict didn't happen.

@swalkinshaw
Copy link
Member

I personally don't know anything about MU, but that constant is used by WP so it's not completely wrong that the docs say it: https://github.com/WordPress/WordPress/blob/8a90b8691ff7a7cf511ec624c912aacb6dd2b30a/wp-admin/network.php#L28-L30

@strarsis
Copy link
Contributor Author

strarsis commented Jun 8, 2022

@swalkinshaw: Right, the constant should be set. But why hadn't there been a conflict with the Trellis multisite check until now, at least for @codepuncher. That PHP file that sets the constant had always been included, so this error should have occurred before for multisite sites, but apparently it hadn't, that's what currently totally baffles me.

@codepuncher: Do deploys of WordPress pre 6.0 multisite work for you - do you get this constant error?
Have you ever had such an error where this constant was set twice during Trellis deploy?

@strarsis
Copy link
Contributor Author

strarsis commented Jun 9, 2022

@swalkinshaw, @codepuncher:
So I tested deploying with Trellis after this PR and before this PR and with WordPress 6.0 and 5.9.

When I comment out the constants in tmp_multisite_constants.php to prevent the PHP constants already defined exceptions, this works - but those PHP constants are set for a reason - it prevents an error for deploying multisite sites that were not set up yet (the multisite site has to be set-up using the command shown in the Trellis Multisite docs).

non-zero return code
WordPress database error Table 'examples_com_production.wp_blogs' doesn't
exist for query SELECT  wp_blogs.blog_id FROM wp_blogs  WHERE domain =
'site2.examples.com' AND path = '/'  ORDER BY wp_blogs.blog_id ASC LIMIT 1
made by include('phar:///usr/bin/wp/php/boot-phar.php'),
include('phar:///usr/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php'),

The commit that added this code explains this as the reason: 51f7b72

So when the multisite site already was set-up, commenting out these PHP constants fixes the PHP constants already defined exceptions - but for non-set-up multisites sites deployments will fail as shown above.

So these PHP constants are only needed for non-set-up multisite sites.

To completely fix this issue IMHO the multisite constants set in the Bedrock site config needs to be set as optional constants - the Config::define(...) method is already used that PHP wrap define(...) by using the ::apply() step at the end.
So another method or optional argument for making PHP constants explicitly optional should solve all these issues.

Before:

/* Multisite */
Config::define('WP_ALLOW_MULTISITE', true);
Config::define('MULTISITE', true);
Config::define('SUBDOMAIN_INSTALL', false); // Set to true if using subdomains
Config::define('DOMAIN_CURRENT_SITE', env('DOMAIN_CURRENT_SITE'));
Config::define('PATH_CURRENT_SITE', env('PATH_CURRENT_SITE') ?: '/');
Config::define('SITE_ID_CURRENT_SITE', env('SITE_ID_CURRENT_SITE') ?: 1);
Config::define('BLOG_ID_CURRENT_SITE', env('BLOG_ID_CURRENT_SITE') ?: 1);

After:

/* Multisite */
Config::defineIfNotDefined('WP_ALLOW_MULTISITE', true);
Config::defineIfNotDefined('MULTISITE', true);
Config::defineIfNotDefined('SUBDOMAIN_INSTALL', false); // Set to true if using subdomains
Config::defineIfNotDefined('DOMAIN_CURRENT_SITE', env('DOMAIN_CURRENT_SITE'));
Config::defineIfNotDefined('PATH_CURRENT_SITE', env('PATH_CURRENT_SITE') ?: '/');
Config::defineIfNotDefined('SITE_ID_CURRENT_SITE', env('SITE_ID_CURRENT_SITE') ?: 1);
Config::defineIfNotDefined('BLOG_ID_CURRENT_SITE', env('BLOG_ID_CURRENT_SITE') ?: 1);

Constants defined by this proposed defineIfNotDefined(...) method should not throw a PHP exception in the apply() method at the end of the Bedrock config file, when the PHP constant to be defined are already defined.

@swalkinshaw
Copy link
Member

So these PHP constants are only needed for non-set-up multisite sites.

Can you explain exactly what this state is and how you did it?

I was testing last night as well and couldn't reproduce that database error. My process was:

  1. create new server with an MU site
  2. let the installation happen + confirm it was an MU site
  3. run wp db drop && wp db create to end up with an empty database
  4. run various wp is-installed commands

@strarsis
Copy link
Contributor Author

strarsis commented Jun 9, 2022

@swalkinshaw:

  1. New Ubuntu server.
  2. Provisioned with Trellis (last version with the PR).
  3. Deployed a non-multisite site, it works.
  4. Tried to deploy a multisite site, deployment fails.
  5. Commented out the PHP constants in the temporary PHP file (to be copied by Ansible) for multisites.
  6. Tried to deploy again, get the database error for non-set up multisites.
  7. Deploy failed, can't invoke the command to set up the multisite.

When I manually go into the release directory of that site (no current symlink was created) and
run the multisite setup command directly from there, PHP warnings show up, but the setup is completed successfully.
Subsequent deploys work now even without these temporary PHP constants as the multisite site is now set up.
This may be a workaround for the is installed check: Trellis can invoke command for multisite setup before the is installed check. Then the site is set up and the temporary constants aren't needed. But this requires Trellis to set the site up on its own (the settings are already set in Trellis config, so why not?).

@swalkinshaw
Copy link
Member

So I wonder if this only happens when going from non-multisite -> multisite? That would seem very rare though. If so, should Trellis even care to support that edge case?

@strarsis
Copy link
Contributor Author

strarsis commented Jun 9, 2022

@swalkinshaw: From my description this was a bit confusing, sorry for that. But I deployed a non-multisite site and then a completely separate multisite site. To be sure I redo these steps with a clean system to verify.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 9, 2022

@swalkinshaw: Alright, I prepared something that can reproduce the issue and also demonstrate what and where exactly things go wrong:

  1. Clone this Trellis setup: https://github.com/strarsis/trellis-multisite-deployment-tests
    It uses recent Trellis with this PR merged as this isolates issues with multisite and simplifies testing.
    It contains two sites, one non-multisite site (example.com) and one multisite site (examples.com, plural form, hehe).
    example.com (non-multisite site): https://github.com/strarsis/bedrock-site-example
    examples.com (multisite site): https://github.com/strarsis/bedrock-multisite-example (added multisite config as described)
    Both sites use WordPress 6.0.
    SSL is disabled to further simplify things.
  2. Spin up some server/VM/cloud instance with Ubuntu 20.04 LTS.
    I tested on a Hyper-V VM with a base Ubuntu install from the ubuntu-20.04.4-live-server-amd64.iso (https://releases.ubuntu.com/20.04/#:~:text=Server%20install%20image%20for%2064%2Dbit%20PC%20(AMD64)%20computers%20(standard%20download).
    I creatively named that system "trellis" in ansible hosts/production config.
    Assign that hostname an IP, manually add an IP, initial admin password/copy SSH keys, and whatever to bootstrap the system.
    (Optionally create VM snapshot here)
  3. Run trellis init; trellis provision production.
    Everything should provision fine.
    (Optionally create VM snapshot here)
  4. Run trellis deploy --verbose production example.com (example, without s (sg.))
    This deploys the non-multisite site, still everything works fine.
    (Optionally create VM snapshot here)
  5. Run trellis deploy --verbose production examples.com (examples with s (pl.)!)
    Deployment of the multisite site will fail because of PHP exception (constant already defined),
    Ansible doesn't really show that in the terminal I think, maybe this can be improved.
    The command exits silently here with a non-zero exit code of 255.
  6. Anyway, now comment out the contents of tmp_multisite_constants.php,
    this is the simplest way to test another deploy without these constants being defined.
  7. Re-run trellis deploy --verbose production examples.com.
    Now the database error occurs for non-set up multisite sites:
non-zero return code
WordPress database error Table 'examples_com_production.wp_blogs' doesn't
exist for query SELECT  wp_blogs.blog_id FROM wp_blogs  WHERE domain =
'site2.examples.com' AND path = '/'  ORDER BY wp_blogs.blog_id ASC LIMIT 1
made by include('phar:///usr/bin/wp/php/boot-phar.php'),
include('phar:///usr/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php'),

The is installed check fails with this error. The current symlink is not created as the deployment failed.

  1. SSH into the Trellis server as web user. (On web@trellis) Go into the latest release directory of examples.com (/srv/www/examples.com/releases/20220609190041(some timestamp)/).
  2. From inside that directory, manually run the WP CLI command to configure the multisite as described in the Trellis Multisite docs:
    wp core multisite-install --title="site title" --admin_user="username" --admin_password="password" --admin_email="[email protected]"
    Despite some occasional PHP warnings the command should succeed. The multisite site is now set up.
  3. (On workstation again) Re-run trellis deploy --verbose production examples.com (with the tmp_multisite_constants.php contents still commented out (step 6.)).
    Note that the deployment and subsequent deployments work fine now.
  4. Now de-comment/restore the contents of tmp_multisite_constants.php.
  5. Re-run trellis deploy --verbose production examples.com.
    Note that the deployment now fails again at the is installed check because the PHP constants already defined exception came back.

This should demonstrate that...

  1. The is installed check on not yet set up multisite sites will always fail (database error) until the site has been set up using WP CLI (as stated in the Trellis Multisite docs) ‒ or by temporarily disabling multisite by letting the WP CLI for the is installed check require a PHP file with constants (see 2. below!) that disable the multisite feature.
  2. Those temporary PHP constants (in tmp_multisite_constants.php) are needed for performing the is installed check on non-set up multisites without causing the database error, as multisite feature is temporarily disabled with them.
  3. The temporary PHP constants (in tmp_multisite_constants.php) will always clash with the existing, necessary, multisite-related PHP constants in the Bedrock config.
    Why hadn't this been an issue in the past? Or has it been, and some manual setup was always expected and multisite sites are far more rare (from what I read)?

Possible solutions that I can come up with:

  1. Let Trellis itself invoke that WP CLI command to set up the multisite site before using the is installed check. The Trellis Multisite docs want this to be run manually, so there may be a reason for not doing this. That command is idempotent (it will only set up non-set up sites, so it ensures that the site is set up and skips otherwise). For a successful deploy when also installing core/plugin/theme languages on potentially not set up sites I run the WP CLI setup command on each deploy (see https://docs.roots.io/trellis/master/guides/install-wordpress-language-files/#using-wp-language-command-on-trellis-deploys:~:text=%2D-,name%3A%20Install%20WP,-(required%20for%20installing) and had no issues.
    This approach would avoid the usage of any temporary PHP constants and it would also avoid to initially, manually run that WP CLI multisite set up command after deployment.
  2. Define the multisite constants in the Bedrock site as "optional" ones, so re-defining them after the temporary PHP constants in tmp_multisite_constants.php doesn't throw PHP exceptions.

@swalkinshaw
Copy link
Member

❤️ 👏 thanks @strarsis. I'll try to replicate on a local VM

@swalkinshaw
Copy link
Member

Thinking out loud a bit... another way of identifying the "WP not installed" case is the initial or first deploy. For remote servers, the workflow is meant to be:

  1. provision server
  2. deploy
  3. manually install WP (or import an existing db)

So I can think of two options that avoid this problem entirely 🤞

Detect initial deploy

We could check if there's any existing deploys/releases in the releases path. If there's none, skip all the tasks that would have been if wp_installed was false.

This wouldn't support an edge case of someone doing multiple deploys before installing but maybe that's fine.

Don't support multisite config on initial deploy

Maybe we could enforce this programmatically, but we could also document that Trellis requires the following workflow for multisite installs:

  1. commit non-multisite configuration
  2. deploy site
  3. install WP
  4. update configuration to change site to multisite

I'm not 100% this would work though and haven't tested it yet.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 10, 2022

@swalkinshaw: Yes, this is a kind of bootstrapping issue IMHO. WordPress has to be installed in order to be either initially set up or further configured by Trellis (e.g. installing languages).
But I am also starting to think that the usage of wp is-installed has underlying issues, it just "works" better with non-multisite sites:

Trellis installs WordPress during deployment (using composer) and afterwards the WordPress site needs to run its setup or import a database dump, in the end the database tables must be in place in order for the site to work correctly.
This setup can be either performed by visiting the non-set up site in the browser and using the setup assistant GUI or by using the WP CLI wp core install command.
The wp core install command, according to the WP CLI docs,

(c)reates the WordPress tables in the database

The wp is-installed command, according to the WP CLI docs,

(d)etermines whether WordPress is installed by checking if the standard database tables are installed.

However, when Trellis deploys a site for the first time - multisite or not - only the files are copied by composer,
no database tables were set up yet. Still wp is-installed exits with a success exit code on non-multisite sites and the deploy succeeds.
(Only the Trellis development playbook includes the wordpress-install role which actually installs WordPress by invoking wp core install / wp core install-multisite).

How is wp is-installed exiting with a success status code? Are database tables created during a normal Trellis deploy?
It doesn't seem that Trellis sets up the WordPress tables on its own during deployments, or have I missed it?

Why is the is installed check used? A release should only be released (current symlink) when the WordPress site is "installed". So what does the is installed check actually verify? That a WordPress site can load at all, including the setup GUI? That just the files are in place (which would actually the job of composer)?

@swalkinshaw
Copy link
Member

How is wp is-installed exiting with a success status code?

It's not. See:

failed_when: wp_installed.stderr | default("") != "" or wp_installed.rc > 1

0 is installed, 1 is not installed. > 1 is a failure.

Are database tables created during a normal Trellis deploy? It doesn't seem that Trellis sets up the WordPress tables on its own during deployments, or have I missed it?

Correct, Trellis does nothing to the database if WP is not installed.

Why is the is installed check used?

It's used to:

  • update theme paths in the db
  • run db upgrades

All the tasks related to those would fail if we tried to run them for non-installed sites.

A release should only be released (current symlink) when the WordPress site is "installed"

I don't think I agree since deploys are mostly getting code on the server,

So what does the is installed check actually verify? That a WordPress site can load at all, including the setup GUI? That just the files are in place (which would actually the job of composer)?

Yeah it lets us know we can run WP site commands basically since the database exists.

@strarsis
Copy link
Contributor Author

strarsis commented Jun 11, 2022

@swalkinshaw: Thank you for this great and detailed explanation!
So wp core is-installed exits with 0 for an installed site, 1 for a non-installed site. > 1 when something is wrong (as 255 for a PHP fatal error).

Interestingly it also exits with 1 when it logs the database error to stderr for a non-set up multisite site!
And this is exactly as expected, the wp core is-installed tool should exit with 1, for any non-multisite or multisite site that is installed but not set up yet.
This means that the non-empty stderr from that database error dump is the underlying issue!

The Ansible check condition requires an empty stderr or an stderr that contains only the strpos needle PHP warning, otherwise it will fail, even with a wp core is-installed exit code <= 1.
So instead of exempting the strpos needle PHP warning from the non-empty stderr condition, that PHP database error stuff can be exempted instead!
The database error may look scary, sure, but in the end it is actually a PHP warning as WP CLI exits with 1 and doesn't crash with 255.
With ignoring that database error that only occurs as long as the multisite site hadn't been configured yet,
all the deployment issues are solved: No temporary PHP constants anymore, the deployment passes and the multisite site can be configured afterwards (also remotely, as the current symlink is set).

Modified roles/deploy/hooks/finalize-before.yml:

- name: WordPress Installed (multisite)?
  block:
    - name: Set variables used in "WordPress Installed (multisite)?" check
      set_fact:
        multisite_non_setup_db_error: "WordPress database error Table '{{ site_env.db_name }}.wp_blogs' doesn't exist"

    - name: "Invoke 'wp core is-installed' command"
      command: wp core is-installed --skip-plugins --skip-themes
      args:
        chdir: "{{ deploy_helper.new_release_path }}"
      register: wp_installed_multisite
      changed_when: false
      failed_when: (wp_installed_multisite.stderr | length > 0 and wp_installed_multisite.stderr is not match(multisite_non_setup_db_error)) or wp_installed_multisite.rc > 1

    - name: Set "WordPress installed?" result variable (from multisite)
      set_fact:
        wp_installed: "{{ wp_installed_multisite }}"
  when:
    - project.multisite.enabled | default(false)

After the now successful deploy, there may still be some redirection hiccups for the frontend URLs (redirection loop stuff) as the site wasn't fully set up now, which is to be expected, that site is deployed, but its configuration/content isn't prepared yet.

  • However, one can still access the setup web GUI page by directly using its URL:
    http://<a canonical host or domain_current_site>/wp/wp-admin/install.php
  • Or of course use WP CLI as stated in the Trellis Multisite docs:
    wp core multisite-install --title="site title" --admin_user="username" --admin_password="password" --admin_email="[email protected]"
  • Or using the WP CLI to import a database dump, etc.

The database error occurs as a PHP warning at its initial run, but doesn't cause any issues, the setup will complete and everything is fine.

@swalkinshaw
Copy link
Member

I hadn't really thought about just catching that specific db error, but it makes sense. It has the minor downside of being tied to a specific error string, but not sure we can avoid that. And it's definitely simpler overall; getting rid of the tmp constants is a big win 👍

Want to do a PR with it?

Thanks for all the help with this 🎉

@strarsis
Copy link
Contributor Author

@swalkinshaw: PR: #1391

@JJJ
Copy link

JJJ commented Jun 13, 2022

Just seeing all of this now. Y'all are legends. Nice work. 💙

@MikeiLL
Copy link
Contributor

MikeiLL commented Aug 3, 2022

If the ping is okay, I still seem to be having an issue with a recently rebased Trellis site.

@strarsis
Copy link
Contributor Author

strarsis commented Aug 3, 2022

@MikeiLL: See this response post: https://discourse.roots.io/t/wordpress-6-0-update-deploy-failed/23225/29?u=strarsis

@JJJ
Copy link

JJJ commented Aug 5, 2022

Should "fmp" be "fpm" ?

@MikeiLL
Copy link
Contributor

MikeiLL commented Aug 5, 2022

Duh! FastCGI Process Manager. Lost in the weeds, was I.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: Autodeploy failures with WordPress 6.0
5 participants