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

[Tools] Script to automate LORIS SQL patching #3677

Closed
wants to merge 48 commits into from
Closed

[Tools] Script to automate LORIS SQL patching #3677

wants to merge 48 commits into from

Conversation

johnsaigle
Copy link
Contributor

@johnsaigle johnsaigle commented May 17, 2018

This PR has been heavily refactored so a lot of the conversation is outdated.

Overview

The script will display to a user which patches they need to apply, in order. By passing the argument --apply-patches a user can have the update script apply SQL patch files to their database automatically.

Details

The function to retrieve patches is heavily dependent on the way we organize and name SQL files. If the directory structure changes, this functionality of the script is likely to break.

To Test

Run the script on your LORIS! Report anything weird or confusing.

@johnsaigle johnsaigle added Feature PR or issue introducing/requiring at least one new feature [branch] minor labels May 17, 2018
tools/update.php Outdated

/**
* Updates source code and dependencies for LORIS. Outputs missing patch files
* based on verion information
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should have an ended dot (.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

tools/update.php Outdated
);
$paths = $config->getSetting('paths');
$loris_root_dir = $paths['base'];
$backup_dir = "/tmp/bkp-LORIS"; // TODO: should this be configurable?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this should be configurable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now configurable

$A = $db_config['database'];
$u = $db_config['username'];
$p = $db_config['password'];
$h = $db_config['host'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

descriptive variable names would be better

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are descriptive to the extent that they match the flags for mysql on the command line.

tools/update.php Outdated
$cmd = "mysql -h $h -u $u -p -A $A < $patch";
if ($report_only === false) {
if (doExec($cmd) === false) {
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if I understand correctly, if a patch fails, doExec should spit out the error and this loop will break (and the script will terminate as this is the last action in main())

I think before breaking the rest of the commands should be output to the user along with a message indicating that the rest of the commands were not run. I figure if this didn't happen a user would just try to rerun this script which could make things worse.

Copy link
Contributor Author

@johnsaigle johnsaigle Jun 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZainVirani that's a good point. I'll come back to this pending the conversation as to whether this script should even apply patches or if it should just print them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZainVirani I have added this functionality. Thanks for the suggestion!

tools/update.php Outdated
// @codingStandardsIgnoreEnd
. PHP_EOL . PHP_EOL;
sleep(3);
main();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be best if the script required a -confirm to actually update, and without it would just spew out some help text (and the newest release version # so users can be sure they want to update), just so this script is never accidentally started

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is now a confirm flag present.

tools/update.php Outdated Show resolved Hide resolved
tools/update.php Outdated Show resolved Hide resolved
tools/update.php Outdated Show resolved Hide resolved
@johnsaigle johnsaigle added the Discussion Required PR or issue awaiting the resolution of a discussion between all involved parties label Jun 11, 2018
@johnsaigle johnsaigle removed the Discussion Required PR or issue awaiting the resolution of a discussion between all involved parties label Jun 12, 2018
@johnsaigle johnsaigle changed the title [Tools] Automated update script [Tools] Automatic update script Jun 12, 2018
@johnsaigle johnsaigle dismissed ZainVirani’s stale review June 12, 2018 18:02

These changes have been incorporated

@johnsaigle johnsaigle changed the title [Tools] Automatic update script [Tools] Script to automate LORIS update process Jun 12, 2018
@maltheism maltheism added the Passed Manual Tests PR has undergone proper testing by at least one peer label Jun 18, 2018
@johnsaigle johnsaigle added this to the 20.1.0 milestone Jul 4, 2018
tools/update.php Outdated
*
* @param string $loris_root_dir The directory where LORIS is installed
* @param string $backup_dir The directory prefix where backups are stored.
* Always '/tmp/loris_' for now
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not anymore as it is read from the CLI

tools/update.php Outdated
* @param string $backup_dir The directory prefix where backups are stored.
* Always '/tmp/loris_' for now
*
* @return bool True if rsync executes successfully, false otherwise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the @param and @return should all end with a dot or not for consistency

tools/update.php Outdated
if (empty($tarball_path)) {
die('ERROR: Could not download the latest LORIS release.');
}
$dst_dir = '/tmp/'; // Parent directory for backup and release download
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should be updated to remove backup

tools/update.php Outdated
}
echo "[**] Latest version $version_to is ahead of installed $version_from "
. "by $diff_major MAJOR release(s), $diff_minor MINOR release(s)."
. PHP_EOL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could end up as Latest version 22.0 is ahead of installed 21.3 by 1 MAJOR release(s), -3 MINOR release(s).

This negative minor can be quite confusing. I suggest to remove the minor part when major is > 0.

tools/update.php Outdated
/**
* Apply a list of SQL patch files using exec. Currently this function is only
* called with $report_only = true so patches are never applied. This can be
* changed in the future if this functionality is required.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment need to be updated

tools/update.php Outdated
* @param dictionary $db_config DB config info. Needed for credentials
* @param bool $apply_patches If true, MySQL commands will be run
*
* @return bool Always true (for now). False if patches fail to be applied.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBU

tools/update.php Show resolved Hide resolved
@johnsaigle johnsaigle mentioned this pull request Jul 16, 2018
$patch_dir = $loris_root . 'SQL/Release_patches/';
$all_release_patches = glob($patch_dir . '*.sql');
$patches = [];
if ($diff_major > 0 || $diff_minor > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johnsaigle most of the time projects will need to apply project specif SQL in between 2 releases to prepare the database, this cannot be supported in this script

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this cannot be supported in this script

What specifically can't be supported? I'm not sure I understand.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assume I'm 2 releases behind, for each release I have PRE and POST custom SQL patches designed for my project (thats usually the case for any project upgrading). how can I run them using your script as follows:

  1. PRE_19.0.sql -> project patches
  2. 18.0_To_19.0.sql -> loris patches
  3. POST_19.0.sql -> project patches
  4. PRE_20.0.sql -> project patches
  5. 19.0_to_20.0.sql -> loris patches
  6. POST_20.0.sql -> project patches

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know about this process for projects.

If it's just one release you could do

  1. Source PRE patch.
  2. Run script.
  3. Source POST patch.

I'm not sure how to handle the case where a project is more than 1 major release behind. If there is a standard location and naming convention for the files it would probably be possible to do these checks. Is that the case? Do you have any suggestions for how to incorporate this feature?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in person, the script will be amended to not do SQL patching if the installed LORIS version is more than 1 major version behind the latest release, as it's difficult to automate and likely quite risky.

The script will display a message informing the user that the update process is complete in terms of src code, packages, etc. but that they will need to apply patches manually.

tools/update.php Outdated
. PHP_EOL;

// Add all patches in Archive/$MAJOR.$MINOR. Everything other needed
// command will be in the Release patches which are been added above
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the release patch is the concatenation of the patches in Archive why are you readding them here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right... I guess this should be New_patches. I remember at some point we were actually putting new patches in Archive so I based this on that.

I'll update this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets talk

@johnsaigle johnsaigle added the Discussion Required PR or issue awaiting the resolution of a discussion between all involved parties label Jul 17, 2018
@johnsaigle
Copy link
Contributor Author

TODO: Add single-use patches to update process

@johnsaigle johnsaigle added the Needs Work PR awaiting additional changes by the author or contains issues that the author needs to fix label Aug 27, 2018
@johnsaigle johnsaigle removed the Needs Work PR awaiting additional changes by the author or contains issues that the author needs to fix label Sep 4, 2018
@johnsaigle
Copy link
Contributor Author

@ridz1208 @PapillonMcGill Please re-review when you can.

tools/update.php Outdated
}
// Require a confirm flag so this script is not accidentally run
if (!in_array('--confirm', $argv)) {
$info = json_decode(getLatestReleaseInfo());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already done at line 79. This line is in extra

tools/update.php Show resolved Hide resolved
tools/update.php Outdated Show resolved Hide resolved
modules/login/ajax/verificationimage.php Outdated Show resolved Hide resolved
@johnsaigle
Copy link
Contributor Author

@PapillonMcGill Thanks, I've incorporated your feedback.

PapillonMcGill
PapillonMcGill previously approved these changes Sep 6, 2018
Copy link
Contributor

@PapillonMcGill PapillonMcGill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work,

will help greatly to let user update their version.

@driusan driusan removed this from the 20.1.0 milestone Sep 6, 2018
@johnsaigle
Copy link
Contributor Author

@driusan Could you review this when you get a chance? It's been ready for final review for about a month

tools/update.php Outdated
/* Create db connection and get version info. */
$config = \NDB_Config::singleton();
$db_config = $config->getSetting('database');
$db = \Database::singleton(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that might be problematic if the release patch requires admin credentials. (generally it shouldn't but all release patches have probably been run as admins to this day) just investigate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it depends on the privileges of the SQL user, e.g. whether they can do ALTER, CREATE etc. That'll depend in a large part on the administrator of the system and how they set up their databases.

I think in the worst case MySQL will give an error about not having the right permissions and the script will continue onward which shouldnt cause issues as patch application is the last step.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it still places the DB is a half-update state and thats generally very difficult to recover front. A very Ideal way to tackle this would be to see what privileges are needed for a specific patch and verify if user have them.

the realistic way of doing this would be to add a notice before the run that says that all SQL patches are run as a regular user ORRR to use the quat credentials when/if they are available ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented the "very Ideal way" 😸

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im very ideally impressed

tools/update.php Outdated
}
// Only apply SQL patches if user explicitly requests it
$apply_patches = false;
if (in_array('--apply-patches', $argv)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always better to use true as 3rd arg when using in_array()

see http://php.net/manual/en/function.in-array.php#106319

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for all below

tools/update.php Outdated
if (updateSourceCode($loris_root_dir, $backup_dir)) {
echo '[+] LORIS source code files successfully updated.' . PHP_EOL;
}

Copy link
Collaborator

@ridz1208 ridz1208 Oct 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it check the php version, apache version, mysql version before starting ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for example 20.0.0 requires apache 2.4 if the update runs without prompting for it, everything is gonna look fine but the website will not be functional

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is a good idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been added

@johnsaigle johnsaigle changed the title [Tools] Script to automate LORIS update process [Tools] Script to automate LORIS SQL patching Jan 3, 2019
@johnsaigle johnsaigle added Needs Work PR awaiting additional changes by the author or contains issues that the author needs to fix and removed Needs Work PR awaiting additional changes by the author or contains issues that the author needs to fix labels Jan 23, 2019
tools/update.php Outdated Show resolved Hide resolved
tools/update.php Outdated Show resolved Hide resolved
@driusan
Copy link
Collaborator

driusan commented Jan 28, 2019

Regarding the "This PR has been heavily refactored so a lot of the conversation is outdated.", can you close it and send a new PR (when the refactoring is done) so that it's clear what's up to date and what's irrelevant?

PapillonMcGill and others added 2 commits January 28, 2019 10:43
Co-Authored-By: johnsaigle <4022790+johnsaigle@users.noreply.github.com>
Co-Authored-By: johnsaigle <4022790+johnsaigle@users.noreply.github.com>
Copy link
Contributor

@PapillonMcGill PapillonMcGill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending Travis

@ridz1208
Copy link
Collaborator

ridz1208 commented Feb 1, 2019

@johnsaigle Can you re-issue it when/if its done to get a clean history ?

closing for now

@ridz1208 ridz1208 closed this Feb 1, 2019
@driusan driusan removed this from Review in Roadmap Aug 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature PR or issue introducing/requiring at least one new feature Needs Work PR awaiting additional changes by the author or contains issues that the author needs to fix Priority: High PR or issue should be prioritised over others for review and testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants