Adding even more components
- Starting on main manager page - Manager layout will be included in the manager page - Manager page will use htmx to load different components via api
This commit is contained in:
parent
5fd215d6dd
commit
223496075a
11
main.go
11
main.go
@ -4,10 +4,12 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
"git.staur.ca/stobbsm/clustvirt/view/layouts"
|
||||
"git.staur.ca/stobbsm/clustvirt/view/static"
|
||||
"github.com/a-h/templ"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
const DEBUG bool = true
|
||||
@ -28,6 +30,10 @@ func main() {
|
||||
|
||||
// Start webserver and serve homepage
|
||||
|
||||
defaultNavBar := []components.NavItem{
|
||||
{Name: "Home", Href: "/"},
|
||||
{Name: "About", Href: "/about"},
|
||||
}
|
||||
fs := http.StripPrefix("/static/", http.FileServer(http.Dir("public")))
|
||||
|
||||
r := chi.NewRouter()
|
||||
@ -41,7 +47,8 @@ func main() {
|
||||
}
|
||||
fs.ServeHTTP(w, r)
|
||||
})
|
||||
r.Get("/", templ.Handler(static.Home()).ServeHTTP)
|
||||
r.Get("/", templ.Handler(layouts.Manager("Cluster Manager", "ClustVirt", defaultNavBar)).ServeHTTP)
|
||||
r.Get("/about", templ.Handler(static.Home()).ServeHTTP)
|
||||
|
||||
log.Println(http.ListenAndServe(":3000", r))
|
||||
}
|
||||
|
@ -848,6 +848,26 @@ span>a:visited {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.my-8 {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.mx-2 {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.my-2 {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.mx-4 {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.mr-auto {
|
||||
margin-right: auto;
|
||||
}
|
||||
@ -856,10 +876,18 @@ span>a:visited {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.inline-flex {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.contents {
|
||||
display: contents;
|
||||
}
|
||||
@ -868,6 +896,30 @@ span>a:visited {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.size-fit {
|
||||
width: -moz-fit-content;
|
||||
width: fit-content;
|
||||
height: -moz-fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.size-max {
|
||||
width: -moz-max-content;
|
||||
width: max-content;
|
||||
height: -moz-max-content;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
.size-72 {
|
||||
width: 18rem;
|
||||
height: 18rem;
|
||||
}
|
||||
|
||||
.size-64 {
|
||||
width: 16rem;
|
||||
height: 16rem;
|
||||
}
|
||||
|
||||
.h-4 {
|
||||
height: 1rem;
|
||||
}
|
||||
@ -908,6 +960,52 @@ span>a:visited {
|
||||
height: 7rem;
|
||||
}
|
||||
|
||||
.h-44 {
|
||||
height: 11rem;
|
||||
}
|
||||
|
||||
.h-52 {
|
||||
height: 13rem;
|
||||
}
|
||||
|
||||
.h-36 {
|
||||
height: 9rem;
|
||||
}
|
||||
|
||||
.h-40 {
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.h-max {
|
||||
height: -moz-max-content;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
.h-auto {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.h-48 {
|
||||
height: 12rem;
|
||||
}
|
||||
|
||||
.h-56 {
|
||||
height: 14rem;
|
||||
}
|
||||
|
||||
.h-64 {
|
||||
height: 16rem;
|
||||
}
|
||||
|
||||
.h-72 {
|
||||
height: 18rem;
|
||||
}
|
||||
|
||||
.h-fit {
|
||||
height: -moz-fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
@ -933,10 +1031,55 @@ span>a:visited {
|
||||
width: 91.666667%;
|
||||
}
|
||||
|
||||
.w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.w-40 {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.w-44 {
|
||||
width: 11rem;
|
||||
}
|
||||
|
||||
.w-auto {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.w-48 {
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
.w-52 {
|
||||
width: 13rem;
|
||||
}
|
||||
|
||||
.w-64 {
|
||||
width: 16rem;
|
||||
}
|
||||
|
||||
.w-72 {
|
||||
width: 18rem;
|
||||
}
|
||||
|
||||
.w-max {
|
||||
width: -moz-max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.flex-auto {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.flex-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.basis-1\/2 {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
@ -969,6 +1112,14 @@ span>a:visited {
|
||||
flex-basis: 66.666667%;
|
||||
}
|
||||
|
||||
.basis-2\/4 {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
|
||||
.basis-2\/5 {
|
||||
flex-basis: 40%;
|
||||
}
|
||||
|
||||
.list-inside {
|
||||
list-style-position: inside;
|
||||
}
|
||||
@ -1009,6 +1160,10 @@ span>a:visited {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
@ -9048,6 +9203,26 @@ span>a:visited {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.self-center {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.justify-self-end {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.justify-self-center {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.border-uiblue-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(221 231 248 / var(--tw-border-opacity));
|
||||
@ -138667,6 +138842,11 @@ span>a:visited {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.py-8 {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.align-bottom {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
@ -220316,6 +220496,10 @@ span>a:visited {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.md\:inline-flex {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.md\:contents {
|
||||
display: contents;
|
||||
}
|
||||
|
BIN
public/images/home/logo-banner-dark-800.png
(Stored with Git LFS)
Normal file
BIN
public/images/home/logo-banner-dark-800.png
(Stored with Git LFS)
Normal file
Binary file not shown.
5
view/components/hero.templ
Normal file
5
view/components/hero.templ
Normal file
@ -0,0 +1,5 @@
|
||||
package components
|
||||
|
||||
templ Hero() {
|
||||
{ children... }
|
||||
}
|
35
view/components/hero_templ.go
Normal file
35
view/components/hero_templ.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.598
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
func Hero() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
40
view/components/navbar.templ
Normal file
40
view/components/navbar.templ
Normal file
@ -0,0 +1,40 @@
|
||||
package components
|
||||
|
||||
templ NavBar(hero templ.Component, navItems []NavItem) {
|
||||
<nav
|
||||
class={ "w-100",
|
||||
"bg-uigrey-600",
|
||||
"shadow",
|
||||
"shadow-uigrey-700",
|
||||
"rounded",
|
||||
"rounded-full",
|
||||
"md:px-auto" }
|
||||
>
|
||||
<div
|
||||
class={ "md:h-16",
|
||||
"h-28",
|
||||
"mx-auto",
|
||||
"md:px-4",
|
||||
"container",
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-between",
|
||||
"flex-wrap",
|
||||
"md:flex-nowrap" }
|
||||
>
|
||||
<a href="/">
|
||||
@hero
|
||||
</a>
|
||||
<div class={ "text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3" }>
|
||||
<ul class={ "flex", "justify-between", "sm:w-full", "md:w-auto" }>
|
||||
for _, ni := range navItems {
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }>
|
||||
<a href={ templ.URL(ni.Href) }>{ ni.Name }</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<div class={ "order-2", "md:order-3" }>Login</div>
|
||||
</div>
|
||||
</nav>
|
||||
}
|
184
view/components/navbar_templ.go
Normal file
184
view/components/navbar_templ.go
Normal file
@ -0,0 +1,184 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.598
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
func NavBar(hero templ.Component, navItems []NavItem) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{"w-100",
|
||||
"bg-uigrey-600",
|
||||
"shadow",
|
||||
"shadow-uigrey-700",
|
||||
"rounded",
|
||||
"rounded-full",
|
||||
"md:px-auto"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<nav class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var2).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 = []any{"md:h-16",
|
||||
"h-28",
|
||||
"mx-auto",
|
||||
"md:px-4",
|
||||
"container",
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-between",
|
||||
"flex-wrap",
|
||||
"md:flex-nowrap"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var3).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"/\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = hero.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{"text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var4).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 = []any{"flex", "justify-between", "sm:w-full", "md:w-auto"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<ul class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var5).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, ni := range navItems {
|
||||
var templ_7745c5c3_Var6 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var6).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 templ.SafeURL = templ.URL(ni.Href)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var7)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(ni.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/components/navbar.templ`, Line: 31, Col: 47}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</ul></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 = []any{"order-2", "md:order-3"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var9).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">Login</div></div></nav>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
@ -4,6 +4,11 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type NavItem struct {
|
||||
Name string
|
||||
Href string
|
||||
}
|
||||
|
||||
func NoWrapSize(size string) string {
|
||||
return fmt.Sprintf("%s:flex-nowrap", size)
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package layouts
|
||||
|
||||
templ Manager(config LayoutConfig) {
|
||||
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
|
||||
templ Manager(title string, subtitle string, navBarItem []components.NavItem) {
|
||||
<!DOCTYPE html>
|
||||
<html class={ "text-slate-50", "bg-slate-900" }>
|
||||
<head>
|
||||
@ -9,11 +11,11 @@ templ Manager(config LayoutConfig) {
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class={}>
|
||||
@header(config.MainTitle, config.SubTitle)
|
||||
<header class={"mx-4"}>
|
||||
@header(title, subtitle, navBarItem)
|
||||
</header>
|
||||
|
||||
<footer>
|
||||
<footer class={"mx-4"}>
|
||||
@footer()
|
||||
</footer>
|
||||
</body>
|
||||
|
@ -10,7 +10,9 @@ import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
func Manager(config LayoutConfig) templ.Component {
|
||||
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
|
||||
func Manager(title string, subtitle string, navBarItem []components.NavItem) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
@ -44,7 +46,7 @@ func Manager(config LayoutConfig) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 = []any{}
|
||||
var templ_7745c5c3_Var3 = []any{"mx-4"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
@ -61,11 +63,28 @@ func Manager(config LayoutConfig) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = header(config.MainTitle, config.SubTitle).Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = header(title, subtitle, navBarItem).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</header><footer>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</header>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{"mx-4"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<footer class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var4).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -1,68 +1,41 @@
|
||||
package layouts
|
||||
|
||||
templ StaticPage(title string, subtitle string) {
|
||||
<!DOCTYPE html>
|
||||
<html class={ "text-uigrey-100" , "bg-uigrey-900" }>
|
||||
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
|
||||
<head>
|
||||
<title>Clustvirt</title>
|
||||
<link href="/static/css/style.css" type="text/css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
@header(title, subtitle)
|
||||
</header>
|
||||
<div id="content" name="content" class={ "flex" , "flex-col" , "gap-2" }>
|
||||
{ children... }
|
||||
</div>
|
||||
<footer>
|
||||
@footer()
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
templ StaticPage(title string, subtitle string, navBarItems []components.NavItem) {
|
||||
<!DOCTYPE html>
|
||||
<html class={ "text-uigrey-100" , "bg-uigrey-900" }>
|
||||
<head>
|
||||
<title>Clustvirt</title>
|
||||
<link href="/static/css/style.css" type="text/css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
@header(title, subtitle, navBarItems)
|
||||
</header>
|
||||
<div id="content" name="content" class={ "flex" , "flex-col" , "gap-2" }>
|
||||
{ children... }
|
||||
</div>
|
||||
<footer>
|
||||
@footer()
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
|
||||
templ header(title string, subtitle string) {
|
||||
<h2 class={ "text-lg" , "font-semibold" , "italic" , "h-6" }>{ subtitle }</h2>
|
||||
@nav(title)
|
||||
templ hero(title string) {
|
||||
<h1 class={ "text-2xl", "font-bold", "text-uiblue-200", "md:order-1" }>{ title }</h1>
|
||||
}
|
||||
|
||||
templ nav(title string) {
|
||||
<nav class={ "w-100" , "bg-uigrey-600" , "shadow" , "shadow-uigrey-700" , "md:px-auto" }>
|
||||
<div class={
|
||||
"md:h-16",
|
||||
"h-28",
|
||||
"mx-auto",
|
||||
"md:px-4",
|
||||
"container",
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-between",
|
||||
"flex-wrap",
|
||||
"md:flex-nowrap" }>
|
||||
<h1 class={ "text-2xl", "font-bold", "text-uiblue-200", "md:order-1" }>{ title }</h1>
|
||||
<div class={"text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3"}>
|
||||
<ul class={ "flex", "justify-between", "sm:w-full", "md:w-auto" }>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">What</a></li>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Why</a></li>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Goals</a></li>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Stretch</a></li>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Requests</a></li>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Never</a></li>
|
||||
<li class={ "hover:text-uiblue-200", "md:px-4", "md:py-2" }><a href="#">Notes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class={"order-2", "md:order-3"}>Login</div>
|
||||
</div>
|
||||
</nav>
|
||||
templ header(title string, subtitle string, navBarItems []components.NavItem) {
|
||||
<h2 class={ "text-lg" , "font-semibold" , "italic" , "h-6" }>{ subtitle }</h2>
|
||||
@components.NavBar(hero(title), navBarItems)
|
||||
}
|
||||
|
||||
templ footer() {
|
||||
<div class="flex gap-4 md:gap-6 sm:gap-8 divide divide-solid">
|
||||
<div id="footer_left" class="flex-auto basis-1/4 md:basis-1/3 p-2">Left</div>
|
||||
<div id="footer_middle" class="flex-auto basis-1/2 md:basis-1/3 p-2">Middle</div>
|
||||
<div id="footer_right" class="flex-auto basis-1/4 md:basis-1/3 p-2">Right</div>
|
||||
</div>
|
||||
<div class="flex gap-4 md:gap-6 sm:gap-8 divide divide-solid">
|
||||
<div id="footer_left" class="flex-auto basis-1/4 md:basis-1/3 p-2">Left</div>
|
||||
<div id="footer_middle" class="flex-auto basis-1/2 md:basis-1/3 p-2">Middle</div>
|
||||
<div id="footer_right" class="flex-auto basis-1/4 md:basis-1/3 p-2">Right</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -10,7 +10,9 @@ import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
func StaticPage(title string, subtitle string) templ.Component {
|
||||
import "git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
|
||||
func StaticPage(title string, subtitle string, navBarItems []components.NavItem) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
@ -44,7 +46,7 @@ func StaticPage(title string, subtitle string) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = header(title, subtitle).Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = header(title, subtitle, navBarItems).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -92,7 +94,7 @@ func StaticPage(title string, subtitle string) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func header(title string, subtitle string) templ.Component {
|
||||
func hero(title string) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
@ -105,12 +107,12 @@ func header(title string, subtitle string) templ.Component {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var5 = []any{"text-lg", "font-semibold", "italic", "h-6"}
|
||||
var templ_7745c5c3_Var5 = []any{"text-2xl", "font-bold", "text-uiblue-200", "md:order-1"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h2 class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -123,19 +125,15 @@ func header(title string, subtitle string) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 27, Col: 71}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 26, Col: 80}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = nav(title).Render(ctx, templ_7745c5c3_Buffer)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -146,7 +144,7 @@ func header(title string, subtitle string) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func nav(title string) templ.Component {
|
||||
func header(title string, subtitle string, navBarItems []components.NavItem) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
@ -159,12 +157,12 @@ func nav(title string) templ.Component {
|
||||
templ_7745c5c3_Var7 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var8 = []any{"w-100", "bg-uigrey-600", "shadow", "shadow-uigrey-700", "md:px-auto"}
|
||||
var templ_7745c5c3_Var8 = []any{"text-lg", "font-semibold", "italic", "h-6"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<nav class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h2 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -176,230 +174,20 @@ func nav(title string) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 = []any{
|
||||
"md:h-16",
|
||||
"h-28",
|
||||
"mx-auto",
|
||||
"md:px-4",
|
||||
"container",
|
||||
"flex",
|
||||
"items-center",
|
||||
"justify-between",
|
||||
"flex-wrap",
|
||||
"md:flex-nowrap"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 30, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var9).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 = []any{"text-2xl", "font-bold", "text-uiblue-200", "md:order-1"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var10).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layouts/staticpage.templ`, Line: 44, Col: 82}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 = []any{"text-uigrey-200", "font-semibold", "md:w-auto", "md:order-2", "order-3"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var12).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 = []any{"flex", "justify-between", "sm:w-full", "md:w-auto"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<ul class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var13).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var14).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">What</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var15).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Why</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var16).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Goals</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var17).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Stretch</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var18 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var18).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Requests</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var19 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var19).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Never</a></li>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var20 = []any{"hover:text-uiblue-200", "md:px-4", "md:py-2"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var20).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><a href=\"#\">Notes</a></li></ul></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var21 = []any{"order-2", "md:order-3"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var21...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ.CSSClasses(templ_7745c5c3_Var21).String()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">Login</div></div></nav>")
|
||||
templ_7745c5c3_Err = components.NavBar(hero(title), navBarItems).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -418,9 +206,9 @@ func footer() templ.Component {
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var22 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var22 == nil {
|
||||
templ_7745c5c3_Var22 = templ.NopComponent
|
||||
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var10 == nil {
|
||||
templ_7745c5c3_Var10 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex gap-4 md:gap-6 sm:gap-8 divide divide-solid\"><div id=\"footer_left\" class=\"flex-auto basis-1/4 md:basis-1/3 p-2\">Left</div><div id=\"footer_middle\" class=\"flex-auto basis-1/2 md:basis-1/3 p-2\">Middle</div><div id=\"footer_right\" class=\"flex-auto basis-1/4 md:basis-1/3 p-2\">Right</div></div>")
|
||||
|
@ -1,249 +1,257 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"git.staur.ca/stobbsm/clustvirt/view/layouts"
|
||||
"git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
"git.staur.ca/stobbsm/clustvirt/view/layouts"
|
||||
"git.staur.ca/stobbsm/clustvirt/view/components"
|
||||
)
|
||||
|
||||
templ Home() {
|
||||
@layouts.StaticPage("ClustVirt", "Libvirt, clustered and managed") {
|
||||
@components.FlexRow(true) {
|
||||
<div class={ "basis-1/3" }>
|
||||
@components.InfoBox("What is This?", "uiorange") {
|
||||
@components.ContentP() {
|
||||
Clustvirt (work in progress name) aims to be the agnostic
|
||||
cluster controller for libvirtd. The server component is
|
||||
used to display both the WebUI and run the REST API used to
|
||||
control one to many libvirtd hosts to manage virual machines,
|
||||
LXC containers (through libvirtd), gather information about
|
||||
each host, and monitor each host.
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class={ "basis-2/3" }>
|
||||
@components.InfoBox("Why?", "uiblue") {
|
||||
@components.List("informational") {
|
||||
@components.ListItem() {
|
||||
Broadcom buying VMWare, and VMWare losing a free
|
||||
teir for homelabbers pissed me off
|
||||
}
|
||||
@components.ListItem() {
|
||||
Vendor lock-in pisses me off
|
||||
}
|
||||
@components.ListItem() {
|
||||
Even good open source Hyperconverged systems
|
||||
(Proxmox, as an example) exhibit a form of vendor lock-in
|
||||
}
|
||||
@components.ListItem() {
|
||||
Libvirt is terrific, has the functionality for everything
|
||||
those other providers do, but there really is not a great
|
||||
option for those dipping their toes into Open Source
|
||||
}
|
||||
@components.ListItem() {
|
||||
Its fun to build things that solve a need
|
||||
}
|
||||
@components.ListItem() {
|
||||
I really want to do it
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@components.FlexRow(true) {
|
||||
<div class={ "basis-7/12" }>
|
||||
@components.InfoBox("Project Goals", "uigreen") {
|
||||
@components.List("accepted") {
|
||||
@components.ListItem() {
|
||||
Open source, currently on the MIT license
|
||||
}
|
||||
@components.ListItem() {
|
||||
Base OS Agnostic. If it can run libvirtd, this should be able to control it on some level
|
||||
}
|
||||
@components.ListItem() {
|
||||
Control the Virtual Machine life cycle on one or more libvirtd hosts
|
||||
}
|
||||
@components.ListItem() {
|
||||
Add clusting capabilities to libvirtd host, including;
|
||||
}
|
||||
@components.ListItem() {
|
||||
Migration of VMs
|
||||
}
|
||||
@components.ListItem() {
|
||||
Syncronizing secrets
|
||||
}
|
||||
@components.ListItem() {
|
||||
Syncronizing VLANs, bridges, host only networking
|
||||
}
|
||||
@components.ListItem() {
|
||||
Sharing HA storage availability
|
||||
}
|
||||
@components.ListItem() {
|
||||
Locking shared resources like disks
|
||||
}
|
||||
@components.ListItem() {
|
||||
Starting VMs marked for HA on another host when one goes down
|
||||
}
|
||||
@components.ListItem() {
|
||||
Manage a library of Cloud-init resources and templates to build new VMs quickly
|
||||
}
|
||||
@components.ListItem() {
|
||||
Local Storage management, including local directory, lvm, zfs (if installed)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Advanced Storage management, such as Ceph, glusterfs, drbd, iscsi, nfs
|
||||
}
|
||||
@components.ListItem() {
|
||||
Storage syncronization of local disks between hosts (zfs snapshots, lvm snapshots, rsync)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Backup scheduling, creation, restoration
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class={ "basis-5/12" }>
|
||||
@components.InfoBox("Stretch Goals", "uipurple") {
|
||||
@components.List("possible") {
|
||||
@components.ListItem() {
|
||||
Install the OS which libvirtd is running on
|
||||
}
|
||||
@components.ListItem() {
|
||||
Install/provision libvirtd on a host that does not have it installed
|
||||
}
|
||||
@components.ListItem() {
|
||||
Tools to move from one vendor to clustvirt/libvirtd
|
||||
}
|
||||
@components.ListItem() {
|
||||
VM templates for common aspects of VM creation and management,
|
||||
like appliances
|
||||
}
|
||||
@components.ListItem() {
|
||||
External tool access that can be used to manage things that are not
|
||||
managed here (cephadm dashboard, for instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@components.FlexRow(true) {
|
||||
<div class={ "basis-8/12" }>
|
||||
@components.InfoBox("Reddit Requested Feature", "uiyellow") {
|
||||
@components.List("possible") {
|
||||
@components.ListItem() {
|
||||
Search/Filter on hosts/vms - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Balance on resource usage per host/Automattically migrate to least
|
||||
used host - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Support inter-vm only commmunication (VxLAN style) - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Deploy VMs using only API - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Well documented, first class API - @kasperlitheater
|
||||
}
|
||||
@components.ListItem() {
|
||||
Bootstrap service to configure a new server - @phatpappa_
|
||||
}
|
||||
@components.ListItem() {
|
||||
For the love of kitten, don't use XML as configuration files - @pascalbrax
|
||||
}
|
||||
@components.ListItem() {
|
||||
Expose the Cluster Manager functionalities as API - @raven2611
|
||||
}
|
||||
@components.ListItem() {
|
||||
CPU architecture awareness for migrations - @raven2611
|
||||
}
|
||||
@components.ListItem() {
|
||||
Inter VM Communications via VXLAN/EVPN - @raven2611
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class={ "basis-4/12" }>
|
||||
@components.InfoBox("Never Going to Happen", "uired") {
|
||||
@components.List("never") {
|
||||
@components.ListItem() {
|
||||
Kubernetes
|
||||
}
|
||||
@components.ListItem() {
|
||||
Application container management (docker, podman, etc)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Become an OS
|
||||
}
|
||||
@components.ListItem() {
|
||||
Have a paywall
|
||||
}
|
||||
@components.ListItem() {
|
||||
Vendor lock-in
|
||||
}
|
||||
@components.ListItem() {
|
||||
Become a commercial entity (even indirectly)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Anything that does not have an Open Source standard behind it
|
||||
}
|
||||
@components.ListItem() {
|
||||
Directly control a guest Operating System
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@components.InfoBox("Other things to note", "uipink") {
|
||||
@components.ContentP() {
|
||||
I recently created a <span>@components.ANewTab("http://redd.it/1bct15z", "post")
|
||||
</span>
|
||||
on reddit announcing that I was building this, and while the majority
|
||||
of responses were supportive, even offering features that may enhance
|
||||
what I originally set out to do, many responded with
|
||||
"Why do we need another one??"
|
||||
}
|
||||
@components.ContentP() {
|
||||
Besides the list above about why this exists, I wanted to clarify
|
||||
a few things those individuals did not seeem to get: This is not
|
||||
a rebuild of Proxmox, Cloudstack, VMWare, Harvester or any of
|
||||
the other "Hyper-converged/Single-solution/turnkey/Operating System"
|
||||
offerings out there. This will not take over your base operating system
|
||||
on your machine, just act as a cluster manager and interface to access
|
||||
the existing libvirtd instances on those machines, nor will it prescribe
|
||||
a set of requirements that make it hard to move your own infrastructure
|
||||
around.
|
||||
}
|
||||
@components.ContentP() {
|
||||
At the heart of this project is that I hate the enshitifiation of
|
||||
Open Source that has been going on, where its just another way to make
|
||||
money and control the eco system. RedHat tried to do it by locking
|
||||
down their source code, Proxmox does it by making sure anything you
|
||||
do on Proxmox is tied to Proxmox (no offense to Proxmox), and even
|
||||
Hashicorp, who I loved so dearly, changed from a pure Open Source
|
||||
licensing model to one that protects the business over the community
|
||||
}
|
||||
@components.ContentP() {
|
||||
I will not let that happen here.
|
||||
}
|
||||
@components.ContentP() {
|
||||
This project will seek to use the Unix philosophy, of building off
|
||||
of existing standards, combining tools, and having one tool do one
|
||||
job well. This does not mean there will be one application for each
|
||||
aspect of the job, but that this application stack will manage Libvirtd
|
||||
well, and have individual and configurable paths to manage each sub-aspect
|
||||
of the libvirt stack. This stack will not create a Ceph cluster for you,
|
||||
it leaves you to do that. It will not even talk to a ceph cluster.
|
||||
It will, however, let you add that cluster via configuration options to
|
||||
define it as a storage pool that libvirt can use.
|
||||
}
|
||||
@components.ContentP() {
|
||||
If you want something that will allow you to use a single interface
|
||||
to create all sub aspects that can be used by libvirt
|
||||
(managing all firewall rules, creating a ceph cluster, etc.),
|
||||
use something like Proxmox which includes that builtin
|
||||
functionality. This isn't the stack for you.
|
||||
}
|
||||
}
|
||||
}
|
||||
@layouts.StaticPage("ClustVirt", "Libvirt, clustered and managed", []components.NavItem{
|
||||
{Name: "What", Href: "#"},
|
||||
{Name: "Why", Href: "#"},
|
||||
{Name: "Goals", Href: "#"},
|
||||
{Name: "Stretch", Href: "#"},
|
||||
{Name: "Requests", Href: "#"},
|
||||
{Name: "Never", Href: "#"},
|
||||
{Name: "Notes", Href: "#"},
|
||||
}) {
|
||||
<div>
|
||||
@components.InfoBox("What is This?", "uiorange") {
|
||||
<div class={"mx-4"}>
|
||||
@components.ContentP() {
|
||||
Clustvirt (work in progress name) aims to be the agnostic
|
||||
cluster controller for libvirtd. The server component is
|
||||
used to display both the WebUI and run the REST API used to
|
||||
control one to many libvirtd hosts to manage virual machines,
|
||||
LXC containers (through libvirtd), gather information about
|
||||
each host, and monitor each host.
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@components.InfoBox("Why?", "uiblue") {
|
||||
@components.List("informational") {
|
||||
@components.ListItem() {
|
||||
Broadcom buying VMWare, and VMWare losing a free
|
||||
teir for homelabbers pissed me off
|
||||
}
|
||||
@components.ListItem() {
|
||||
Vendor lock-in pisses me off
|
||||
}
|
||||
@components.ListItem() {
|
||||
Even good open source Hyperconverged systems
|
||||
(Proxmox, as an example) exhibit a form of vendor lock-in
|
||||
}
|
||||
@components.ListItem() {
|
||||
Libvirt is terrific, has the functionality for everything
|
||||
those other providers do, but there really is not a great
|
||||
option for those dipping their toes into Open Source
|
||||
}
|
||||
@components.ListItem() {
|
||||
Its fun to build things that solve a need
|
||||
}
|
||||
@components.ListItem() {
|
||||
I really want to do it
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@components.InfoBox("Project Goals", "uigreen") {
|
||||
@components.List("accepted") {
|
||||
@components.ListItem() {
|
||||
Open source, currently on the MIT license
|
||||
}
|
||||
@components.ListItem() {
|
||||
Base OS Agnostic. If it can run libvirtd, this should be able to control it on some level
|
||||
}
|
||||
@components.ListItem() {
|
||||
Control the Virtual Machine life cycle on one or more libvirtd hosts
|
||||
}
|
||||
@components.ListItem() {
|
||||
Add clusting capabilities to libvirtd host, including;
|
||||
}
|
||||
@components.ListItem() {
|
||||
Migration of VMs
|
||||
}
|
||||
@components.ListItem() {
|
||||
Syncronizing secrets
|
||||
}
|
||||
@components.ListItem() {
|
||||
Syncronizing VLANs, bridges, host only networking
|
||||
}
|
||||
@components.ListItem() {
|
||||
Sharing HA storage availability
|
||||
}
|
||||
@components.ListItem() {
|
||||
Locking shared resources like disks
|
||||
}
|
||||
@components.ListItem() {
|
||||
Starting VMs marked for HA on another host when one goes down
|
||||
}
|
||||
@components.ListItem() {
|
||||
Manage a library of Cloud-init resources and templates to build new VMs quickly
|
||||
}
|
||||
@components.ListItem() {
|
||||
Local Storage management, including local directory, lvm, zfs (if installed)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Advanced Storage management, such as Ceph, glusterfs, drbd, iscsi, nfs
|
||||
}
|
||||
@components.ListItem() {
|
||||
Storage syncronization of local disks between hosts (zfs snapshots, lvm snapshots, rsync)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Backup scheduling, creation, restoration
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@components.InfoBox("Stretch Goals", "uipurple") {
|
||||
@components.List("possible") {
|
||||
@components.ListItem() {
|
||||
Install the OS which libvirtd is running on
|
||||
}
|
||||
@components.ListItem() {
|
||||
Install/provision libvirtd on a host that does not have it installed
|
||||
}
|
||||
@components.ListItem() {
|
||||
Tools to move from one vendor to clustvirt/libvirtd
|
||||
}
|
||||
@components.ListItem() {
|
||||
VM templates for common aspects of VM creation and management,
|
||||
like appliances
|
||||
}
|
||||
@components.ListItem() {
|
||||
External tool access that can be used to manage things that are not
|
||||
managed here (cephadm dashboard, for instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@components.InfoBox("Reddit Requested Feature", "uiyellow") {
|
||||
@components.List("possible") {
|
||||
@components.ListItem() {
|
||||
Search/Filter on hosts/vms - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Balance on resource usage per host/Automattically migrate to least
|
||||
used host - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Support inter-vm only commmunication (VxLAN style) - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Deploy VMs using only API - @Lopsided_Speaker_553
|
||||
}
|
||||
@components.ListItem() {
|
||||
Well documented, first class API - @kasperlitheater
|
||||
}
|
||||
@components.ListItem() {
|
||||
Bootstrap service to configure a new server - @phatpappa_
|
||||
}
|
||||
@components.ListItem() {
|
||||
For the love of kitten, don't use XML as configuration files - @pascalbrax
|
||||
}
|
||||
@components.ListItem() {
|
||||
Expose the Cluster Manager functionalities as API - @raven2611
|
||||
}
|
||||
@components.ListItem() {
|
||||
CPU architecture awareness for migrations - @raven2611
|
||||
}
|
||||
@components.ListItem() {
|
||||
Inter VM Communications via VXLAN/EVPN - @raven2611
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class={ }>
|
||||
@components.InfoBox("Never Going to Happen", "uired") {
|
||||
@components.List("never") {
|
||||
@components.ListItem() {
|
||||
Kubernetes
|
||||
}
|
||||
@components.ListItem() {
|
||||
Application container management (docker, podman, etc)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Become an OS
|
||||
}
|
||||
@components.ListItem() {
|
||||
Have a paywall
|
||||
}
|
||||
@components.ListItem() {
|
||||
Vendor lock-in
|
||||
}
|
||||
@components.ListItem() {
|
||||
Become a commercial entity (even indirectly)
|
||||
}
|
||||
@components.ListItem() {
|
||||
Anything that does not have an Open Source standard behind it
|
||||
}
|
||||
@components.ListItem() {
|
||||
Directly control a guest Operating System
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
@components.InfoBox("Other things to note", "uipink") {
|
||||
<div class={"flex", "flex-col", "gap-4", "mx-4"}>
|
||||
@components.ContentP() {
|
||||
I recently created a
|
||||
<span>
|
||||
@components.ANewTab("http://redd.it/1bct15z", "post")
|
||||
</span>
|
||||
on reddit announcing that I was building this, and while the majority
|
||||
of responses were supportive, even offering features that may enhance
|
||||
what I originally set out to do, many responded with
|
||||
"Why do we need another one??"
|
||||
}
|
||||
@components.ContentP() {
|
||||
Besides the list above about why this exists, I wanted to clarify
|
||||
a few things those individuals did not seeem to get: This is not
|
||||
a rebuild of Proxmox, Cloudstack, VMWare, Harvester or any of
|
||||
the other "Hyper-converged/Single-solution/turnkey/Operating System"
|
||||
offerings out there. This will not take over your base operating system
|
||||
on your machine, just act as a cluster manager and interface to access
|
||||
the existing libvirtd instances on those machines, nor will it prescribe
|
||||
a set of requirements that make it hard to move your own infrastructure
|
||||
around.
|
||||
}
|
||||
@components.ContentP() {
|
||||
At the heart of this project is that I hate the enshitifiation of
|
||||
Open Source that has been going on, where its just another way to make
|
||||
money and control the eco system. RedHat tried to do it by locking
|
||||
down their source code, Proxmox does it by making sure anything you
|
||||
do on Proxmox is tied to Proxmox (no offense to Proxmox), and even
|
||||
Hashicorp, who I loved so dearly, changed from a pure Open Source
|
||||
licensing model to one that protects the business over the community
|
||||
}
|
||||
@components.ContentP() {
|
||||
I will not let that happen here.
|
||||
}
|
||||
@components.ContentP() {
|
||||
This project will seek to use the Unix philosophy, of building off
|
||||
of existing standards, combining tools, and having one tool do one
|
||||
job well. This does not mean there will be one application for each
|
||||
aspect of the job, but that this application stack will manage Libvirtd
|
||||
well, and have individual and configurable paths to manage each sub-aspect
|
||||
of the libvirt stack. This stack will not create a Ceph cluster for you,
|
||||
it leaves you to do that. It will not even talk to a ceph cluster.
|
||||
It will, however, let you add that cluster via configuration options to
|
||||
define it as a storage pool that libvirt can use.
|
||||
}
|
||||
@components.ContentP() {
|
||||
If you want something that will allow you to use a single interface
|
||||
to create all sub aspects that can be used by libvirt
|
||||
(managing all firewall rules, creating a ceph cluster, etc.),
|
||||
use something like Proxmox which includes that builtin
|
||||
functionality. This isn't the stack for you.
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user