support deployments
This commit is contained in:
parent
8f600b21fb
commit
e4ae62ad7b
9 changed files with 140 additions and 15 deletions
|
@ -37,8 +37,9 @@ Initially the user will be presented with the login screen; upon successful logi
|
|||
|
||||
- `Pages`: the default page, shows a list of existing pages - clicking one enables editing that page; a button is also presented for adding a new page. Each `Adapter` will provide different formatting help and can allow editable slugs/URLs or not (eg, the `EurekaAdapter` builds slugs/URLs directly from the page title).
|
||||
- `Files`: provides an interface for managing statically hosted files. Files and directories can be added, moved, and deleted.
|
||||
- `Build`: a simple form to build the site - build options configurable by `Adapter` are present under an accordion.
|
||||
- `Configuration`: interface to the configuration for the `Adapter`. Each `Adapter` provides its own configuration interface with associated data types (currently supported: `int`, `float`, `string`, and `multilinestring`)
|
||||
- `Build`: a simple form to build the site - build options configurable by `Adapter` are present under an accordion.
|
||||
- `Deploy`: a _very_ simple form to either deploy the site or revert the current state to the deployed state
|
||||
- `Logout`: logs the user out and returns to the login screen
|
||||
|
||||
## adapter interface
|
||||
|
@ -61,6 +62,8 @@ The `Adapter` interface and associated data types can be found in the [adapter.g
|
|||
- `SavePage(oldSlug, newSlug, title, content string) error`: given all the proper arguments, save a page to the backing store (eg filesystem, db)
|
||||
- `DeletePage(slug string) error`: given a slug, delete the corresponding page source and possibly its generated HTML, depending on the `Adapter`
|
||||
- `Build(buildOptions map[string][]string) BuildStatus`: takes a map of build option names to their values and builds the site, returning a `BuildStatus` object containing the success or failure as a boolean and the detailed status (eg, the console ouptut of the build process)
|
||||
- `Deploy() DeployStatus`: executes the deployment script and returns a `DeployStatus` object, analagous to a `BuildStatus`
|
||||
- `Revert() RevertStatus`: executes the reversion script and returns a `RevertStatus` object, analagous to a `BuildStatus`
|
||||
|
||||
## license
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ type BuildStatus struct {
|
|||
Message string
|
||||
}
|
||||
|
||||
type DeployStatus BuildStatus
|
||||
type RevertStatus BuildStatus
|
||||
|
||||
type Page struct {
|
||||
Title string
|
||||
Content string
|
||||
|
@ -38,4 +41,6 @@ type Adapter interface {
|
|||
SavePage(oldSlug, newSlug, title, content string) error
|
||||
DeletePage(slug string) error
|
||||
Build(buildOptions map[BuildOption]string) BuildStatus
|
||||
Deploy() DeployStatus
|
||||
Revert() RevertStatus
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ func (self *EurekaAdapter) Init(cfg *Config) {
|
|||
|
||||
err = self.readCfg()
|
||||
if err != nil {
|
||||
fmt.Printf(err.Error())
|
||||
fmt.Printf(err.Error())
|
||||
panic("config.h is malformed!")
|
||||
}
|
||||
}
|
||||
|
@ -302,6 +302,28 @@ func (self *EurekaAdapter) Build(buildOptions map[BuildOption]string) BuildStatu
|
|||
}
|
||||
}
|
||||
|
||||
func (self *EurekaAdapter) Deploy() DeployStatus {
|
||||
cmd := exec.Command("./deploy.sh")
|
||||
cmd.Dir = self.Root
|
||||
out, err := cmd.CombinedOutput()
|
||||
|
||||
return DeployStatus{
|
||||
Success: err == nil,
|
||||
Message: string(out),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *EurekaAdapter) Revert() RevertStatus {
|
||||
cmd := exec.Command("./deploy.sh", "--resync")
|
||||
cmd.Dir = self.Root
|
||||
out, err := cmd.CombinedOutput()
|
||||
|
||||
return RevertStatus{
|
||||
Success: err == nil,
|
||||
Message: string(out),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *EurekaAdapter) readCfg() error {
|
||||
configPath := filepath.Join(self.Root, "config.h")
|
||||
_, err := os.Stat(filepath.Join(self.Root, "config.h"))
|
||||
|
@ -315,9 +337,9 @@ func (self *EurekaAdapter) readCfg() error {
|
|||
}
|
||||
|
||||
fileData := strings.Replace(
|
||||
strings.Replace(
|
||||
string(f[:]), "/* clang-format on */", "", -1),
|
||||
"/* clang-format off */", "", -1)
|
||||
strings.Replace(
|
||||
string(f[:]), "/* clang-format on */", "", -1),
|
||||
"/* clang-format off */", "", -1)
|
||||
|
||||
macros := strings.Split(fileData, "#define ")[1:]
|
||||
for _, macro := range macros {
|
||||
|
@ -370,8 +392,8 @@ func (self *EurekaAdapter) readCfg() error {
|
|||
}
|
||||
cfgType := "int"
|
||||
if strings.HasPrefix(k, "IS_") {
|
||||
cfgType = "bool"
|
||||
}
|
||||
cfgType = "bool"
|
||||
}
|
||||
self.Config[ConfigOption{
|
||||
Name: k,
|
||||
Type: cfgType,
|
||||
|
@ -389,11 +411,11 @@ func (self *EurekaAdapter) writeCfg() error {
|
|||
|
||||
defer f.Close()
|
||||
|
||||
f.WriteString("/* clang-format off */\n");
|
||||
f.WriteString("/* clang-format off */\n")
|
||||
for k, v := range self.Config {
|
||||
switch k.Type {
|
||||
case "int":
|
||||
fallthrough
|
||||
fallthrough
|
||||
case "bool":
|
||||
_, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
|
@ -418,6 +440,6 @@ func (self *EurekaAdapter) writeCfg() error {
|
|||
}
|
||||
}
|
||||
|
||||
f.WriteString("/* clang-format on */\n");
|
||||
f.WriteString("/* clang-format on */\n")
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ package lfo
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
core "hacklab.nilfm.cc/nirvash/archetype"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
48
nirvash.go
48
nirvash.go
|
@ -1,14 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
core "hacklab.nilfm.cc/nirvash/archetype"
|
||||
. "hacklab.nilfm.cc/nirvash/lfo"
|
||||
"hacklab.nilfm.cc/quartzgun/indentalUserDB"
|
||||
. "hacklab.nilfm.cc/quartzgun/middleware"
|
||||
"hacklab.nilfm.cc/quartzgun/renderer"
|
||||
"hacklab.nilfm.cc/quartzgun/router"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
@ -161,6 +161,50 @@ func main() {
|
|||
udb,
|
||||
"/"))
|
||||
|
||||
rtr.Get(
|
||||
`/deploy`,
|
||||
Fortify(
|
||||
Protected(
|
||||
WithAdapter(
|
||||
renderer.Template(
|
||||
pathConcat(templateRoot, "deploy.html"),
|
||||
pathConcat(templateRoot, "header.html"),
|
||||
pathConcat(templateRoot, "footer.html")),
|
||||
cfg.Adapter),
|
||||
http.MethodGet,
|
||||
udb,
|
||||
"/login")))
|
||||
|
||||
rtr.Post(
|
||||
`/deploy`,
|
||||
Defend(
|
||||
Protected(
|
||||
WithAdapter(
|
||||
renderer.Template(
|
||||
pathConcat(templateRoot, "deployed.html"),
|
||||
pathConcat(templateRoot, "header.html"),
|
||||
pathConcat(templateRoot, "footer.html")),
|
||||
cfg.Adapter),
|
||||
http.MethodGet,
|
||||
udb,
|
||||
"/login"),
|
||||
udb,
|
||||
"/"))
|
||||
rtr.Post(
|
||||
`/revert`,
|
||||
Defend(
|
||||
Protected(
|
||||
WithAdapter(
|
||||
renderer.Template(
|
||||
pathConcat(templateRoot, "reverted.html"),
|
||||
pathConcat(templateRoot, "header.html"),
|
||||
pathConcat(templateRoot, "footer.html")),
|
||||
cfg.Adapter),
|
||||
http.MethodGet,
|
||||
udb,
|
||||
"/login"),
|
||||
udb,
|
||||
"/"))
|
||||
rtr.Post(
|
||||
`/delete/(?P<Slug>\S+)`,
|
||||
Defend(
|
||||
|
|
16
templates/deploy.html
Normal file
16
templates/deploy.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{{ $csrfToken := (.Context).Value "csrfToken" }}
|
||||
|
||||
{{ template "header" . }}
|
||||
|
||||
<h2>Deployment</h2>
|
||||
|
||||
<form class="build" method="POST" action="/deploy">
|
||||
<input hidden name="csrfToken" value="{{$csrfToken}}"/>
|
||||
<input type="submit" value="Deploy"/>
|
||||
</form>
|
||||
<form class="build" method="POST" action="/revert">
|
||||
<input hidden name="csrfToken" value="{{$csrfToken}}"/>
|
||||
<input type="submit" value="Revert"/>
|
||||
</form>
|
||||
|
||||
{{ template "footer" . }}
|
17
templates/deployed.html
Normal file
17
templates/deployed.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
{{ $status := ((.Context).Value "adapter").Deploy }}
|
||||
|
||||
{{ template "header" . }}
|
||||
|
||||
{{ if ne ($status).Success true }}
|
||||
|
||||
<h2>Deployment Error</h2>
|
||||
<span class="adapter-error"><pre>{{($status).Message}}</pre></span>
|
||||
|
||||
{{ else }}
|
||||
|
||||
<h2>Deployment Successful</h2>
|
||||
<span class="adapter-success"><pre>{{($status).Message}}</pre></span>
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ template "footer" . }}
|
|
@ -14,8 +14,9 @@
|
|||
<ul>
|
||||
<li><a href="/">Pages</a></li>
|
||||
<li><a href="/file-mgr">Files</a></li>
|
||||
<li><a href="/build">Build</a></li>
|
||||
<li><a href="/config">Configuration</a></li>
|
||||
<li><a href="/build">Build</a></li>
|
||||
<li><a href="/deploy">Deployment</a></li>
|
||||
<li><a href="/logout">Logout</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
17
templates/reverted.html
Normal file
17
templates/reverted.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
{{ $status := ((.Context).Value "adapter").Revert }}
|
||||
|
||||
{{ template "header" . }}
|
||||
|
||||
{{ if ne ($status).Success true }}
|
||||
|
||||
<h2>Revert Error</h2>
|
||||
<span class="adapter-error"><pre>{{($status).Message}}</pre></span>
|
||||
|
||||
{{ else }}
|
||||
|
||||
<h2>Revert Successful</h2>
|
||||
<span class="adapter-success"><pre>{{($status).Message}}</pre></span>
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{ template "footer" . }}
|
Loading…
Reference in a new issue