Skip to content

Commit

Permalink
Add farm management support (#88)
Browse files Browse the repository at this point in the history
* Add propagating verbose to external subcommands(#61)

* Add propagating verbose to external subcommands(#61)

* Add propagating verbose to external subcommands(#61)

* enhanced create and add for wiki farm

* added add and remove wiki in the Canasta container feature

* updated farmsettings.go

* cleaned the code

* structure 0.1

* structure 0.2

* midterm version

* Add documentation

* Add documentation

* test version

* Update with HTTPS

* Canasta-CLI 2.0 adding wiki farm support
  • Loading branch information
chl178 authored Nov 3, 2023
1 parent 51e08b5 commit 81d2a71
Show file tree
Hide file tree
Showing 30 changed files with 1,411 additions and 106 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
*.yaml

# Test binary, built with `go test -c`
*.test
Expand Down
8 changes: 8 additions & 0 deletions LocalSettingsTemplate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
// If not running MediaWiki, exit
if ( !defined( 'MEDIAWIKI' ) ) {
exit;
}
#$wgServer = "http://localhost";
#$wgSitename = ;
#$wgMetaNamespace = ;
85 changes: 82 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,83 @@
# Canasta: Command Line Interface Tool for Canasta
This is the official Command Line Interface tool for the Canasta.
# Canasta CLI - Recent Enhancements & New Commands for wiki farm support

We're excited to introduce a series of enhancements and new commands to the Canasta CLI. These changes aim to provide users with more flexibility and power in managing their MediaWiki instances and wiki farms.

## Table of Contents
- [Installation](#installation)
- [Enhancements](#enhancements)
- [create](#create)
- [extension](#extension)
- [skin](#skin)
- [New Commands](#new-commands)
- [add](#add)
- [remove](#remove)


## Enhancements

### create
**Description:** Creates a Canasta installation. Enhanced to support wiki farm setup with the `-f` flag.

**Usage:**
sudo go run canasta.go create [flags]
- `-p, --path`: Canasta directory.
- `-o, --orchestrator`: Orchestrator to use for installation (default: "docker-compose").
- `-i, --id`: Canasta instance ID.
- `-w, --wiki`: Name of the wiki.
- `-n, --domain-name`: Domain name (default: "localhost").
- `-a, --WikiSysop`: Initial wiki admin username.
- `-s, --password`: Initial wiki admin password.
- `-f, --yamlfile`: Initial wiki yaml file for wiki farm setup.
- `-k, --keep-config`: Keep the config files on installation failure.

**YAML Format for Wiki Farm:**
To create a wiki farm, you need to provide a YAML file with the following format:
```yaml
wikis:
- id: [WIKI_ID] # Example: "mywiki1"
url: [WIKI_URL] # Example: "mywiki1.example.com"
```
sudo go run canasta.go create -f [yamlfile] # Example: "wikis.yaml
### extension
**Description:** Manage Canasta extensions. Enhanced to target a specific wiki within the farm using the `-w` flag.

**Subcommands:**
- `list`: Lists all the installed Canasta extensions.
- `enable`: Enables specified extensions.
- `disable`: Disables specified extensions.

**Usage:**
sudo go run canasta.go extension [subcommand] [flags]
**Flags:**
- `-i, --id`: Specifies the Canasta instance ID.
- `-p, --path`: Specifies the Canasta installation directory.
- `-w, --wiki`: Specifies the ID of a specific wiki within the Canasta farm.
- `-v, --verbose`: Enables verbose output.

## New Commands

### add
**Description:** Adds a new wiki to a Canasta instance.

**Usage:**
sudo go run canasta.go add [flags]
**Flags:**
- `-w, --wiki`: ID of the new wiki.
- `-u, --url`: URL of the new wiki.
- `-s, --site-name`: Name of the new wiki site.
- `-p, --path`: Path to the new wiki.
- `-i, --id`: Canasta instance ID.
- `-o, --orchestrator`: Orchestrator to use for installation (default: "docker-compose").
- `-d, --database`: Path to the existing database dump.

### remove
**Description:** Removes a wiki from a Canasta instance.

**Usage:**
sudo go run canasta.go remove [flags]
**Flags:**
- `-w, --wiki`: ID of the wiki to be removed.
- `-p, --path`: Path to the wiki.
- `-i, --id`: Canasta instance ID.

Download and install the latest package to start using the CLI. For more information on using the CLI, please see the [documentation](https://canasta.wiki/cli).
136 changes: 136 additions & 0 deletions cmd/add/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package add

import (
"fmt"
"log"
"os"

"github.com/spf13/cobra"

"github.com/CanastaWiki/Canasta-CLI-Go/cmd/restart"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/canasta"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/config"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/farmsettings"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/mediawiki"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/orchestrators"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/prompt"
)

func NewCmdCreate() *cobra.Command {
var instance config.Installation
var wikiName string
var domainName string
var wikiPath string
var siteName string
var databasePath string
var url string
var admin string

addCmd := &cobra.Command{
Use: "add",
Short: "Add a new wiki to a Canasta instance",
RunE: func(cmd *cobra.Command, args []string) error {
var err error
wikiName, domainName, wikiPath, instance.Id, siteName, admin, err = prompt.PromptWiki(wikiName, url, instance.Id, siteName, admin)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Adding wiki '%s' to Canasta instance '%s'...\n", wikiName, instance.Id)
err = AddWiki(wikiName, domainName, wikiPath, siteName, databasePath, admin, instance)
if err != nil {
log.Fatal(err)
}
fmt.Println("Done.")
return nil
},
}

pwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}

addCmd.Flags().StringVarP(&wikiName, "wiki", "w", "", "ID of the new wiki")
addCmd.Flags().StringVarP(&url, "url", "u", "", "URL of the new wiki")
addCmd.Flags().StringVarP(&siteName, "site-name", "s", "", "Name of the new wiki site")
addCmd.Flags().StringVarP(&instance.Path, "path", "p", pwd, "Path to the new wiki")
addCmd.Flags().StringVarP(&instance.Id, "id", "i", "", "Canasta instance ID")
addCmd.Flags().StringVarP(&instance.Orchestrator, "orchestrator", "o", "docker-compose", "Orchestrator to use for installation")
addCmd.Flags().StringVarP(&databasePath, "database", "d", "", "Path to the existing database dump")
addCmd.Flags().StringVarP(&admin, "admin", "a", "", "Admin name of the new wiki")
return addCmd
}

// addWiki accepts the Canasta instance ID, the name, domain and path of the new wiki, and the initial admin info, then creates a new wiki in the instance.
func AddWiki(name, domain, wikipath, siteName, databasePath, admin string, instance config.Installation) error {
var err error

//Checking Installation existence
instance, err = canasta.CheckCanastaId(instance)
if err != nil {
return err
}

//Migrate to the new version Canasta
err = canasta.MigrateToNewVersion(instance.Path)
if err != nil {
return err
}

//Checking Running status
err = orchestrators.CheckRunningStatus(instance.Path, instance.Id, instance.Orchestrator)
if err != nil {
return err
}

//Checking Wiki existence
exists, pathComboExists, err := farmsettings.CheckWiki(instance.Path, name, domain, wikipath)
if err != nil {
return err
}
if exists {
return fmt.Errorf("A wiki with the name '%s' exists", name)
}
if pathComboExists {
return fmt.Errorf("A wiki with the same installation path '%s' in the Canasta '%s' exists", name+": "+domain+"/"+wikipath, instance.Id)
}

//Add the wiki in farmsettings
err = farmsettings.AddWiki(name, instance.Path, domain, wikipath, siteName)
if err != nil {
return err
}

// Import the database if databasePath is specified
if databasePath != "" {
err = orchestrators.ImportDatabase(name, databasePath, instance)
if err != nil {
return err
}
}

//Copy the Localsettings
err = canasta.CopySetting(instance.Path, name)
if err != nil {
return err
}

//Rewrite the Caddyfile
err = canasta.RewriteCaddy(instance.Path)
if err != nil {
return err
}

err = mediawiki.InstallOne(instance.Path, name, domain, wikipath, admin,instance.Orchestrator)
if err != nil {
return err
}
err = restart.Restart(instance)
if err != nil {
return err
}

fmt.Println("Successfully Added the Wiki '" + name + "in Canasta instance '" + instance.Id + "'...")

return nil
}
32 changes: 25 additions & 7 deletions cmd/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@ import (

"github.com/CanastaWiki/Canasta-CLI-Go/internal/canasta"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/config"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/farmsettings"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/mediawiki"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/orchestrators"
"github.com/CanastaWiki/Canasta-CLI-Go/internal/prompt"
)

func NewCmdCreate() *cobra.Command {
var (
path string
orchestrator string
pwd string
name string
domain string
yamlPath string
err error
keepConfig bool
canastaInfo canasta.CanastaVariables
Expand All @@ -29,11 +34,11 @@ func NewCmdCreate() *cobra.Command {
Short: "Create a Canasta installation",
Long: "Creates a Canasta installation using an orchestrator of your choice.",
RunE: func(cmd *cobra.Command, args []string) error {
if canastaInfo, err = mediawiki.PromptUser(canastaInfo); err != nil {
if name, canastaInfo, err = prompt.PromptUser(name, yamlPath, canastaInfo); err != nil {
log.Fatal(err)
}
fmt.Println("Creating Canasta installation '" + canastaInfo.Id + "'...")
if err = createCanasta(canastaInfo, pwd, path, orchestrator, override); err != nil {
if err = createCanasta(canastaInfo, pwd, path, name, domain, yamlPath, orchestrator, override); err != nil {
fmt.Print(err.Error(), "\n")
if keepConfig {
log.Fatal(fmt.Errorf("Keeping all the containers and config files\nExiting"))
Expand All @@ -59,24 +64,37 @@ func NewCmdCreate() *cobra.Command {
createCmd.Flags().StringVarP(&path, "path", "p", pwd, "Canasta directory")
createCmd.Flags().StringVarP(&orchestrator, "orchestrator", "o", "docker-compose", "Orchestrator to use for installation")
createCmd.Flags().StringVarP(&canastaInfo.Id, "id", "i", "", "Canasta instance ID")
createCmd.Flags().StringVarP(&canastaInfo.WikiName, "wiki", "w", "", "Name of wiki")
createCmd.Flags().StringVarP(&canastaInfo.DomainName, "domain-name", "n", "localhost", "Domain name")
createCmd.Flags().StringVarP(&name, "wiki", "w", "", "Name of wiki")
createCmd.Flags().StringVarP(&domain, "domain-name", "n", "localhost", "Domain name")
createCmd.Flags().StringVarP(&canastaInfo.AdminName, "WikiSysop", "a", "", "Initial wiki admin username")
createCmd.Flags().StringVarP(&canastaInfo.AdminPassword, "password", "s", "", "Initial wiki admin password")
createCmd.Flags().StringVarP(&yamlPath, "yamlfile", "f", "", "Initial wiki yaml file")
createCmd.Flags().BoolVarP(&keepConfig, "keep-config", "k", false, "Keep the config files on installation failure")
createCmd.Flags().StringVarP(&override, "override", "r", "", "Name of a file to copy to docker-compose.override.yml")
return createCmd
}

// importCanasta accepts all the keyword arguments and create a installation of the latest Canasta.
func createCanasta(canastaInfo canasta.CanastaVariables, pwd, path, orchestrator, override string) error {
func createCanasta(canastaInfo canasta.CanastaVariables, pwd, path, name, domain, yamlPath, orchestrator, override string) error {
if _, err := config.GetDetails(canastaInfo.Id); err == nil {
log.Fatal(fmt.Errorf("Canasta installation with the ID already exist!"))
}
if err := farmsettings.CreateYaml(name, domain, &yamlPath); err != nil {
return err
}
if err := canasta.CloneStackRepo(orchestrator, canastaInfo.Id, &path); err != nil {
return err
}
if err := canasta.CopyEnv("", canastaInfo.DomainName, path, pwd); err != nil {
if err := canasta.CopyYaml(yamlPath, path); err != nil {
return err
}
if err := canasta.CopyEnv("", path, pwd); err != nil {
return err
}
if err := canasta.CopySettings(path); err != nil {
return err
}
if err := canasta.RewriteCaddy(path); err != nil {
return err
}
if err := orchestrators.CopyOverrideFile(path, orchestrator, override, pwd); err != nil {
Expand All @@ -85,7 +103,7 @@ func createCanasta(canastaInfo canasta.CanastaVariables, pwd, path, orchestrator
if err := orchestrators.Start(path, orchestrator); err != nil {
return err
}
if _, err := mediawiki.Install(path, orchestrator, canastaInfo); err != nil {
if _, err := mediawiki.Install(path, yamlPath, orchestrator, canastaInfo); err != nil {
return err
}
if err := config.Add(config.Installation{Id: canastaInfo.Id, Path: path, Orchestrator: orchestrator}); err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func Delete(instance config.Installation) error {
if err = config.Delete(instance.Id); err != nil {
return err
}

fmt.Println("Deleted.")
return nil
}
4 changes: 2 additions & 2 deletions cmd/extension/disable.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ func disableCmdCreate() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
extensions := strings.Split(args[0], ",")
for _, extension := range extensions {
extensionName, err := extensionsskins.CheckEnabled(extension, instance, constants)
extensionName, err := extensionsskins.CheckEnabled(extension, wiki, instance, constants)
if err != nil {
fmt.Print(err.Error() + "\n")
continue
}
extensionsskins.Disable(extensionName, instance, constants)
extensionsskins.Disable(extensionName, wiki, instance, constants)
}
return err
},
Expand Down
2 changes: 1 addition & 1 deletion cmd/extension/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func enableCmdCreate() *cobra.Command {
fmt.Print(err.Error() + "\n")
continue
}
extensionsskins.Enable(extensionName, instance, constants)
extensionsskins.Enable(extensionName, wiki, instance, constants)
}
return err
},
Expand Down
2 changes: 2 additions & 0 deletions cmd/extension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
var (
instance config.Installation
pwd string
wiki string
err error
verbose bool
extensionCmd *cobra.Command
Expand All @@ -40,6 +41,7 @@ func NewCmdCreate() *cobra.Command {
}
extensionCmd.PersistentFlags().StringVarP(&instance.Id, "id", "i", "", "Canasta instance ID")
extensionCmd.PersistentFlags().StringVarP(&instance.Path, "path", "p", pwd, "Canasta installation directory")
extensionCmd.PersistentFlags().StringVarP(&wiki, "wiki", "w", "", "ID of the specific wiki within the Canasta farm")
extensionCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose Output")

extensionCmd.AddCommand(listCmdCreate())
Expand Down
2 changes: 1 addition & 1 deletion cmd/import/importExisting.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func importCanasta(pwd, canastaId, domainName, path, orchestrator, databasePath,
if err := canasta.CloneStackRepo(orchestrator, canastaId, &path); err != nil {
return err
}
if err := canasta.CopyEnv(envPath, domainName, path, pwd); err != nil {
if err := canasta.CopyEnv(envPath, path, pwd); err != nil {
return err
}
if err := canasta.CopyDatabase(databasePath, path, pwd); err != nil {
Expand Down
Loading

0 comments on commit 81d2a71

Please sign in to comment.