Vague title, sorry. Issue is, I would like to copy a whole brush of directories and files over to every new webroot I create with ISPC. Not only the one page. I already created it in conf-custom/index/ but how to get ISPC to use it?
This can't be achieved like that. You'll have to write an ISPConfig server-side plugin instead which binds itself to the 'web_domain_insert' event.
in addition to #2 the plugin must be run after most the of the other plugins bound to web_domain_insert. IIRC, they will be executed in alpabetical order. Have a look at the apache or nginx-plugin for the code "//* Copy the web skeleton files only when there is no index.php, standard_index.html or index.html file yet"
If you really are going to modify ISPConfig code to add the functionality you need, surely you know to do Code: grep -r "Copy the web skeleton files only" /usr/local/ispconfig/ to find the ISPConfig source files @florian030 writes about in #4. Don't ask me what modification to make, I do not know that. Plus I do not like coding in PHP.
Thank you, I found it. I can do a bit of PHP. We will see if my knowledge will suffice. :3 Do I understand it correctly, that the whole block is commented out to be disabled because at the moment it is "hard coded"? The default function will be replaced by this if I uncomment? Sorry, I need to ask stupid noobish questions. Ubuntu/Linux isn't my natural habitat and somehow I need to learn.
This is the plugin code I use for a custom skeleton. PHP: <?php// Created: 2021/04/12 17:41:23// Last modified: 2021/04/14 09:05:57/** * Skapa custom skeleton för nya websites. * * Kopiera denna fil till /usr/local/ispconfig/server/plugins-available * och länka den sedan till plugins-enabled * */class z_apache2_customskel { /** * @var string */ public $plugin_name = 'z_apache2_customskel'; /** * @var string */ public $class_name = 'z_apache2_customskel'; // This function is called during ispconfig installation to determine // if a symlink shall be created for this plugin. public function onInstall() { global $conf; if ($conf['services']['web'] == true) { return true; } else { return false; } } /* This function is called when the plugin is loaded */ public function onLoad() { global $app; /* Register for the events */ $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); } /** * @param $event_name * @param $data */ public function insert($event_name, $data) { global $app, $conf; $this->action = 'insert'; // just run the update function $this->update($event_name, $data); } /** * @param $event_name * @param $data */ public function update($event_name, $data) { global $app, $conf; if ($this->action != 'insert') { $this->action = 'update'; } // file_put_contents("./QazQaz.log", var_export($data, true), FILE_APPEND); // load the server configuration options $app->uses('getconf'); $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); if ($data['new']['document_root'] == '') { return 0; } if ($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { return 0; } if (trim($data['new']['domain']) == '') { return 0; } $web_folder = 'web'; $old_web_folder = 'web'; if ($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { // new one $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); if ($subdomain_host == '') { $subdomain_host = 'web' . $data['new']['domain_id']; } $web_folder = $data['new']['web_folder']; unset($tmp); if ($app->system->is_blacklisted_web_path($web_folder)) { return 0; } } // // Och nu kommer koden vi är ute efter // $owner = $data['new']['system_user']; $group = $data['new']['system_group']; // TB Autoconfig if (is_dir($conf['rootpath'] . '/conf-custom/index/.well-known')) { $app->system->exec_safe('cp -a ? ?', $conf['rootpath'] . '/conf-custom/index/.well-known', $data['new']['document_root'] . '/' . $web_folder . '/' ); $app->system->exec_safe('chown -R ? ?', $owner, $data['new']['document_root'] . '/' . $web_folder . '/.well-known', ); $app->system->exec_safe('chgrp -R ? ?', $group, $data['new']['document_root'] . '/' . $web_folder . '/.well-known', ); } // Autodiscover in Outlook 2010 if (is_dir($conf['rootpath'] . '/conf-custom/index/autodiscover')) { $app->system->exec_safe('cp -a ? ?', $conf['rootpath'] . '/conf-custom/index/autodiscover', $data['new']['document_root'] . '/' . $web_folder . '/' ); $app->system->exec_safe('chown -R ? ?', $owner, $data['new']['document_root'] . '/' . $web_folder . '/autodiscover', ); $app->system->exec_safe('chgrp -R ? ?', $group, $data['new']['document_root'] . '/' . $web_folder . '/autodiscover', ); } } /** * @param $event_name * @param $data */ public function delete($event_name, $data) { global $app, $conf; // load the server configuration options // $app->uses('getconf'); // $app->uses('system'); // $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); // $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); }} The skeleton it copies resides in "/usr/local/ispconfig/server/conf-custom/index/". You can use this code as a start.
Thank you @atle this helped me loads. Just two things: For my solution, I needed to get rid of the ".well-known" in lines 121 to 137 and replace it with a "*" to copy everything inside the custom-conf/index/ directory. Second thing: I think we can get rid of the "Autodiscover in Outlook" part below if we're not using Outlook for whatever that is good for? What I did in steps (Ubuntu 20.04): ATTENTION! THIS DOES NOT WORK!!!! SEE NEXT POST! 1. Copy atles code (post above) into a new file named "z_apache2_customskel.inc.php" in Code: /usr/local/ispconfig/server/plugins-available and replace the Code: .well-known in lines 121 to 137 with a Code: * . 2. Create your files/structure in Code: /conf-custom/index/ 3. add a symlink to plugins-enabled. Code: ln -s /usr/local/ispconfig/server/plugins-available/z_apache2_customskel.inc.php /usr/local/ispconfig/server/plugins-enabled/ 4. just reboot the whole system to make sure. Code: sudo reboot 5. Try it. If nothing happens or ISPC will get stuck on the tasks, go to ISPCONFIG panel > Monitor (top navigation) > ISPC Cron-Log (left navigation, quite low). There might be a few errors in there. Mine was: Code: Sa 26. Mär 15:17:01 CET 2022 26.03.2022-15:17 - WARNING - There is already a lockfile set, but no process running with this pid (653898). Continuing. Sa 26. Mär 15:17:01 CET 2022 PHP Fatal error: Uncaught Error: Class 'zz_custom_defaultpage' not found in /usr/local/ispconfig/server/lib/classes/plugins.inc.php:67 Sa 26. Mär 15:17:01 CET 2022 Stack trace: Sa 26. Mär 15:17:01 CET 2022 #0 /usr/local/ispconfig/server/server.php(172): plugins->loadPlugins() Sa 26. Mär 15:17:01 CET 2022 #1 {main} Sa 26. Mär 15:17:01 CET 2022 thrown in /usr/local/ispconfig/server/lib/classes/plugins.inc.php on line 67 And it happened because I named the file wrong ("zz_custom_defaultpage.inc.php"). Use the first class name from the file as file name! In this case, it is "z_apache2_customskel", so use that and add a ".inc.php". Then another error was triggered, because I had no ".well-known" file in the conf-custom/index directory. See step 1. So thank you everyone for helping out with this - and I hope this thread is a help for others in the future. PS: Is there a way to use `inline code`? Oo
Okay, I was wrong, it did not work. Here's my working solution: I copied a bit of the code of artle into roughly line 924 the apache2_plugin.inc.php and replaced the "old" function which iffed a lot and copied over single hardcoded files. See the comments at the beginning and the end of the following snippet. You will also need to format it, as this editor doesn't like indentations. Sorry. I know this might not be advised, as it is not a custom plugin and I got rid of the if requests around it. Sadly, I don't know yet(!) how to add my own plugin. But I was looking for a working solution, so sorry. I would love some education. Code: // Copy the web skeleton files only when there is no index.php, standard_index.html or index.html file yet if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/standard_index.html')) { // // NEW FUNCTION copied from atles post in the ISPC forums and moronically edited by NMND: // // // Och nu kommer koden vi är ute efter // $owner = $data['new']['system_user']; $group = $data['new']['system_group']; // TB Autoconfig // if (is_dir($conf['rootpath'] . '/conf-custom/index/')) { $subdir = "/conf-custom/index/"; $app->system->exec_safe('cp -a ?* ?', $conf['rootpath'] . $subdir , $data['new']['document_root'] . '/' . $web_folder . '/' ); $app->system->exec_safe('chown -R ?* ?', $owner, $data['new']['document_root'] . '/' . $web_folder, ); $app->system->exec_safe('chgrp -R ?* ?', $group, $data['new']['document_root'] . '/' . $web_folder, ); // } } $app->system->exec_safe('chmod -R a+r ?', $data['new']['document_root'].'/' . $web_folder . '/'); //** Copy the error documents on [...] My suggestion for a more dynamic way would be to glob through "conf-custom/index/" and foreach cp over every file found. Maybe add an array for blacklisting files like "empty.dir". I would like to try that, I'd just like a bit of input why there's confusing amounts of if()s around the copy cmds? What should I check for?