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

Allow non-read-only external libraries that support asset deletion #8943

Closed
wants to merge 3 commits into from

Conversation

valpackett
Copy link

Related: #5449 #8438
Sponsored by: @benmccann

This is an attempt at switching from hardcoded "external means cannot delete" to an explicit isReadOnly flag for libraries. (Not fully polished change yet, hence draft)

The per-asset isExternal and isReadOnly flags being stored in the database is making this difficult… I guess just using them and updating them while the library's read-onliness changes would be significantly easier than removing them and making everywhere query the library flags, but I'm looking for feedback re: the right way to do this.

@bo0tzz bo0tzz added 🗄️server external-library Issues related to external libraries labels Apr 20, 2024
@alextran1502
Copy link
Contributor

I think the most natural change of this feature is to let the user know they can mount the library with ro or without that flag for docker mount; then, we can treat external library assets as normal upload assets to avoid introducing an additional boolean flag in the system. What do you think?

@valpackett
Copy link
Author

Hm. That would mean checking mount info (only on boot? on rescan too?) and updating the flags based on that. Seems nice in terms of not adding any admin UI. I'm slightly worried about potential surprising behavior (e.g. adding a writable mount, possibly for multiple libraries inside of it, and adding libraries in the admin interface, not expecting them to be automatically writable) but on the other hand "it's a purely outside configured sysadmin level decision" does feel nice in a way.

Not sure we'd actually avoid the flag on the library, even if it would get set automatically based on the mount: it would definitely make sense to show in the admin interface whether it is writable, and have that fully consistent with what we've set for the assets…

@alextran1502
Copy link
Contributor

@etnoy I am pretty sure isReadOnly flag isn't used anymore after we move to your implementation of external library, correct? It was for the previous import mechanism

@alextran1502
Copy link
Contributor

Hm. That would mean checking mount info (only on boot? on rescan too?) and updating the flags based on that. Seems nice in terms of not adding any admin UI. I'm slightly worried about potential surprising behavior (e.g. adding a writable mount, possibly for multiple libraries inside of it, and adding libraries in the admin interface, not expecting them to be automatically writable) but on the other hand "it's a purely outside configured sysadmin level decision" does feel nice in a way.

Not sure we'd actually avoid the flag on the library, even if it would get set automatically based on the mount: it would definitely make sense to show in the admin interface whether it is writable, and have that fully consistent with what we've set for the assets…

I am thinking more of, if the user know that they use the ro flag in docker mount, the deletion call will error out expectedly, otherwise, the operation will happen as if it the assets are from the upload library. So we don't necessary need to do anything special here in term of checking the state of read/write of the mount

@etnoy
Copy link
Contributor

etnoy commented Apr 20, 2024

@etnoy I am pretty sure isReadOnly flag isn't used anymore after we move to your implementation of external library, correct? It was for the previous import mechanism

That is my understanding, too.

I've argued for removing the field but I think @jrasm91 knew of something that still used it

@jrasm91
Copy link
Contributor

jrasm91 commented Apr 21, 2024

I would recommend keeping the per asset flags. Otherwise it will probably be a nightmare trying to load in the property everywhere it needs to be used. If a library is marked as read only, it seems easy enough to do a bulk asset update

Copy link
Contributor

@jrasm91 jrasm91 left a comment

Choose a reason for hiding this comment

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

This seems fine, but should be simplified. Furthermore, when a library is updated and readonly changes we should SQL update the affected assets.

@@ -128,6 +131,8 @@ export class LibraryResponseDto {
createdAt!: Date;
updatedAt!: Date;
refreshedAt!: Date | null;

isReadOnly!: boolean | null;
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't nullable.

@@ -53,6 +53,9 @@ export class LibraryEntity {

@Column({ type: 'boolean', default: true })
isVisible!: boolean;

@Column({ type: 'boolean', nullable: true })
isReadOnly!: boolean | null;
Copy link
Contributor

Choose a reason for hiding this comment

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

This should not be nullable and should default to true

// Ignore requests that are not from external library job but is for an external read-only asset
const isReadOnlyLibrary = !asset.library || asset.library.isReadOnly ||
(asset.library.isReadOnly === null && asset.library.type === LibraryType.EXTERNAL);
if (!fromExternal && isReadOnlyLibrary) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should just check if from external and the asset is read only and skip if so. No reason to make it complicated.

@@ -406,7 +408,7 @@ export class AssetService {
}

const files = [asset.thumbnailPath, asset.previewPath, asset.encodedVideoPath];
if (!(asset.isExternal || asset.isReadOnly)) {
if (!isReadOnlyLibrary) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If asset isn't readonly

@@ -193,7 +193,7 @@
{/if}

{#if isOwner}
{#if !asset.isReadOnly || !asset.isExternal}
{#if !asset.isReadOnly || !asset.isExternal || (true /* XXX */)}
Copy link
Contributor

Choose a reason for hiding this comment

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

Just change this to asset not read only

const prevValue = library.isReadOnly == null ? (library.type === LibraryType.External) : library.isReadOnly;

try {
await updateLibrary({ id: library.id, updateLibraryDto: { ...library, isReadOnly: !prevValue } });
Copy link
Contributor

Choose a reason for hiding this comment

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

Please don't send the whole dto. Just send the read only setting.

@@ -397,6 +410,12 @@
<Portal target="body">
<ContextMenu {...contextMenuPosition} on:outclick={() => onMenuExit()}>
<MenuOption on:click={() => onRenameClicked()} text={`Rename`} />
<MenuOption
on:click={() => onToggleReadOnlyClicked()}
text={(selectedLibrary?.isReadOnly ||
Copy link
Contributor

Choose a reason for hiding this comment

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

This should not be nullable

Copy link
Contributor

Choose a reason for hiding this comment

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

we could probably change the {#if showContextMenu} above to {#if showContextMenu && selectedLibrary} to simplify all the accesses to selectedLibrary within

@@ -8778,6 +8778,10 @@
},
"type": "array"
},
"isReadOnly": {
"nullable": true,
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 this shouldn't be nullable either

@jrasm91
Copy link
Contributor

jrasm91 commented May 3, 2024

Hey, thanks for working on this and sorry for the confusion/back and forth around this topic. Internally we have had a lot of discussions about the direction we want to take external libraries. Long story short, we decided to go ahead with the implementation laid out in #9235.

@jrasm91 jrasm91 closed this May 3, 2024
@valpackett valpackett deleted the library-rdonly branch May 3, 2024 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external-library Issues related to external libraries 🗄️server
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants