{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Guide to Custom Pkgacct Components","description":"With its world-class support and rich feature set, cPanel &amp; WHM has been the industry-leading web hosting platform for over 20 years. Trusted worldwide by our technology partners WordPress, CloudLinux, LiteSpeed, and more.","siteUrl":"https://api.docs.cpanel.net/","image":"/assets/cpanel-whm.ccd85fdccb18de0645f8a6ebf38e36a0489b92fc9d4ca92776f06aa5a160b167.db81178d.svg","keywords":"documentation, api, portal, cpanel","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides"},"children":["Development Guides Home"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"guide-to-custom-pkgacct-components","__idx":0},"children":["Guide to Custom Pkgacct Components"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"introduction","__idx":1},"children":["Introduction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can extend the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://docs.cpanel.net/whm/scripts/the-pkgacct-script/"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/usr/local/cpanel/scripts/pkgacct"]}]}," script with custom components. A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," component is a Perl module. It runs when the system packages an account. Components let you add more data to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cpmove"]}," archive that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," creates. For example, you can include a config file that lives outside the cPanel account user's home directory."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Components only cover the packaging side of an integration. To put your data back during a restore, use the matching ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/guide-to-standardized-hooks/guide-to-standardized-hooks-hookable-events/guide-to-standardized-hooks-pkgacct-functions#restore"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PkgAcct::Restore"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["post"]}," hook"]}," from the Standardized Hooks System. The ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#restore-the-data"},"children":["Restore the data"]}," section shows how the two pieces work together."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Important:"},"children":[{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The system loads components from disk on every ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," run. It has no way to disable an installed component. To turn one off for a single run, move the module file out of the components directory."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The calling code ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must"]}," work with Perl 5.36. For more information, read our ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/guide-to-perl/guide-to-perl-in-cpanel-custom-modules"},"children":["Custom Modules"]}," documentation."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"component-location","__idx":2},"children":["Component location"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Place your component module in the following directory:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"/var/cpanel/perl/Cpanel/Pkgacct/Components/\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each module's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["package"]}," name ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must"]}," match its filename. It ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["must"]}," also use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Cpanel::Pkgacct::Components::"]}," namespace. For example, the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Cpanel::Pkgacct::Components::MyAppPkgacct"]}," package belongs in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/var/cpanel/perl/Cpanel/Pkgacct/Components/MyAppPkgacct.pm"]}," file."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"component-structure","__idx":3},"children":["Component structure"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A component must use the following criteria:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Inherit from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Cpanel::Pkgacct::Component"]}," parent class."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Define a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["perform()"]}," method. The system calls this method when it packages an account."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["perform()"]}," method takes the component instance (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$self"]},") as its only argument. Each component holds a reference to the parent ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," object as the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct_obj"]}," attribute. Call methods on that object to get information about the current run."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Access the object with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$self->get_attr('pkgacct_obj')"]},". For example, the call below returns the temporary working directory:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"perl","header":{"controls":{"copy":{}}},"source":"my $work_dir = $self->get_attr('pkgacct_obj')->get_work_dir();\n","lang":"perl"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"job-context-methods","__idx":4},"children":["Job context methods"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use these methods on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct_obj"]}," to read details about the account that the system packages."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Method"},"children":["Method"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_work_dir()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the temporary directory where the system builds the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cpmove"]}," archive. Write any files that you want in the backup to this directory."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_user()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the cPanel account username that the system packages."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_uid()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the cPanel account user's UID."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_domains()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the cPanel account user's domains."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_dns_list()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the cPanel account user's DNS zone list."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_suspended()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]}," if the cPanel account is suspended. Otherwise returns a false value."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_is_backup()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]}," when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," runs as part of a backup. Otherwise returns a false value."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_is_userbackup()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]}," when the cPanel account user started the backup. Otherwise returns a false value."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_is_incremental()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]}," when the archive is incremental. Otherwise returns a false value."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_new_mysql_version()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the target MySQL version for the archive."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_now()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the timestamp the system captured at the start of the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," run. Use this value so all components share the same notion of the current time."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_cpconf()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the parsed ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/var/cpanel/cpanel.config"]}," hashref."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_OPTS()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the raw options hashref that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," ran with."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["get_output_obj()"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Returns the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Cpanel::Output"]}," logger. Call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["out()"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn()"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error()"]}," on this object to send messages through the normal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," log stream."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"backup-helpers","__idx":5},"children":["Backup helpers"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct_obj"]}," also offers helper methods for common backup tasks."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Method"},"children":["Method"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ensure_dir_at_target($reldir, $perms)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Creates a directory inside ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["work_dir"]}," at the given relative path with the given permissions."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["syncfile_or_warn($source, $dest, $no_sym, $no_chown, $resume)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Copies a single file. Sends a warning through the output object if the copy fails."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["backup_dir_if_target_is_older_than_source($source_dir, $rel_target_dir)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Syncs an entire directory tree into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["work_dir/$rel_target_dir"]},". Uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rsync"]}," semantics and honors the incremental backup flag."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"methods-on-the-component-itself","__idx":6},"children":["Methods on the component itself"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can also call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["$self->get_cpuser_data()"]}," to load the cPanel account user's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cpuser"]}," file. This method is defined on the component class. It delegates to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct_obj"]}," for you."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example-component","__idx":7},"children":["Example component"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following example component copies a config file into the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cpmove"]}," archive. The file lives outside the cPanel account user's home directory. The fictional ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["myapp"]}," integration stores its data for each cPanel account user in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/var/myapp/users/"]}," directory."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the module in the following location: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/var/cpanel/perl/Cpanel/Pkgacct/Components/MyAppPkgacct.pm"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"perl","header":{"controls":{"copy":{}}},"source":"package Cpanel::Pkgacct::Components::MyAppPkgacct;\n\nuse strict;\nuse warnings;\n\nuse parent 'Cpanel::Pkgacct::Component';\n\nsub perform {\n    my ($self) = @_;\n\n    my $pkgacct = $self->get_attr('pkgacct_obj');\n\n    # The temporary directory where the system builds the cpmove archive.\n    my $work_dir = $pkgacct->get_work_dir();\n\n    # The cPanel account user whose account the system packages.\n    my $user = $pkgacct->get_user();\n\n    # Skip this component if the cPanel account user has no myapp configuration file.\n    my $source = \"/var/myapp/users/$user.conf\";\n    return if !-s $source;\n\n    # Stage the file inside the cpmove archive.\n    require File::Copy;\n    require File::Path;\n    File::Path::make_path(\"$work_dir/myapp\");\n    File::Copy::cp( $source, \"$work_dir/myapp/$user.conf\" )\n      or warn \"Failed to copy '$source' to '$work_dir/myapp/$user.conf': $!\";\n\n    return;\n}\n\n1;\n","lang":"perl"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," runs, the system loads the component and calls ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["perform()"]},". The component writes the myapp config file into the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["myapp/"]}," subdirectory of the working directory. The system then adds that directory to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cpmove"]}," archive."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"restore-the-data","__idx":8},"children":["Restore the data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pkgacct"]}," components only handle the packaging side. To restore the data that your component packaged, register a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/guide-to-standardized-hooks/guide-to-standardized-hooks-hookable-events/guide-to-standardized-hooks-pkgacct-functions#restore"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PkgAcct::Restore"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["post"]}," Standardized Hook"]},". The hook runs after the system extracts the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cpmove"]}," archive. It gives you access to the extracted contents through the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["extract_dir"]}," parameter."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Place your hook module in the following location:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"/var/cpanel/perl5/lib/\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following example hook restores the file that the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#example-component"},"children":["example component"]}," packaged."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the module in the following location: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/var/cpanel/perl5/lib/MyAppRestorepkg.pm"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"perl","header":{"controls":{"copy":{}}},"source":"package MyAppRestorepkg;\n\nuse strict;\nuse warnings;\n\nsub describe {\n    return [\n        {\n            'category' => 'PkgAcct',\n            'event'    => 'Restore',\n            'stage'    => 'post',\n            'hook'     => 'MyAppRestorepkg::do_it',\n            'exectype' => 'module',\n        },\n    ];\n}\n\nsub do_it {\n    my ( $context, $data ) = @_;\n\n    my $user      = $data->{'user'};\n    my $conf_file = $data->{'extract_dir'} . \"/myapp/$user.conf\";\n\n    return if !-s $conf_file;\n\n    require File::Copy;\n    File::Copy::cp( $conf_file, \"/var/myapp/users/$user.conf\" )\n      or warn \"Failed to copy '$conf_file' to '/var/myapp/users/$user.conf': $!\";\n\n    return;\n}\n\n1;\n","lang":"perl"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Register the hook with the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/guide-to-standardized-hooks/guide-to-standardized-hooks-the-manage-hooks-utility"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/usr/local/cpanel/bin/manage_hooks"]}]}," utility:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"/usr/local/cpanel/bin/manage_hooks add module MyAppRestorepkg\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For more about the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PkgAcct::Restore"]}," event and its data, read our ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/guide-to-standardized-hooks/guide-to-standardized-hooks-hookable-events/guide-to-standardized-hooks-pkgacct-functions#restore"},"children":["PkgAcct Functions"]}," documentation."]}]},"headings":[{"value":"Guide to Custom Pkgacct Components","id":"guide-to-custom-pkgacct-components","depth":1},{"value":"Introduction","id":"introduction","depth":2},{"value":"Component location","id":"component-location","depth":2},{"value":"Component structure","id":"component-structure","depth":2},{"value":"Job context methods","id":"job-context-methods","depth":3},{"value":"Backup helpers","id":"backup-helpers","depth":3},{"value":"Methods on the component itself","id":"methods-on-the-component-itself","depth":3},{"value":"Example component","id":"example-component","depth":2},{"value":"Restore the data","id":"restore-the-data","depth":2}],"frontmatter":{"seo":{"title":"Guide to Custom Pkgacct Components"}},"lastModified":"2026-05-14T18:23:33.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/guide-to-custom-pkgacct-components","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}