Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Is it possible to script Vanilla installation?

businessdadbusinessdad Stealth contributor MVP
edited June 2012 in Vanilla 2.0 - 2.8

I'm trying to find a way to automate the installation of Vanilla, but, so far, I haven't found an easy way to do it. I created a script that, given a Vanilla distribution file and some parameters, extracts the file, creates a Database, creates a User with appropriate permissions and fills the setup form via HTTP Requests.

At such point, the forum is installed in its basic form, but I also need to enable some plugins, and this is where I'm stuck. I figured out that, to enable a plugin, I would just have to open a specific URL, which contains a Transient Key. I could easily build the URL manually, but I wouldn't know the value of the Transient Key and, therefore, my calls would fail.

I was thinking of simulating User actions like I did for the installation, i.e. POSTing forms and saving returned pages, but parsing HTML is not really an option, as I don't have a DOM Parser available and I can't rely on Regular Expressions.

I was therefore wondering if there would be an easier way to "drive" Vanilla from a script, without having to jump through too many hoops.

Thanks in advance for all replies.

«1

Comments

  • well there are implementation like SimpleScript but like any of these case it relies on them being properly implemented, and being able to predict the particular setup.

    Have a look at the class.pluginmanager.php especially TestPlugin and EnablePlugin (which calls TestPlugin) methods. Essentially once everything check out it saves to config.

    The key thing is for Setup param to be true if you follow it through all the methods used, you will see that the Setup method of the plugin will get called. This ensures that all the setup operations are done.

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP

    @x00 Thanks, I was actually looking at class.pluginmanager.php. The issue is that I'd need to install Vanilla from an external script, such as Bash or Powershell, and I must be able to "stay outside" of Vanilla's code. For the same reason, I don't want to copy code and try to emulate its behaviour, as next version might be different and I would be back to square one.

    My objective is to install Vanilla the same way it's done now, just without a browser and a human who clicks on stuff. My scripts stays outside, tells Vanilla what to do and Vanilla does it.

  • Why not copy a custom plugin that implements IPlugin rather than extends Gnd_Pluign. Those don't need to be enabled, and you can make sure it has not setup requirements. Then you could run your install by point to an install method with curl, etc. You can make sure it only work with mange permission or 'disables' itself on install.

    That plugin could then use the plugin manger, and do a whole host of other things.

    grep is your friend.

  • x00x00 MVP
    edited June 2012

    other than that you need to parse web page (api doesn't jackopt TransientKey) you could use something like DOMDocument/preg/grep

    http://en.wikipedia.org/wiki/Web_scraping

    or if you want more of browser/client simulation

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP

    x00 said:
    Why not copy a custom plugin that implements IPlugin rather than extends Gnd_Pluign. Those don't need to be enabled, and you can make sure it has not setup requirements. Then you could run your install by point to an install method with curl, etc. You can make sure it only work with mange permission or 'disables' itself on install.

    That plugin could then use the plugin manger, and do a whole host of other things.

    I'm not sure I understand how this plugin would work. Even without the need of being enabled, I would have it sitting in a directory, while Vanilla still expects to be set up for first use. Instead of having to simulate POST actions via CURL, I'd have to do it through the plugin. That would only move the problem to another environment, rather than solve it.

    The only way such a plugin would add something, from what I understand, would be by implementing some sort of interface/API which can take calls and perform the tasks that are normally done via a web pages by loading the various classes and calling their methods "just as the normal installation procedure does".

    However, I'm not going to implement such a plugin, as I don't have time or resources to do it. Even worse, the whole thing would be based on tons of guesswork, as my knowledge of the internal mechanisms of Vanilla are insufficient and I'd have to "figure out" (very bad approach) what to do.

    I was looking for something I could use by staying completely outside of Vanilla, but I understand there isn't anything of sort available, yet.

    It seems that the only way may be parsing the HTML, after all. That would not be too bad if I could parse the DOM, but that won't be possible, either (installation script is written with ANT). I'll have to use Regular Expressions, hoping that nobody will change the structure of the URLs or the Dashboard.

  • I don't really understand the issue. There is dozens of ways you could do this.

    They are not going to spend a huge a mount of time on installation script, becuase they don't get used very often.

    Also anything could change, be it, the plugins page, and api, the core. That is the nature of development, thing change, maintenance is needed.

    I was simply suggesting that you script copies the plug-in over one the vanilla folder is copied/downloaded. Then you could use that to control these processes. That is your api. It is not really complicated, it would simply use the plugin manager. If your script need to download the plugn so be it.

    If you like you could start of a with a predetermined version of Garden>vanilla they you will know what it has or doesn't have.

    Most installations script work of set versions anyway.

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP

    @x00 In my case, the installation script would be used several times a day, as it will be fired automatically to update a testing environment when new features are implemented for a client. It's part of a Continuous Integration process. This can't possibly be done manually.

    I understand what you mean with your suggestion of an "API plugin", and I agree that it can be done. My point is simply that it's not what I was looking for, as I lack both the time and the knowledge needed to implement it (e.g. I have no idea how I could instantiate or use the Plugin Manager).

    Regarding the various versions, of course things will change, and the installation script will follow. Right now it can download, install and set up Vanilla 2.0.8.14, the plugin enable/disable is the only thing that's missing.

  • businessdadbusinessdad Stealth contributor MVP

    By the way, I will still keep your idea handy, I'll probably propose it later on. It would save us a lot of headaches, if we'll manage to implement it correctly.

    If I may, I have some questions about the IPlugin you mentioned:
    - You said that a plugin implementing IPlugin doesn't need to be enabled. I guess you refer to Gdn_IPlugin, is it correct?
    - If such a plugin is "installed" (i.e. simply copied into Vanilla's plugin subdirectory), will it need the setup to be completed for the plugin to be usable, or would it be possible to reach its methods straight away? Obviously, supposing they don't need to use the database.

  • x00x00 MVP
    edited June 2012

    You could put something like this in conf/bootstrap.after.php file. It will be applied on first run

    <?php if (!defined('APPLICATION')) exit();
    $PluginManager = Gdn::PluginManager();
    if(!$PluginManager->CheckPlugin('MyPlugin')){
        $Validation = new Gdn_Validation();
        if(Gdn::PluginManager()->EnablePlugin('MyPlugin', $Validation)){
            //Success!
        }else{
            //var_dump($Validation->Results());
        }
    }
    

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP

    x00 said:
    You could put something like this in conf/bootstrap.after.php file. It will be applied on first run

    I wasn't aware of the existence of bootstrap.after.php, that would come handy more than once! :O
    Could you please tell me if there's any documentation about it? Or can I simply create the file and write anything "Vanilla compatible" into it?

  • x00x00 MVP
    edited June 2012

    yes.

    bootstap before.php is before the framwork is loaded, bootstap after.php is after the framework is loaded. That simple.

    they are deliberately kept out of the core so they don't get overwritten.

    grep is your friend.

  • x00x00 MVP
    edited June 2012

    Not they are base level includes, they are not contained like plugin hooks. So avoid collisions through good practice.

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP
    edited June 2012

    x00 said:
    Not they are base level includes, they are not contained like plugin hooks. So avoid collisions through good practice.

    Sorry for the possibly stupid question, did you mean "note that they are base level includes"? Were you referring to bootstrap.before/after.php?

  • what I'm say is both of these are included in the boostrap.php file, which loads the framework that is all.

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP

    @x00 Thanks, I was guessing so. It's just that you wrote "not they are", which made little sense to me, but, since I'm not a native English speaker, I preferred to be 200% sure I got it right. :)

  • businessdadbusinessdad Stealth contributor MVP

    x00 said:
    You could put something like this in conf/bootstrap.after.php file. It will be applied on first run

    Your suggestion worked almost perfectly. It tries to enable the plugin, but it fails with the error "missing the following requirement(s): Vanilla 2.0.10". I'm a bit puzzled, because the plugin is running inside Vanilla 2.0.18 and it can be enabled correctly "by hand".

  • do you have

    'RequiredApplications' => array('Vanilla' => '>=2.0.10'),

    in you pluigin info?

    What do you have for

    APPLICATION_VERSION

    at the top of /index.php ?

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP
    edited June 2012

    x00 said:
    What do you have for

    APPLICATION_VERSION

    at the top of /index.php ?

    Found the reason: APPLICATION_VERSION was undefined in my script. I must have deleted its definition by mistake, while I was making my hundreds of experiments. I should stop working until 4 AM... Sorry about that.

  • yes definitely, not a good idea from personal experience, your performance will be affected in the days after.

    I also make that mistake, but I'm trying hard to make sure I get enough sleep. The less sleep you get the less productive you will be, and the more stressed.

    In university I didn't sleep for 48 hours, and was experiencing extreme paranoia after.

    grep is your friend.

  • businessdadbusinessdad Stealth contributor MVP

    @x00 Thanks for your help, now the CI Server is a bit happier. Funnily enough, I made an experiment and wrote down some automated tests for a plugin. They seemed to work and pass correctly, but they did it only on the development machine.

    That's because the tests call the Plugin's method directly, which means the whole dispatching mechanism of Vanilla is bypassed. Next challenge will be attempting to invoke Plugin's method the same way vanilla does. I tried to create a Request object and use the dispatcher, but it didn't work. I inspected a "normal" browser Request, and I found out it contains a billion more things. I'm afraid things are much more complicated than I thought. :O

Sign In or Register to comment.