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

jellyfin 10.5.5 -> 10.6.0 #93654

Merged
merged 2 commits into from Aug 19, 2020
Merged

jellyfin 10.5.5 -> 10.6.0 #93654

merged 2 commits into from Aug 19, 2020

Conversation

Church-
Copy link

@Church- Church- commented Jul 22, 2020

Motivation for this change

Jellyfin 10.6.0 was released, large feature set change

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@lsix
Copy link
Member

lsix commented Jul 23, 2020

Hi, Thanks for the contribution!

Apparently, the homepage redirects to https://jellyfin.org/. Maybe you can update the meta.homepage attribute too.

Appart from that, this looks good to me.

@lsix
Copy link
Member

lsix commented Jul 23, 2020

I have also checked the nixos test (nix-build nixos/tests/jellyfin.nix).

@Church-
Copy link
Author

Church- commented Jul 23, 2020

Sure, let me update that!

@minijackson
Copy link
Member

The release notes strongly suggest doing backups of the state directory in case of a rollback, which can't be done automatically from this new version. Is there something we should do to prevent some unwanted surprises for users of the jellyfin module?

In my opinion, it's also something to keep in mind for the NixOS release notes, too

@Church-
Copy link
Author

Church- commented Jul 23, 2020

I was going to suggest adding a blurb in the release notes that you should make a backup, etc, etc.
I'm wondering if the service can't be patched to make a backup on next run.
cp -r /var/lib/jellyfin /var/lib/jellyfin.backup or something. Stick it with a conditional in a preExec step in the service.

@Church-
Copy link
Author

Church- commented Jul 24, 2020

Something like the above could possibly suffice for at least allowing the users to rollback if needed after upgrading to 10.6.0.

Along with a by-line in the release notes for this package.

@minijackson
Copy link
Member

minijackson commented Jul 24, 2020

I'm personally not a fan of doing the backups this way, it seems to me a bit orthogonal to the nixos way: not configurable, and done without mentioning it to the users. The only way for them to see that this backup is done is either by being aware of this PR, reading the source code before nixos-rebuild switch, or reading the release notes when they are here.

It also introduces a new directory under /var/lib, which kinda breaks some assumptions about jellyfin data when you read the systemd unit file?

But, I might need a second opinion on this

@Church-
Copy link
Author

Church- commented Jul 24, 2020

That is true, and I do agree.
Maybe include it as an option?
Something like:

jellyfin = {
  enable_backups = true;
   }

If set to true then tar.gz up the dir and place it somewhere.
Where I'm not certain.

Could model it off a similar option in gitea.

But really it seems like folks are going to either need to read the release notes at some point or be aware of breaking changes. There's only so much we can do I think.

Unless we can have some way to detect they're upgrading to 10.6.0 and backup their data dir + dump a message to stdout for them.

@minijackson
Copy link
Member

Jellyfin 10.6.1 released a few hours ago, could you update the derivation?

@lsix
Copy link
Member

lsix commented Jul 28, 2020

Reguarding the question of the module storage part, one approach that can be to do something like:

      serviceConfig = rec {
        User = cfg.user;
        Group = cfg.group;
        StateDirectory = "jellyfin";
        CacheDirectory = "jellyfin";
        db_version = pkgs.lib.versions.majorMinor pkgs.jellyfin.version;
        ExecStart = "${pkgs.jellyfin}/bin/jellyfin --datadir '/var/lib/${StateDirectory}/${db_version}' --cachedir '/var/cache/${CacheDirectory}'";
        Restart = "on-failure";
      };

This is the kind of approach that is used for postgresql. This is not perfect since after an upgrade you tend to have old state dir that dangle around forever. But if the main concern is about keeping old version of the data before a major upgrade, it kind of does the trick (considering that you never actually upgrade, but only create a fresh instance).

@Church-
Copy link
Author

Church- commented Jul 28, 2020

Reguarding the question of the module storage part, one approach that can be to do something like:

      serviceConfig = rec {
        User = cfg.user;
        Group = cfg.group;
        StateDirectory = "jellyfin";
        CacheDirectory = "jellyfin";
        db_version = pkgs.lib.versions.majorMinor pkgs.jellyfin.version;
        ExecStart = "${pkgs.jellyfin}/bin/jellyfin --datadir '/var/lib/${StateDirectory}/${db_version}' --cachedir '/var/cache/${CacheDirectory}'";
        Restart = "on-failure";
      };

This is the kind of approach that is used for postgresql. This is not perfect since after an upgrade you tend to have old state dir that dangle around forever. But if the main concern is about keeping old version of the data before a major upgrade, it kind of does the trick (considering that you never actually upgrade, but only create a fresh instance).

That actually is a good idea. Wonderful, thank you. I'll make those modifications soon as I get the chance today.

@lsix My only question is, does this mean setup will have to be done anew after every upgrade?

Jellyfin 10.6.1 released a few hours ago, could you update the derivation?

Yep definitely, should help some with the mem leaks this version can have.

@lsix
Copy link
Member

lsix commented Jul 29, 2020

It overall looks good. From what I see:

  • You should squash your commits. Probably into 2 commits: one for the package update, and one for the module change,
  • The state dir could probably be a module option. This way someone can just choose to set a version-independent folder and never worry about it (but I guess this is an option),
  • You should probably add a release note in nixos/doc/manual/release-notes/rl-2009.xml to warn users of the configuration change

(If you need help with point 2, reach out)

@lsix My only question is, does this mean setup will have to be done anew after every upgrade?

As it is, yes (for every « major » upgrade ; not for a minor, such as 10.6.0 -> 10.6.1). We might want to be a bit more clever about this, and maybe ass a preStart script that will check if the current state dir is empty and if an older one can be found, then copy from the old one to the new and let jellyfin take care of the internal structure upgrade.

@Church-
Copy link
Author

Church- commented Jul 29, 2020

It overall looks good. From what I see:

* You should squash your commits. Probably into 2 commits: one for the package update, and one for the module change,

* The state dir could probably be a module option. This way someone can just choose to set a version-independent folder and never worry about it (but I guess this is an option),

* You should probably add a release note in `nixos/doc/manual/release-notes/rl-2009.xml` to warn users of the configuration change

(If you need help with point 2, reach out)

@lsix My only question is, does this mean setup will have to be done anew after every upgrade?

As it is, yes (for every « major » upgrade ; not for a minor, such as 10.6.0 -> 10.6.1). We might want to be a bit more clever about this, and maybe ass a preStart script that will check if the current state dir is empty and if an older one can be found, then copy from the old one to the new and let jellyfin take care of the internal structure upgrade.

All good points, a preStart step might be a good idea ya.

As far as squashing git commits, things are somewhat inter leavened I believe. Package updates and module updates in the same commits.

Guess the best way might be reverting/deleting the module updates in a new commit, squash, and then make a new commit with module updates ya?

@Church-
Copy link
Author

Church- commented Aug 2, 2020

@lsix Already, redid the commits as per your suggestion. One for the package update.One for the module.

For the module there's a... fairly gnarly shellscript in the PreStart stage of the service.
It'll:

  • ensure there's a dir of /var/lib/jellyfin/database/db_version
  • if the version is 10.6.1 (commit where the breaking change occurs) just copy over the database into the correct database/db_version dir.
  • If it's not equal to that version (presumed greater since we didn't track it till this update)
    • Get all the db versions, and reverse sort them to get the latest version (Maybe use the version sort flag here?)
    • loop through and check if the version dir is actually a dir.
    • check if the version dir has contents
    • copies them to the new db_version dir if it does have contents.

Thoughts?

Copy link
Member

@lsix lsix left a comment

Choose a reason for hiding this comment

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

Few remarks.

As mentioned by @minijackson this approach is not completely usual in the nixos ecosystem. Having this behavior governed by an option (jellyfin.versioned_statedir or something else, I am terrible with finding good concise names) could be beneficial. In many systems, it would make sense to just use the service as it is currently, and rely on a generic backup system aside (I guess).

I do not really have a strong opinion on where this should go, so I’ll let @minijackson decide as module maintainer ^_^

Anyway @Church- thanks a lot for your contribution and work, sorry this takes so long.

cp -r /var/lib/${StateDirectory}/data /var/lib/${StateDirectory}/database/${db_version}/
exit 0
else
versions=$(find /var/lib/${StateDirectory}/database/ -maxdepth 1 -mindepth 1 | sort -r)
Copy link
Member

Choose a reason for hiding this comment

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

Sort might not work as expected here:

echo -e "10.8\n10.9\n10.10"|sort -r
10.9
10.8
10.10

do
if [ -d "$version" ]; then
if find "$version" -mindepth 1 -print -quit 2>/dev/null | grep -q .; then;
cp -r "$version" /var/lib/${StateDirectory}/database/${db_version}
Copy link
Member

Choose a reason for hiding this comment

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

If we have this sort of thing, I guess we might want a clean-up mechanism (or not, I really do not know). Maybe drop all but 2 most recent?

ExecPreStart = ''
#!/bin/bash
mkdir -p /var/lib/${StateDirectory}/database/${db_version}
if [ "${db_version}" = "10.6.1" ]; then
Copy link
Member

Choose a reason for hiding this comment

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

maybe

if [ -d "/var/lib/${StateDirectory}/data" ]

would be more direct and also more generic (not version specific).

#!/bin/bash
mkdir -p /var/lib/${StateDirectory}/database/${db_version}
if [ "${db_version}" = "10.6.1" ]; then
cp -r /var/lib/${StateDirectory}/data /var/lib/${StateDirectory}/database/${db_version}/
Copy link
Member

Choose a reason for hiding this comment

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

I have not checked, but what happens to everything that does not fall into data? (log and so on)

@minijackson
Copy link
Member

Ultimately, I think it should be up for the user / sysadmin to decide how and if they want to backup the jellyfin state directory. One solution that could be nice is to do it the PostgreSQL way, and use the system.stateVersion option to check if we want to upgrade to 10.6+, by adding the package option, and doing something like this:

{
  services.jellyfin.package = mkDefault (
    if versionAtLeast config.system.stateVersion "20.09" then pkgs.jellyfin
    else pkgs.jellyfin_10_5);
}

That would mean we would also have to add the jellyfin_10_5 pkg, and print a friendly warning to the user if the stateVersion is less than 20.09.

Sorry to ask you that again, but could you also update the version to the recently released 10.6.2?

@Church-
Copy link
Author

Church- commented Aug 3, 2020

Ultimately, I think it should be up for the user / sysadmin to decide how and if they want to backup the jellyfin state directory. One solution that could be nice is to do it the PostgreSQL way, and use the system.stateVersion option to check if we want to upgrade to 10.6+, by adding the package option, and doing something like this:

{
  services.jellyfin.package = mkDefault (
    if versionAtLeast config.system.stateVersion "20.09" then pkgs.jellyfin
    else pkgs.jellyfin_10_5);
}

That would mean we would also have to add the jellyfin_10_5 pkg, and print a friendly warning to the user if the stateVersion is less than 20.09.

Sorry to ask you that again, but could you also update the version to the recently released 10.6.2?

Given we want to waylay any possible db corruptions/rollback issues.

Maybe defaulting to pkgs.jellyfin10_5 and having to opt in to pkgs.jellyfin without the dep rectifying above.
Thoughts @minijackson? Otherwise I'm all for your approach.

@minijackson
Copy link
Member

minijackson commented Aug 3, 2020

Do you mean defaulting the package option to the old version, and letting the user override that?

I'm personally more fond of the "default to the old one only if stateVersion < 20.03" solution: it makes new installations much simpler/cleaner, and there is very little chance of someone wanting to rollback or having db corruption issues if the user didn't have a jellyfin service <= 10.5.x

But if you feel I'm missing something, feel free to tell!

@Church-
Copy link
Author

Church- commented Aug 3, 2020

Hmm, okay. No I think you do have the right of it ya.

I'll go with that implementation idea.

@DIzFer
Copy link
Contributor

DIzFer commented Aug 13, 2020

Upgrade-wise this WFM, no related issues in the last weeks, beyond upgrading to 10.6.2 because of a 404.

I also agree using stateVersion is the way to go.

@Church-
Copy link
Author

Church- commented Aug 15, 2020

@lsix Finally pushed those changes, if you're happy with them then I think we're good to merge down.

@minijackson
Copy link
Member

Thank you! Small nitpick: according to the CONTRIBUTING, I think your last commit should start with nixos/jellyfin:, otherwise, I'm good with the changes.

@minijackson
Copy link
Member

Just did a nix-review, and got an error:

hash mismatch in fixed-output derivation '/nix/store/arpdb9sxb95xl79bh9yljmmw3alaas0g-jellyfin_10.6.2.tar.gz':
  wanted: sha256:0dw9fvxwpbm4pn5m8lqvn7nzysn8ks9n92frs3pidifvxlnzawzz
  got:    sha256:16yib2k9adch784p6p0whgfb6lrjzwiigg1n14cp88dx64hyhxhb

Comment on lines 19 to 25
package = mkDefault (
if versionAtLeast config.system.stateVersion "20.09" then pkgs.jellyfin
else pkgs.jellyfin_10_5
);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
package = mkDefault (
if versionAtLeast config.system.stateVersion "20.09" then pkgs.jellyfin
else pkgs.jellyfin_10_5
);
package = mkOption {
type = types.package;
example = literalExample "pkgs.jellyfin";
description = ''
Jellyfin package to use.
'';
};

then you can add this to the configuration part:

    services.jellyfin.package =
      mkDefault (if versionAtLeast config.system.stateVersion "20.09" then pkgs.jellyfin
        else pkgs.jellyfin_10_5);

and finally, you can replace pkgs.jellyfin by cfg.package in the ExecStart line of the configuration part.

@Church-
Copy link
Author

Church- commented Aug 16, 2020

Ugh, dumb mistakes, I'll push those up in a few.

@Church-
Copy link
Author

Church- commented Aug 16, 2020

@minijackson And those are fixed. Dumb mistakes, thanks for catching them.

Copy link
Member

@minijackson minijackson left a comment

Choose a reason for hiding this comment

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

Pro-tip: you can do nix build -L -f ./nixos/tests/jellyfin.nix to execute the jellyfin unit-test yourself

Comment on lines 19 to 25
package = mkOption (
type = types.package;
example = literalExample "pkgs.jellyfin";
description = ''
Jellyfin package to use.
'';
);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
package = mkOption (
type = types.package;
example = literalExample "pkgs.jellyfin";
description = ''
Jellyfin package to use.
'';
);
package = mkOption {
type = types.package;
example = literalExample "pkgs.jellyfin";
description = ''
Jellyfin package to use.
'';
};

Restart = "on-failure";
};
};

package = mkDefault (
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
package = mkDefault (
services.jellyfin.package = mkDefault (

@Church-
Copy link
Author

Church- commented Aug 16, 2020

@minijackson And fixed yet again, you know with all the module writing I've done the past few weeks you'd think I wouldn't make such stupid mistakes. 😛

@minijackson
Copy link
Member

No worries ^^

Everything works now when system.stateVersion = "20.09"

We still have issues for when stateVersion is less than 20.09:

  • we need to add the jellyfin_10_5 package to all-packages.nix
  • the jellyfin_10_5 package needs to be version 10.5.x, currently it is 10.6.1 ^^

Also, could you put the jellyfin_10_5 package into pkgs/servers/jellyfin/10.5.x.nix instead of pkgs/servers/jellyfin_10_5/default.nix? I think this would be more in line with the rest of nixpkgs.

Sorry that the review is in such a back and forth manner...

@Church-
Copy link
Author

Church- commented Aug 16, 2020

@minijackson Nah that's perfectly fine, first time PR'ing to nix, so there are things to learn. 😄
Thanks for taking the time to teach me.

Changes incoming.

@Church-
Copy link
Author

Church- commented Aug 16, 2020

@minijackson For all-packages.nix would I invoke jellyfin_10_5 via: jellyfin = callPackage ../servers/jellyfin/10.5.x.nix { }; ?

@minijackson
Copy link
Member

Almost! If I'm not wrong, it would be jellyfin_10_5 = callPackage ../servers/jellyfin/10.5.x.nix { }

@Church-
Copy link
Author

Church- commented Aug 16, 2020

And pushed again!

Added jellyfin_10_5 package as well to be used for the module in nixos versions < 20.09
…ts to using the default jellyfin package if nixos version is 20.09 or greater, otherwise will default to using the new jellyfin_10_5 derivation for older systems.
@Church-
Copy link
Author

Church- commented Aug 16, 2020

And hopefully the last typo is fixed.

@minijackson
Copy link
Member

Perfect! Both packages build, and the test pass with either stateVersion = "20.09" or stateVersion = "20.03"!

Do you still want to be writing something for the 20.09 release notes?

If you do, I think you need to add to the file nixos/doc/manual/release-notes/rl-2009.xml. If you don't, no worries, I don't mind writing to it either ^^

@Church-
Copy link
Author

Church- commented Aug 16, 2020

Edit: Actually I'll let you do the Release Notes if you don't mind? :)
Would be a good chance to see what the structure of it should look like for future releases.

I'll add to the release notes! Change incoming.
I'll include release notes as a separate commit?

@minijackson
Copy link
Member

Actually I'll let you do the Release Notes if you don't mind? :)

No problem! I think we're good to merge, then.

@Church-
Copy link
Author

Church- commented Aug 16, 2020

So what's the merge process like? Get someone with write access to do it?

@minijackson
Copy link
Member

So what's the merge process like? Get someone with write access to do it?

Yes, it's usually as simple as waiting a few days, but if it takes too long, there's a thread on NixOS's discourse for already reviewed PR: https://discourse.nixos.org/t/prs-already-reviewed/2617

@Church-
Copy link
Author

Church- commented Aug 16, 2020

Got it, cool. :)

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-already-reviewed/2617/203

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

Successfully merging this pull request may close these issues.

None yet

8 participants