Compare commits
4 Commits
testing
...
78947747be
Author | SHA1 | Date | |
---|---|---|---|
78947747be | |||
645c617956 | |||
dacfc8c6ce | |||
16a0ff0823 |
@ -1,5 +1,5 @@
|
|||||||
# ------------------------------------------------------------------------
|
# ------------------------------------------------------------------------
|
||||||
from mcluseau/golang-builder:1.17.3 as build
|
from mcluseau/golang-builder:1.18.2 as build
|
||||||
|
|
||||||
# ------------------------------------------------------------------------
|
# ------------------------------------------------------------------------
|
||||||
from debian:stretch
|
from debian:stretch
|
||||||
@ -7,7 +7,7 @@ entrypoint ["/bin/dkl-local-server"]
|
|||||||
|
|
||||||
env _uncache 1
|
env _uncache 1
|
||||||
run apt-get update \
|
run apt-get update \
|
||||||
&& apt-get install -y genisoimage gdisk dosfstools util-linux udev \
|
&& apt-get install -y genisoimage gdisk dosfstools util-linux udev binutils systemd \
|
||||||
&& apt-get clean
|
&& apt-get clean
|
||||||
|
|
||||||
run yes |apt-get install -y grub2 grub-pc-bin grub-efi-amd64-bin \
|
run yes |apt-get install -y grub2 grub-pc-bin grub-efi-amd64-bin \
|
||||||
|
@ -6,9 +6,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
"novit.nc/direktil/pkg/localconfig"
|
|
||||||
|
|
||||||
"novit.nc/direktil/local-server/pkg/clustersconfig"
|
"novit.tech/direktil/pkg/localconfig"
|
||||||
|
|
||||||
|
"novit.tech/direktil/local-server/pkg/clustersconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -92,7 +93,8 @@ func main() {
|
|||||||
Initrd: ctx.Group.Initrd,
|
Initrd: ctx.Group.Initrd,
|
||||||
Versions: ctx.Group.Versions,
|
Versions: ctx.Group.Versions,
|
||||||
|
|
||||||
Config: ctx.Config(),
|
BootstrapConfig: ctx.BootstrapConfig(),
|
||||||
|
Config: ctx.Config(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
testDir = "testdata"
|
|
||||||
goldenFile = "config.yaml.golden"
|
|
||||||
outFile = "config.yaml"
|
|
||||||
|
|
||||||
binName = "dkl-dir2config"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Build and run the code with default parameters and testdata
|
|
||||||
*/
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
fmt.Println("Building...")
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
binName += ".exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
build := exec.Command("go", "build", "-o", filepath.Join(testDir, binName))
|
|
||||||
if err := build.Run(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "Cannot build : %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Running Tests...")
|
|
||||||
result := m.Run()
|
|
||||||
|
|
||||||
fmt.Println("Cleaning Up ... ")
|
|
||||||
os.Remove(binName)
|
|
||||||
os.Exit(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRunMain(t *testing.T) {
|
|
||||||
err := os.Chdir(testDir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("RunWithNoArgument", func(t *testing.T) {
|
|
||||||
cmd := exec.Command("./" + binName)
|
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("CompareOutputs", func(t *testing.T) {
|
|
||||||
cmd := exec.Command("./"+binName, "-out", outFile)
|
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := os.ReadFile(outFile)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
expected, err := os.ReadFile(goldenFile)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if ret := bytes.Compare(output, expected); ret != 0 {
|
|
||||||
t.Fatalf("Output (%v) of length %d is different than expected (%v) of length %d", outFile, len(output), goldenFile, len(expected))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"novit.nc/direktil/local-server/pkg/clustersconfig"
|
"novit.tech/direktil/local-server/pkg/clustersconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func clusterFuncs(clusterSpec *clustersconfig.Cluster) map[string]interface{} {
|
func clusterFuncs(clusterSpec *clustersconfig.Cluster) map[string]interface{} {
|
||||||
|
@ -11,20 +11,23 @@ import (
|
|||||||
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"novit.nc/direktil/local-server/pkg/clustersconfig"
|
"novit.tech/direktil/pkg/config"
|
||||||
"novit.nc/direktil/pkg/config"
|
|
||||||
|
"novit.tech/direktil/local-server/pkg/clustersconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
type renderContext struct {
|
type renderContext struct {
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
Annotations map[string]string
|
Annotations map[string]string
|
||||||
|
|
||||||
Host *clustersconfig.Host
|
Host *clustersconfig.Host
|
||||||
Group *clustersconfig.Group
|
Group *clustersconfig.Group
|
||||||
Cluster *clustersconfig.Cluster
|
Cluster *clustersconfig.Cluster
|
||||||
Vars map[string]interface{}
|
Vars map[string]interface{}
|
||||||
ConfigTemplate *clustersconfig.Template
|
|
||||||
StaticPodsTemplate *clustersconfig.Template
|
BootstrapConfigTemplate *clustersconfig.Template
|
||||||
|
ConfigTemplate *clustersconfig.Template
|
||||||
|
StaticPodsTemplate *clustersconfig.Template
|
||||||
|
|
||||||
clusterConfig *clustersconfig.Config
|
clusterConfig *clustersconfig.Config
|
||||||
}
|
}
|
||||||
@ -56,12 +59,14 @@ func newRenderContext(host *clustersconfig.Host, cfg *clustersconfig.Config) (ct
|
|||||||
Labels: mergeLabels(cluster.Labels, group.Labels, host.Labels),
|
Labels: mergeLabels(cluster.Labels, group.Labels, host.Labels),
|
||||||
Annotations: mergeLabels(cluster.Annotations, group.Annotations, host.Annotations),
|
Annotations: mergeLabels(cluster.Annotations, group.Annotations, host.Annotations),
|
||||||
|
|
||||||
Host: host,
|
Host: host,
|
||||||
Group: group,
|
Group: group,
|
||||||
Cluster: cluster,
|
Cluster: cluster,
|
||||||
Vars: vars,
|
Vars: vars,
|
||||||
ConfigTemplate: cfg.ConfigTemplate(group.Config),
|
|
||||||
StaticPodsTemplate: cfg.StaticPodsTemplate(group.StaticPods),
|
BootstrapConfigTemplate: cfg.ConfigTemplate(group.BootstrapConfig),
|
||||||
|
ConfigTemplate: cfg.ConfigTemplate(group.Config),
|
||||||
|
StaticPodsTemplate: cfg.StaticPodsTemplate(group.StaticPods),
|
||||||
|
|
||||||
clusterConfig: cfg,
|
clusterConfig: cfg,
|
||||||
}, nil
|
}, nil
|
||||||
@ -134,11 +139,21 @@ func (ctx *renderContext) Name() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx *renderContext) BootstrapConfig() string {
|
||||||
|
if ctx.BootstrapConfigTemplate == nil {
|
||||||
|
log.Fatalf("no such (bootstrap) config: %q", ctx.Group.BootstrapConfig)
|
||||||
|
}
|
||||||
|
return ctx.renderConfig(ctx.BootstrapConfigTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx *renderContext) Config() string {
|
func (ctx *renderContext) Config() string {
|
||||||
if ctx.ConfigTemplate == nil {
|
if ctx.ConfigTemplate == nil {
|
||||||
log.Fatalf("no such config: %q", ctx.Group.Config)
|
log.Fatalf("no such config: %q", ctx.Group.Config)
|
||||||
}
|
}
|
||||||
|
return ctx.renderConfig(ctx.ConfigTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *renderContext) renderConfig(configTemplate *clustersconfig.Template) string {
|
||||||
ctxName := ctx.Name()
|
ctxName := ctx.Name()
|
||||||
|
|
||||||
ctxMap := ctx.asMap()
|
ctxMap := ctx.asMap()
|
||||||
@ -203,7 +218,7 @@ func (ctx *renderContext) Config() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(make([]byte, 0, 4096))
|
buf := bytes.NewBuffer(make([]byte, 0, 4096))
|
||||||
if err := ctx.ConfigTemplate.Execute(ctxName, "config", buf, ctxMap, extraFuncs); err != nil {
|
if err := configTemplate.Execute(ctxName, "config", buf, ctxMap, extraFuncs); err != nil {
|
||||||
log.Fatalf("failed to render config %q for host %q: %v", ctx.Group.Config, ctx.Host.Name, err)
|
log.Fatalf("failed to render config %q for host %q: %v", ctx.Group.Config, ctx.Host.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
cmd/dkl-dir2config/testdata/cert-requests.yaml
vendored
39
cmd/dkl-dir2config/testdata/cert-requests.yaml
vendored
@ -1,39 +0,0 @@
|
|||||||
- name: etcd-server
|
|
||||||
ca: etcd
|
|
||||||
profile: server
|
|
||||||
per_host: true
|
|
||||||
template: |
|
|
||||||
{"CN":"{{.host.name}}","hosts":["127.0.0.1","{{.host.ip}}"],"key":{"algo":"ecdsa","size":256}}
|
|
||||||
- name: etcd-peer
|
|
||||||
ca: etcd
|
|
||||||
profile: peer
|
|
||||||
per_host: true
|
|
||||||
template: |
|
|
||||||
{"CN":"{{.host.name}}","hosts":["127.0.0.1","{{.host.ip}}"],"key":{"algo":"ecdsa","size":256}}
|
|
||||||
- name: etcd-client
|
|
||||||
ca: etcd
|
|
||||||
profile: client
|
|
||||||
template: |
|
|
||||||
{"CN":"client","hosts":["*"],"key":{"algo":"ecdsa","size":256}}
|
|
||||||
|
|
||||||
- name: apiserver
|
|
||||||
ca: cluster
|
|
||||||
profile: server
|
|
||||||
per_host: true
|
|
||||||
template: |
|
|
||||||
{"CN":"{{.host.name}}","hosts":[
|
|
||||||
"kubernetes", "kubernetes.default", "kubernetes.default.svc.{{.cluster.domain}}","{{.host.name}}",
|
|
||||||
"127.0.0.1","{{.cluster.kubernetes_svc_ip}}","{{.vars.public_vip}}",
|
|
||||||
{{- if .vars.apiserver_vip }}"{{.vars.apiserver_vip}}",{{ end }}
|
|
||||||
"{{.host.ip}}"
|
|
||||||
],"key":{"algo":"ecdsa","size":521}}
|
|
||||||
- name: cluster-client
|
|
||||||
ca: cluster
|
|
||||||
profile: client
|
|
||||||
template: |
|
|
||||||
{"CN":"client","hosts":["*"],"key":{"algo":"ecdsa","size":256}}
|
|
||||||
- name: kubelet-client
|
|
||||||
ca: cluster
|
|
||||||
profile: client
|
|
||||||
template: |
|
|
||||||
{"CN":"kubelet-client","names":[{"O":"system:masters"}],"hosts":["*"],"key":{"algo":"ecdsa","size":256}}
|
|
@ -1 +0,0 @@
|
|||||||
from: v1.19:test
|
|
6187
cmd/dkl-dir2config/testdata/config.yaml
vendored
6187
cmd/dkl-dir2config/testdata/config.yaml
vendored
File diff suppressed because it is too large
Load Diff
6187
cmd/dkl-dir2config/testdata/config.yaml.golden
vendored
6187
cmd/dkl-dir2config/testdata/config.yaml.golden
vendored
File diff suppressed because it is too large
Load Diff
1
cmd/dkl-dir2config/testdata/defaults
vendored
1
cmd/dkl-dir2config/testdata/defaults
vendored
Submodule cmd/dkl-dir2config/testdata/defaults deleted from be8c8592fb
@ -1 +0,0 @@
|
|||||||
from: v1.19:master
|
|
3
cmd/dkl-dir2config/testdata/hosts/test1.yaml
vendored
3
cmd/dkl-dir2config/testdata/hosts/test1.yaml
vendored
@ -1,3 +0,0 @@
|
|||||||
ip: 172.16.0.1
|
|
||||||
cluster: test
|
|
||||||
group: test-master
|
|
3
cmd/dkl-dir2config/testdata/hosts/test2.yaml
vendored
3
cmd/dkl-dir2config/testdata/hosts/test2.yaml
vendored
@ -1,3 +0,0 @@
|
|||||||
ip: 172.16.0.2
|
|
||||||
cluster: test
|
|
||||||
group: test-master
|
|
3
cmd/dkl-dir2config/testdata/hosts/test3.yaml
vendored
3
cmd/dkl-dir2config/testdata/hosts/test3.yaml
vendored
@ -1,3 +0,0 @@
|
|||||||
ip: 172.16.0.3
|
|
||||||
cluster: test
|
|
||||||
group: test-master
|
|
34
cmd/dkl-dir2config/testdata/ssl-config.json
vendored
34
cmd/dkl-dir2config/testdata/ssl-config.json
vendored
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"signing": {
|
|
||||||
"default": {
|
|
||||||
"expiry": "43800h"
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"server": {
|
|
||||||
"expiry": "43800h",
|
|
||||||
"usages": [
|
|
||||||
"signing",
|
|
||||||
"key encipherment",
|
|
||||||
"server auth"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"client": {
|
|
||||||
"expiry": "43800h",
|
|
||||||
"usages": [
|
|
||||||
"signing",
|
|
||||||
"key encipherment",
|
|
||||||
"client auth"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"peer": {
|
|
||||||
"expiry": "43800h",
|
|
||||||
"usages": [
|
|
||||||
"signing",
|
|
||||||
"key encipherment",
|
|
||||||
"server auth",
|
|
||||||
"client auth"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,11 +2,13 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"fmt"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
|
"novit.tech/direktil/local-server/pkg/utf16"
|
||||||
)
|
)
|
||||||
|
|
||||||
func rmTempFile(f *os.File) {
|
func rmTempFile(f *os.File) {
|
||||||
@ -21,7 +23,7 @@ func buildBootTar(out io.Writer, ctx *renderContext) (err error) {
|
|||||||
defer arch.Close()
|
defer arch.Close()
|
||||||
|
|
||||||
archAdd := func(path string, ba []byte) (err error) {
|
archAdd := func(path string, ba []byte) (err error) {
|
||||||
err = arch.WriteHeader(&tar.Header{Name: path, Size: int64(len(ba))})
|
err = arch.WriteHeader(&tar.Header{Name: path, Mode: 0640, Size: int64(len(ba))})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -29,70 +31,95 @@ func buildBootTar(out io.Writer, ctx *renderContext) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// config
|
// kernel
|
||||||
cfgBytes, cfg, err := ctx.Config()
|
kernelPath, err := ctx.distFetch("kernels", ctx.Host.Kernel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
archAdd("config.yaml", cfgBytes)
|
kernelBytes, err := ioutil.ReadFile(kernelPath)
|
||||||
|
if err != nil {
|
||||||
// add "current" elements
|
return
|
||||||
type distCopy struct {
|
|
||||||
Src []string
|
|
||||||
Dst string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// kernel and initrd
|
err = archAdd("current/vmlinuz", kernelBytes)
|
||||||
copies := []distCopy{
|
if err != nil {
|
||||||
{Src: []string{"kernels", ctx.Host.Kernel}, Dst: "current/vmlinuz"},
|
return
|
||||||
{Src: []string{"initrd", ctx.Host.Initrd}, Dst: "current/initrd"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// layers
|
// initrd
|
||||||
for _, layer := range cfg.Layers {
|
initrd := new(bytes.Buffer)
|
||||||
layerVersion := ctx.Host.Versions[layer]
|
err = buildInitrdV2(initrd, ctx)
|
||||||
if layerVersion == "" {
|
if err != nil {
|
||||||
return fmt.Errorf("layer %q not mapped to a version", layer)
|
return
|
||||||
}
|
|
||||||
|
|
||||||
copies = append(copies,
|
|
||||||
distCopy{
|
|
||||||
Src: []string{"layers", layer, layerVersion},
|
|
||||||
Dst: filepath.Join("current", "layers", layer+".fs"),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, copy := range copies {
|
err = archAdd("current/initrd", initrd.Bytes())
|
||||||
outPath, err := ctx.distFetch(copy.Src...)
|
if err != nil {
|
||||||
if err != nil {
|
return
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Open(outPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
stat, err := f.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = arch.WriteHeader(&tar.Header{
|
|
||||||
Name: copy.Dst,
|
|
||||||
Size: stat.Size(),
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = io.Copy(arch, f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildBootEFITar(out io.Writer, ctx *renderContext) (err error) {
|
||||||
|
arch := tar.NewWriter(out)
|
||||||
|
defer arch.Close()
|
||||||
|
|
||||||
|
archAdd := func(path string, ba []byte) (err error) {
|
||||||
|
err = arch.WriteHeader(&tar.Header{Name: path, Mode: 0640, Size: int64(len(ba))})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = arch.Write(ba)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
prefix = "EFI/dkl/"
|
||||||
|
efiPrefix = "\\EFI\\dkl\\"
|
||||||
|
)
|
||||||
|
|
||||||
|
// boot.csv
|
||||||
|
// -> annoyingly it's UTF-16...
|
||||||
|
bootCsvBytes := utf16.FromUTF8([]byte("" +
|
||||||
|
"current_kernel.efi,dkl current,initrd=" + efiPrefix + "current_initrd.img,Direktil current\n" +
|
||||||
|
"previous_kernel.efi,dkl previous,initrd=" + efiPrefix + "previous_initrd.img,Direktil previous\n"))
|
||||||
|
|
||||||
|
err = archAdd(prefix+"BOOT.CSV", []byte(bootCsvBytes))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// kernel
|
||||||
|
kernelPath, err := ctx.distFetch("kernels", ctx.Host.Kernel)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelBytes, err := ioutil.ReadFile(kernelPath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = archAdd(prefix+"current_kernel.efi", kernelBytes)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// initrd
|
||||||
|
initrd := new(bytes.Buffer)
|
||||||
|
err = buildInitrdV2(initrd, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = archAdd(prefix+"current_initrd.img", initrd.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// done
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
140
cmd/dkl-local-server/bootv2.go
Normal file
140
cmd/dkl-local-server/bootv2.go
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"novit.tech/direktil/pkg/cpiocat"
|
||||||
|
)
|
||||||
|
|
||||||
|
func renderBootstrapConfig(w http.ResponseWriter, r *http.Request, ctx *renderContext, asJson bool) (err error) {
|
||||||
|
log.Printf("sending bootstrap config for %q", ctx.Host.Name)
|
||||||
|
|
||||||
|
_, cfg, err := ctx.BootstrapConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if asJson {
|
||||||
|
err = json.NewEncoder(w).Encode(cfg)
|
||||||
|
} else {
|
||||||
|
err = yaml.NewEncoder(w).Encode(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildInitrdV2(out io.Writer, ctx *renderContext) (err error) {
|
||||||
|
_, cfg, err := ctx.Config()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cat := cpiocat.New(out)
|
||||||
|
|
||||||
|
// initrd
|
||||||
|
initrdPath, err := ctx.distFetch("initrd", "2.0.0" /* FIXME */)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cat.AppendArchFile(initrdPath)
|
||||||
|
|
||||||
|
// embedded layers (modules)
|
||||||
|
for _, layer := range cfg.Layers {
|
||||||
|
switch layer {
|
||||||
|
case "modules":
|
||||||
|
|
||||||
|
layerVersion := ctx.Host.Versions[layer]
|
||||||
|
modulesPath, err := ctx.distFetch("layers", layer, layerVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cat.AppendFile(modulesPath, "modules.sqfs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// config
|
||||||
|
cfgBytes, _, err := ctx.BootstrapConfig()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cat.AppendBytes(cfgBytes, "config.yaml", 0600)
|
||||||
|
|
||||||
|
// ssh keys
|
||||||
|
// FIXME we want a bootstrap-stage key instead of the real host key
|
||||||
|
cat.AppendBytes(cfg.FileContent("/etc/ssh/ssh_host_rsa_key"), "id_rsa", 0600)
|
||||||
|
|
||||||
|
return cat.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
|
||||||
|
arch := tar.NewWriter(out)
|
||||||
|
defer arch.Close()
|
||||||
|
|
||||||
|
// config
|
||||||
|
cfgBytes, cfg, err := ctx.Config()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = arch.WriteHeader(&tar.Header{Name: "config.yaml", Size: int64(len(cfgBytes))})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = arch.Write(cfgBytes)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// layers
|
||||||
|
for _, layer := range cfg.Layers {
|
||||||
|
if layer == "modules" {
|
||||||
|
continue // modules are with the kernel in boot v2
|
||||||
|
}
|
||||||
|
|
||||||
|
layerVersion := ctx.Host.Versions[layer]
|
||||||
|
if layerVersion == "" {
|
||||||
|
return fmt.Errorf("layer %q not mapped to a version", layer)
|
||||||
|
}
|
||||||
|
|
||||||
|
outPath, err := ctx.distFetch("layers", layer, layerVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(outPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
stat, err := f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = arch.WriteHeader(&tar.Header{
|
||||||
|
Name: layer + ".fs",
|
||||||
|
Size: stat.Size(),
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(arch, f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -8,7 +8,8 @@ import (
|
|||||||
|
|
||||||
"github.com/cloudflare/cfssl/csr"
|
"github.com/cloudflare/cfssl/csr"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
"novit.nc/direktil/pkg/config"
|
|
||||||
|
"novit.tech/direktil/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var templateFuncs = map[string]interface{}{
|
var templateFuncs = map[string]interface{}{
|
||||||
@ -146,7 +147,7 @@ var templateFuncs = map[string]interface{}{
|
|||||||
|
|
||||||
func getKeyCert(cluster, caName, name, profile, label, reqJson string) (kc *KeyCert, err error) {
|
func getKeyCert(cluster, caName, name, profile, label, reqJson string) (kc *KeyCert, err error) {
|
||||||
certReq := &csr.CertificateRequest{
|
certReq := &csr.CertificateRequest{
|
||||||
KeyRequest: csr.NewBasicKeyRequest(),
|
KeyRequest: csr.NewKeyRequest(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(reqJson), certReq)
|
err = json.Unmarshal([]byte(reqJson), certReq)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"novit.nc/direktil/pkg/localconfig"
|
"novit.tech/direktil/pkg/localconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
cpio "github.com/cavaliercoder/go-cpio"
|
cpio "github.com/cavaliergopher/cpio"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func buildInitrd(out io.Writer, ctx *renderContext) error {
|
|||||||
} {
|
} {
|
||||||
archive.WriteHeader(&cpio.Header{
|
archive.WriteHeader(&cpio.Header{
|
||||||
Name: dir,
|
Name: dir,
|
||||||
Mode: 0600 | cpio.ModeDir,
|
Mode: cpio.FileMode(0600 | os.ModeDir),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,10 @@ import (
|
|||||||
|
|
||||||
restful "github.com/emicklei/go-restful"
|
restful "github.com/emicklei/go-restful"
|
||||||
swaggerui "github.com/mcluseau/go-swagger-ui"
|
swaggerui "github.com/mcluseau/go-swagger-ui"
|
||||||
"novit.nc/direktil/pkg/cas"
|
|
||||||
|
|
||||||
"novit.nc/direktil/local-server/pkg/apiutils"
|
"novit.tech/direktil/pkg/cas"
|
||||||
|
|
||||||
|
"novit.tech/direktil/local-server/pkg/apiutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -15,8 +15,10 @@ import (
|
|||||||
restful "github.com/emicklei/go-restful"
|
restful "github.com/emicklei/go-restful"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"novit.nc/direktil/pkg/config"
|
"novit.tech/direktil/pkg/config"
|
||||||
"novit.nc/direktil/pkg/localconfig"
|
"novit.tech/direktil/pkg/localconfig"
|
||||||
|
|
||||||
|
bsconfig "novit.tech/direktil/pkg/bootstrapconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdlineParam = restful.QueryParameter("cmdline", "Linux kernel cmdline addition")
|
var cmdlineParam = restful.QueryParameter("cmdline", "Linux kernel cmdline addition")
|
||||||
@ -89,9 +91,37 @@ func newRenderContext(host *localconfig.Host, cfg *localconfig.Config) (ctx *ren
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
|
func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
|
||||||
|
ba, err = ctx.render(ctx.Host.Config)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg = &config.Config{}
|
||||||
|
if err = yaml.Unmarshal(ba, cfg); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *renderContext) BootstrapConfig() (ba []byte, cfg *bsconfig.Config, err error) {
|
||||||
|
ba, err = ctx.render(ctx.Host.BootstrapConfig)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg = &bsconfig.Config{}
|
||||||
|
if err = yaml.Unmarshal(ba, cfg); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *renderContext) render(templateText string) (ba []byte, err error) {
|
||||||
tmpl, err := template.New(ctx.Host.Name + "/config").
|
tmpl, err := template.New(ctx.Host.Name + "/config").
|
||||||
Funcs(templateFuncs).
|
Funcs(templateFuncs).
|
||||||
Parse(ctx.Host.Config)
|
Parse(templateText)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -110,13 +140,6 @@ func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ba = buf.Bytes()
|
ba = buf.Bytes()
|
||||||
|
|
||||||
cfg = &config.Config{}
|
|
||||||
|
|
||||||
if err = yaml.Unmarshal(buf.Bytes(), cfg); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ func (sd *SecretData) CA(cluster, name string) (ca *CA, err error) {
|
|||||||
|
|
||||||
req := &csr.CertificateRequest{
|
req := &csr.CertificateRequest{
|
||||||
CN: "Direktil Local Server",
|
CN: "Direktil Local Server",
|
||||||
KeyRequest: &csr.BasicKeyRequest{
|
KeyRequest: &csr.KeyRequest{
|
||||||
A: "ecdsa",
|
A: "ecdsa",
|
||||||
S: 521, // 256, 384, 521
|
S: 521, // 256, 384, 521
|
||||||
},
|
},
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
restful "github.com/emicklei/go-restful"
|
restful "github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"novit.nc/direktil/pkg/localconfig"
|
"novit.tech/direktil/pkg/localconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func wsListClusters(req *restful.Request, resp *restful.Response) {
|
func wsListClusters(req *restful.Request, resp *restful.Response) {
|
||||||
|
@ -8,8 +8,9 @@ import (
|
|||||||
|
|
||||||
restful "github.com/emicklei/go-restful"
|
restful "github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"novit.nc/direktil/local-server/pkg/mime"
|
"novit.tech/direktil/pkg/localconfig"
|
||||||
"novit.nc/direktil/pkg/localconfig"
|
|
||||||
|
"novit.tech/direktil/local-server/pkg/mime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var trustXFF = flag.Bool("trust-xff", true, "Trust the X-Forwarded-For header")
|
var trustXFF = flag.Bool("trust-xff", true, "Trust the X-Forwarded-For header")
|
||||||
@ -55,6 +56,9 @@ func (ws *wsHost) register(rws *restful.WebService, alterRB func(*restful.RouteB
|
|||||||
b("boot.tar").
|
b("boot.tar").
|
||||||
Produces(mime.TAR).
|
Produces(mime.TAR).
|
||||||
Doc("Get the " + ws.hostDoc + "'s /boot archive (ie: for metal upgrades)"),
|
Doc("Get the " + ws.hostDoc + "'s /boot archive (ie: for metal upgrades)"),
|
||||||
|
b("boot-efi.tar").
|
||||||
|
Produces(mime.TAR).
|
||||||
|
Doc("Get the " + ws.hostDoc + "'s /boot archive (ie: for metal upgrades)"),
|
||||||
|
|
||||||
// read-only ISO support
|
// read-only ISO support
|
||||||
b("boot.iso").
|
b("boot.iso").
|
||||||
@ -74,6 +78,22 @@ func (ws *wsHost) register(rws *restful.WebService, alterRB func(*restful.RouteB
|
|||||||
b("initrd").
|
b("initrd").
|
||||||
Produces(mime.OCTET).
|
Produces(mime.OCTET).
|
||||||
Doc("Get the " + ws.hostDoc + "'s initial RAM disk (ie: for netboot)"),
|
Doc("Get the " + ws.hostDoc + "'s initial RAM disk (ie: for netboot)"),
|
||||||
|
|
||||||
|
// boot v2
|
||||||
|
// - bootstrap config
|
||||||
|
b("bootstrap-config").
|
||||||
|
Produces(mime.YAML).
|
||||||
|
Doc("Get the " + ws.hostDoc + "'s bootstrap configuration"),
|
||||||
|
b("bootstrap-config.json").
|
||||||
|
Doc("Get the " + ws.hostDoc + "'s bootstrap configuration (as JSON)"),
|
||||||
|
// - initrd
|
||||||
|
b("initrd-v2").
|
||||||
|
Produces(mime.OCTET).
|
||||||
|
Doc("Get the " + ws.hostDoc + "'s initial RAM disk (v2)"),
|
||||||
|
// - bootstrap
|
||||||
|
b("bootstrap.tar").
|
||||||
|
Produces(mime.TAR).
|
||||||
|
Doc("Get the " + ws.hostDoc + "'s bootstrap seed archive"),
|
||||||
} {
|
} {
|
||||||
alterRB(rb)
|
alterRB(rb)
|
||||||
rws.Route(rb)
|
rws.Route(rb)
|
||||||
@ -151,6 +171,8 @@ func renderHost(w http.ResponseWriter, r *http.Request, what string, host *local
|
|||||||
|
|
||||||
case "boot.tar":
|
case "boot.tar":
|
||||||
err = renderCtx(w, r, ctx, what, buildBootTar)
|
err = renderCtx(w, r, ctx, what, buildBootTar)
|
||||||
|
case "boot-efi.tar":
|
||||||
|
err = renderCtx(w, r, ctx, what, buildBootEFITar)
|
||||||
|
|
||||||
case "boot.img":
|
case "boot.img":
|
||||||
err = renderCtx(w, r, ctx, what, buildBootImg)
|
err = renderCtx(w, r, ctx, what, buildBootImg)
|
||||||
@ -161,6 +183,16 @@ func renderHost(w http.ResponseWriter, r *http.Request, what string, host *local
|
|||||||
case "boot.img.lz4":
|
case "boot.img.lz4":
|
||||||
err = renderCtx(w, r, ctx, what, buildBootImgLZ4)
|
err = renderCtx(w, r, ctx, what, buildBootImgLZ4)
|
||||||
|
|
||||||
|
// boot v2
|
||||||
|
case "bootstrap-config":
|
||||||
|
err = renderBootstrapConfig(w, r, ctx, false)
|
||||||
|
case "bootstrap-config.json":
|
||||||
|
err = renderBootstrapConfig(w, r, ctx, true)
|
||||||
|
case "initrd-v2":
|
||||||
|
err = renderCtx(w, r, ctx, what, buildInitrdV2)
|
||||||
|
case "bootstrap.tar":
|
||||||
|
err = renderCtx(w, r, ctx, what, buildBootstrap)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,9 @@ import (
|
|||||||
|
|
||||||
"github.com/emicklei/go-restful"
|
"github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"novit.nc/direktil/local-server/pkg/mime"
|
"novit.tech/direktil/pkg/localconfig"
|
||||||
"novit.nc/direktil/pkg/localconfig"
|
|
||||||
|
"novit.tech/direktil/local-server/pkg/mime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func registerWS(rest *restful.Container) {
|
func registerWS(rest *restful.Container) {
|
||||||
|
155
go.mod
155
go.mod
@ -1,55 +1,146 @@
|
|||||||
module novit.nc/direktil/local-server
|
module novit.tech/direktil/local-server
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e
|
github.com/cavaliergopher/cpio v1.0.1
|
||||||
github.com/cespare/xxhash v1.1.0
|
github.com/cespare/xxhash v1.1.0
|
||||||
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e
|
github.com/cloudflare/cfssl v1.6.1
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/emicklei/go-restful v2.10.0+incompatible
|
github.com/emicklei/go-restful v2.15.0+incompatible
|
||||||
github.com/emicklei/go-restful-openapi v1.2.0
|
github.com/emicklei/go-restful-openapi v1.4.1
|
||||||
github.com/mcluseau/go-swagger-ui v0.0.0-20191019002626-fd9128c24a34
|
github.com/mcluseau/go-swagger-ui v0.0.0-20191019002626-fd9128c24a34
|
||||||
github.com/miolini/datacounter v1.0.1
|
github.com/miolini/datacounter v1.0.3
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
github.com/pierrec/lz4 v2.3.0+incompatible
|
github.com/pierrec/lz4 v2.6.1+incompatible
|
||||||
gopkg.in/src-d/go-billy.v4 v4.3.2
|
gopkg.in/src-d/go-billy.v4 v4.3.2
|
||||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||||
gopkg.in/yaml.v2 v2.2.4
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
k8s.io/apimachinery v0.0.0-20191203211716-adc6f4cd9e7d
|
k8s.io/apimachinery v0.23.5
|
||||||
novit.nc/direktil/pkg v0.0.0-20191211161950-96b0448b84c2
|
novit.tech/direktil/pkg v0.0.0-20220331140020-b11c53b36ae8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/zmap/zlint/v3 => github.com/zmap/zlint/v3 v3.3.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
bitbucket.org/creachadair/shell v0.0.7 // indirect
|
||||||
|
cloud.google.com/go/compute v1.5.0 // indirect
|
||||||
|
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
|
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
|
||||||
|
github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc // indirect
|
||||||
|
github.com/coreos/go-semver v0.3.0 // indirect
|
||||||
|
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||||
github.com/emirpasic/gods v1.12.0 // indirect
|
github.com/emirpasic/gods v1.12.0 // indirect
|
||||||
|
github.com/envoyproxy/go-control-plane v0.10.1 // indirect
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.6.7 // indirect
|
||||||
|
github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect
|
||||||
github.com/frankban/quicktest v1.5.0 // indirect
|
github.com/frankban/quicktest v1.5.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.3 // indirect
|
github.com/fullstorydev/grpcurl v1.8.6 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
github.com/go-openapi/spec v0.19.3 // indirect
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
github.com/go-openapi/swag v0.19.5 // indirect
|
github.com/go-openapi/spec v0.20.4 // indirect
|
||||||
github.com/gobuffalo/envy v1.7.1 // indirect
|
github.com/go-openapi/swag v0.21.1 // indirect
|
||||||
github.com/gobuffalo/packd v0.3.0 // indirect
|
github.com/gobuffalo/envy v1.10.1 // indirect
|
||||||
|
github.com/gobuffalo/packd v1.0.1 // indirect
|
||||||
github.com/gobuffalo/packr v1.30.1 // indirect
|
github.com/gobuffalo/packr v1.30.1 // indirect
|
||||||
github.com/golang/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/google/certificate-transparency-go v1.0.21 // indirect
|
github.com/golang/glog v1.0.0 // indirect
|
||||||
github.com/google/go-cmp v0.3.1 // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/google/btree v1.0.1 // indirect
|
||||||
|
github.com/google/certificate-transparency-go v1.1.2 // indirect
|
||||||
|
github.com/google/trillian v1.4.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||||
github.com/joho/godotenv v1.3.0 // indirect
|
github.com/jhump/protoreflect v1.12.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.8 // indirect
|
github.com/jmoiron/sqlx v1.3.4 // indirect
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect
|
github.com/joho/godotenv v1.4.0 // indirect
|
||||||
github.com/mailru/easyjson v0.7.0 // indirect
|
github.com/jonboulle/clockwork v0.2.3 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/kevinburke/ssh_config v1.1.0 // indirect
|
||||||
|
github.com/kisielk/sqlstruct v0.0.0-20210630145711-dae28ed37023 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.5.0 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
github.com/sergi/go-diff v1.0.0 // indirect
|
github.com/prometheus/client_golang v1.12.1 // indirect
|
||||||
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
|
github.com/prometheus/common v0.33.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
github.com/sergi/go-diff v1.2.0 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
|
github.com/soheilhy/cmux v0.1.5 // indirect
|
||||||
|
github.com/spf13/cobra v1.4.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/src-d/gcfg v1.4.0 // indirect
|
github.com/src-d/gcfg v1.4.0 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
|
github.com/urfave/cli v1.22.5 // indirect
|
||||||
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 // indirect
|
github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236 // indirect
|
||||||
golang.org/x/sys v0.0.0-20191018095205-727590c5006e // indirect
|
github.com/xanzy/ssh-agent v0.3.1 // indirect
|
||||||
golang.org/x/text v0.3.2 // indirect
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||||
|
github.com/zmap/zcrypto v0.0.0-20220402174210-599ec18ecbac // indirect
|
||||||
|
github.com/zmap/zlint/v3 v3.1.0 // indirect
|
||||||
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
|
go.etcd.io/etcd/api/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/client/v2 v2.305.2 // indirect
|
||||||
|
go.etcd.io/etcd/client/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/etcdctl/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/etcdutl/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/pkg/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/raft/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/server/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/tests/v3 v3.5.2 // indirect
|
||||||
|
go.etcd.io/etcd/v3 v3.5.2 // indirect
|
||||||
|
go.opentelemetry.io/contrib v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/proto/otlp v0.7.0 // indirect
|
||||||
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
|
go.uber.org/zap v1.21.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||||
|
golang.org/x/tools v0.1.10 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7 // indirect
|
||||||
|
google.golang.org/grpc v1.45.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.28.0 // indirect
|
||||||
|
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
|
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
@ -231,14 +231,15 @@ type Group struct {
|
|||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
Annotations map[string]string
|
Annotations map[string]string
|
||||||
|
|
||||||
Master bool
|
Master bool
|
||||||
IPXE string
|
IPXE string
|
||||||
Kernel string
|
Kernel string
|
||||||
Initrd string
|
Initrd string
|
||||||
Config string
|
BootstrapConfig string `yaml:"bootstrap_config"`
|
||||||
StaticPods string `yaml:"static_pods"`
|
Config string
|
||||||
Versions map[string]string
|
StaticPods string `yaml:"static_pods"`
|
||||||
Vars Vars
|
Versions map[string]string
|
||||||
|
Vars Vars
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vars store user-defined key-values
|
// Vars store user-defined key-values
|
||||||
|
@ -124,6 +124,11 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group.BootstrapConfig, err = template(group.Rev(), "configs", group.BootstrapConfig, &config.Configs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to load config for group %q: %v", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
group.Config, err = template(group.Rev(), "configs", group.Config, &config.Configs)
|
group.Config, err = template(group.Rev(), "configs", group.Config, &config.Configs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load config for group %q: %v", name, err)
|
return nil, fmt.Errorf("failed to load config for group %q: %v", name, err)
|
||||||
|
61
pkg/initrdconfig/config.go
Normal file
61
pkg/initrdconfig/config.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
AntiPhishingCode string `json:"anti_phishing_code"`
|
||||||
|
|
||||||
|
Keymap string
|
||||||
|
Modules string
|
||||||
|
|
||||||
|
Auths []Auth
|
||||||
|
|
||||||
|
Networks []struct {
|
||||||
|
Name string
|
||||||
|
Interfaces []struct {
|
||||||
|
Var string
|
||||||
|
N int
|
||||||
|
Regexps []string
|
||||||
|
}
|
||||||
|
Script string
|
||||||
|
}
|
||||||
|
|
||||||
|
LVM []LvmVG
|
||||||
|
Bootstrap Bootstrap
|
||||||
|
}
|
||||||
|
|
||||||
|
type Auth struct {
|
||||||
|
Name string
|
||||||
|
SSHKey string `yaml:"sshKey"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LvmVG struct {
|
||||||
|
VG string
|
||||||
|
PVs struct {
|
||||||
|
N int
|
||||||
|
Regexps []string
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults struct {
|
||||||
|
FS string
|
||||||
|
Raid *RaidConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
LVs []struct {
|
||||||
|
Name string
|
||||||
|
Crypt string
|
||||||
|
FS string
|
||||||
|
Raid *RaidConfig
|
||||||
|
Size string
|
||||||
|
Extents string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type RaidConfig struct {
|
||||||
|
Mirrors int
|
||||||
|
Stripes int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Bootstrap struct {
|
||||||
|
Dev string
|
||||||
|
Seed string
|
||||||
|
}
|
29
pkg/utf16/utf16.go
Normal file
29
pkg/utf16/utf16.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package utf16
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FromUTF8(data []byte) (res []byte) {
|
||||||
|
endian := binary.LittleEndian
|
||||||
|
|
||||||
|
res = make([]byte, (len(data)+1)*2)
|
||||||
|
|
||||||
|
res = res[0:2]
|
||||||
|
endian.PutUint16(res, 0xfeff)
|
||||||
|
|
||||||
|
for len(data) > 0 {
|
||||||
|
r, size := utf8.DecodeRune(data)
|
||||||
|
if r > 65535 {
|
||||||
|
panic(fmt.Errorf("r=0x%x > 0xffff", r))
|
||||||
|
}
|
||||||
|
|
||||||
|
slen := len(res)
|
||||||
|
res = res[0 : slen+2]
|
||||||
|
endian.PutUint16(res[slen:], uint16(r))
|
||||||
|
data = data[size:]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Reference in New Issue
Block a user