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

Allowing custom folder name for plugin installation #446

Conversation

VachaShah
Copy link
Contributor

@VachaShah VachaShah commented Jun 4, 2021

Signed-off-by: Vacha Shah [email protected]

Description

This PR allows plugin owners to specify a custom folder name for plugin cli installation and override the folder name. This custom folder name can be specified in opensearch_dashboards.json for the plugin. If the folder name is specified in the opensearch_dashboards.json, the plugin is installed using the custom folder name as is specified for the plugin, else the id of the plugin is used in kebab-case.

Testing

The unit tests have been added. Also tested with a plugin anomaly-detection-dashboards-plugin, I have added an attribute in opensearch_dashboards.json as follows:

{
  "id": "anomalyDetectionDashboards",
  "folderName": "customFolder",
  "version": "1.0.0.0-beta1",
  "opensearchDashboardsVersion": "1.0.0-beta1",
  "configPath": ["anomaly_detection_dashboards"],
  "requiredPlugins": ["navigation"],
  "optionalPlugins": [],
  "server": true,
  "ui": true
}

Using the above settings, I installed the plugin using:

./opensearch-dashboards-plugin install file://<path to build zip for the plugin> 

The above command installs the plugin as:
customFolder

Issues Resolved

Part 3 and 4 of #322.

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed per the DCO using --signoff

@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed c23c30e

@opensearch-ci-bot
Copy link
Collaborator

❌   DCO Check Failed ffa60d1
Run ./dev-tools/signoff-check.sh remotes/origin/main ffa60d1cb32801517220cb8a52c6b79d9b91aecd to check locally
Use git commit with -s to add 'Signed-of-by: {EMAIL}' on impacted commits

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from ffa60d1 to 86111b9 Compare June 4, 2021 23:57
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed 86111b9

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from 86111b9 to 5fa4e2f Compare June 5, 2021 00:28
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed 5fa4e2f

Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

I think naming should be standardized. it looks like pluginFolder is an existing thing, soI would call the option pluginFolderas well, or targetPluginFolder.

@@ -64,6 +64,7 @@ export function installCommand(program) {
'length of time before failing; 0 for never fail',
parseMilliseconds
)
.option('-o, --override', 'override the folder name for plugin installation')
Copy link
Member

Choose a reason for hiding this comment

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

Should this match the folderName name? Aka --folderName= (can still be -o for the short version)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the option to --folderName.

@@ -59,11 +59,14 @@ export async function install(settings, logger) {

del.sync(settings.tempArchiveFile, { force: true });

settings.plugins[0].pluginFolder = settings.override
Copy link
Member

Choose a reason for hiding this comment

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

We should be using the same name everywhere, if the option is folderName, then this would also be folderName and settings.folderName.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made the naming consistent.

@opensearch-ci-bot
Copy link
Collaborator

❌   DCO Check Failed d45105d
Run ./dev-tools/signoff-check.sh remotes/origin/main d45105da3b1a00f53185ded958f0cd14563ee199 to check locally
Use git commit with -s to add 'Signed-of-by: {EMAIL}' on impacted commits

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from d45105d to fb00d2f Compare June 7, 2021 18:54
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed fb00d2f

@VachaShah VachaShah requested a review from dblock June 7, 2021 19:11
Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

I missed this in the first review, apologies. I think the value of folderName that's passed by the user should be used as-is, and not kebab-cased. It would be really confusing to users if I were to specify --folderName=myPlugin and end up with my-plugin, don't you think? Some test coverage of the above is needed in that case, too, then.

Thus, I think I'd want a property, settings.plugins[0].folderName, that defaults to kebabcase(id) on construction or some other place, and is overridden by -o. Move the calls to kebabcasing into whenever that value is assigned, so that we would reference it everywhere consistently. Also easier to test.

@VachaShah
Copy link
Contributor Author

I missed this in the first review, apologies. I think the value of folderName that's passed by the user should be used as-is, and not kebab-cased. It would be really confusing to users if I were to specify --folderName=myPlugin and end up with my-plugin, don't you think? Some test coverage of the above is needed in that case, too, then.

The --folderName is a boolean flag to allow the cli to override the folder name, the folder name would be specified in the opensearch_dashboards.json file by the user just like the id, which would then be converted to kebab-case to follow the naming convention. The json file would look like this:

{
  "id": "anomalyDetectionDashboards",
  "folderName": "customFolder",
  "version": "1.0.0.0-beta1",
  "opensearchDashboardsVersion": "1.0.0-beta1",
  "configPath": ["anomaly_detection_dashboards"],
  "requiredPlugins": ["navigation"],
  "optionalPlugins": [],
  "server": true,
  "ui": true
}

I kept the conversion to kebab-case to keep the naming convention consistent. LMK what you think.

@dblock
Copy link
Member

dblock commented Jun 7, 2021

The --folderName is a boolean flag to allow the cli to override the folder name, the folder name would be specified in the opensearch_dashboards.json file by the user just like the id, which would then be converted to kebab-case to follow the naming convention. The json file would look like this:

{
  "id": "anomalyDetectionDashboards",
  "folderName": "customFolder",
  "version": "1.0.0.0-beta1",
  "opensearchDashboardsVersion": "1.0.0-beta1",
  "configPath": ["anomaly_detection_dashboards"],
  "requiredPlugins": ["navigation"],
  "optionalPlugins": [],
  "server": true,
  "ui": true
}

I kept the conversion to kebab-case to keep the naming convention consistent. LMK what you think.

Oh this is not at all how I understood this and is quite unusual! The developers of the plugin should be able to decide where the plugin is installed by default. This is how I believe this feature should be designed.

  1. If I don't specify folderName in opensearch_dashboards.json then kebab_case(id) is used.
  2. If I specify folderName in opensearch_dashboards.json, it's used "as is".
  3. If I specify --folderName=X during installation, X is used as folder name.

That seems much more straightforward, doesn't it?

@VachaShah
Copy link
Contributor Author

Oh this is not at all how I understood this and is quite unusual! The developers of the plugin should be able to decide where the plugin is installed by default. This is how I believe this feature should be designed.

The first two points are definitely straightforward. For the third one, I think if the user is allowed to enter the plugin folder name in the cli command itself, it will result in problems during the next install of the same plugin. When a plugin is installed, the logic first checks for an existing installation, this is checked using the plugin's id and the plugin's folderName both specified in the opensearch_dashboards.json. If the installation already exists, the user is given an error specifying the issue. If the folder name is given through cli using --folderName=X, there will be no way for the logic to check for existing installation next time and it will result in the same plugin being installed more than once. Do you think we should skip the point 3?

@dblock
Copy link
Member

dblock commented Jun 8, 2021

Oh this is not at all how I understood this and is quite unusual! The developers of the plugin should be able to decide where the plugin is installed by default. This is how I believe this feature should be designed.

The first two points are definitely straightforward. For the third one, I think if the user is allowed to enter the plugin folder name in the cli command itself, it will result in problems during the next install of the same plugin. When a plugin is installed, the logic first checks for an existing installation, this is checked using the plugin's id and the plugin's folderName both specified in the opensearch_dashboards.json. If the installation already exists, the user is given an error specifying the issue. If the folder name is given through cli using --folderName=X, there will be no way for the logic to check for existing installation next time and it will result in the same plugin being installed more than once. Do you think we should skip the point 3?

Makes sense to me, agreed.

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from fb00d2f to 8a8327a Compare June 8, 2021 20:11
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed 8a8327a

@VachaShah VachaShah requested a review from dblock June 8, 2021 21:28
@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from 8a8327a to 58edde7 Compare June 11, 2021 22:35
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed 58edde7

Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

Please refactor and add tests for the refactored folder name function. This also needs tests for that the target directory is settings.folderName when specified, and is kebab-case of id when not.

@@ -63,7 +63,10 @@ export async function install(settings, logger) {

assertVersion(settings);

const targetDir = path.join(settings.pluginDir, kebabCase(settings.plugins[0].id));
const folderName = settings.plugins[0].folderName
Copy link
Member

@dblock dblock Jun 14, 2021

Choose a reason for hiding this comment

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

Can this condition move into a targetFolderName() method in settings (might need to be extended into a class with methods), and use .targetFolderName() everywhere it's needed? This would avoid duplication, be more OOO, and would be easy to write unit tests against.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this to getTargetFolderName() function.

@@ -47,6 +47,18 @@ export function existingInstall(settings, logger) {
} catch (e) {
if (e.code !== 'ENOENT') throw e;
}
if (settings.plugins[0].folderName !== '') {
Copy link
Member

Choose a reason for hiding this comment

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

The duplicate check for both .id and .folderName is telling me that there should only be one check here, instead of .id it would be using .targetFolderName().

Copy link
Contributor Author

@VachaShah VachaShah Jun 14, 2021

Choose a reason for hiding this comment

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

Updated the logic to check for the targetFolderName.

@@ -82,6 +82,10 @@ export function analyzeArchive(archive) {
plugins.push({
id: manifest.id,
stripPrefix: match[1],
folderName:
Copy link
Member

@dblock dblock Jun 14, 2021

Choose a reason for hiding this comment

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

This should just be .manifest.folderName. There's nothing wrong with a null value, it shouldn't become blank if it's not set. If you move the logic to resolve targetFolderName into a function you can check for null or blank there and return id if the value of folderName is either.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to move the logic to getTargetFolderName function.

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from 58edde7 to 7b02a01 Compare June 15, 2021 21:40
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed 7b02a01

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from 7b02a01 to fcc3bdc Compare June 15, 2021 22:17
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed fcc3bdc

@VachaShah VachaShah requested a review from dblock June 16, 2021 04:59
Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

A lot cleaner! What's this removed code? Otherwise LGTM.

@@ -38,10 +38,11 @@ import { versionSatisfies, cleanVersion } from '../../legacy/utils/version';

export function existingInstall(settings, logger) {
try {
statSync(path.join(settings.pluginDir, kebabCase(settings.plugins[0].id)));
Copy link
Member

Choose a reason for hiding this comment

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

You may have been right to worry that previous versions of plugins may have been installed into settings.plugins[0].id (1.1 installation on top of 1.0). Is that a valid concern. If so, make an array of all possible folder names, and do a foreach on them to check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One of the cases I can think of now is the user first used the id of the plugin to install it, then added a folderName property to opensearch_dashboards.json and tried installing again. It should fail saying the plugin is already installed. I will add both the checks to be on the safer side.

logger.log(pkg.id + '@' + pkg.version);
} catch (e) {
throw new Error('Unable to read opensearch_dashboards.json file for plugin ' + name);
}
Copy link
Member

Choose a reason for hiding this comment

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

What's the reason to remove this?

Copy link
Contributor Author

@VachaShah VachaShah Jun 16, 2021

Choose a reason for hiding this comment

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

For the list command, the output printed was <pluginId>@<pluginVersion> but this same output could not be used in the remove command, this was mentioned in the same issue #322 in the latest comments, I removed this so that the actual folder name can be printed which the user can use to remove the plugin with the remove command. LMK if you think this could be better.

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from fcc3bdc to 72cc7e6 Compare June 16, 2021 19:01
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed 72cc7e6

@VachaShah VachaShah force-pushed the allow_custom_folder_name_for_plugins branch from 72cc7e6 to a2ff1fd Compare June 16, 2021 20:13
@opensearch-ci-bot
Copy link
Collaborator

✅   DCO Check Passed a2ff1fd

@VachaShah VachaShah requested a review from dblock June 16, 2021 21:21
Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

Looks good. Maybe someone from Dashboards wants to review this as well, since I'm not super familiar with the codebase - @mihirsoni maybe?

@VachaShah
Copy link
Contributor Author

Going to close this PR, can be picked up when required.

@VachaShah VachaShah closed this Sep 8, 2021
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.

3 participants