-
Notifications
You must be signed in to change notification settings - Fork 173
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
Conversation
tools/update.php
Outdated
|
||
/** | ||
* Updates source code and dependencies for LORIS. Outputs missing patch files | ||
* based on verion information |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should have an ended dot (.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
tools/update.php
Outdated
); | ||
$paths = $config->getSetting('paths'); | ||
$loris_root_dir = $paths['base']; | ||
$backup_dir = "/tmp/bkp-LORIS"; // TODO: should this be configurable? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should be configurable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now configurable
$A = $db_config['database']; | ||
$u = $db_config['username']; | ||
$p = $db_config['password']; | ||
$h = $db_config['host']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
descriptive variable names would be better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ZainVirani I have added this functionality. Thanks for the suggestion!
tools/update.php
Outdated
// @codingStandardsIgnoreEnd | ||
. PHP_EOL . PHP_EOL; | ||
sleep(3); | ||
main(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I 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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is now a confirm flag present.
These changes have been incorporated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBU
$patch_dir = $loris_root . 'SQL/Release_patches/'; | ||
$all_release_patches = glob($patch_dir . '*.sql'); | ||
$patches = []; | ||
if ($diff_major > 0 || $diff_minor > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this cannot be supported in this script
What specifically can't be supported? I'm not sure I understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
PRE_19.0.sql
-> project patches18.0_To_19.0.sql
-> loris patchesPOST_19.0.sql
-> project patchesPRE_20.0.sql
-> project patches19.0_to_20.0.sql
-> loris patchesPOST_20.0.sql
-> project patches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know about this process for projects.
If it's just one release you could do
- Source
PRE
patch. - Run script.
- 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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the release patch is the concatenation of the patches in Archive
why are you readding them here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets talk
TODO: Add single-use patches to update process |
@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()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already done at line 79. This line is in extra
@PapillonMcGill Thanks, I've incorporated your feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work,
will help greatly to let user update their version.
@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( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented the "very Ideal way" 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
always better to use true
as 3rd arg when using in_array()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same for all below
tools/update.php
Outdated
if (updateSourceCode($loris_root_dir, $backup_dir)) { | ||
echo '[+] LORIS source code files successfully updated.' . PHP_EOL; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't it check the php version, apache version, mysql version before starting ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been added
Remove duplicate line. Add case where installed minor version is ahead of latest release version when major versions are equal. Remove unrelated script.
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? |
Co-Authored-By: johnsaigle <4022790+johnsaigle@users.noreply.github.com>
Co-Authored-By: johnsaigle <4022790+johnsaigle@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pending Travis
@johnsaigle Can you re-issue it when/if its done to get a clean history ? closing for now |
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
PHP_CLI_Helper.class.inc
provides some functions for nice output and can be re-used by other scripts. It is also used in [Tools] Ubuntu production environment "bootstrap" script #3981.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.