diff --git a/.circleci/config.yml b/.circleci/config.yml index 371c1b5e..4e83549b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,9 +7,6 @@ workflows: - test: requires: - clean-code - - race: - requires: - - clean-code - compile: requires: - clean-code @@ -27,6 +24,7 @@ workflows: jobs: - compile - image + #TODO: Utilize CircleCI caching for at least the kernel tarball jobs: clean-code: @@ -38,16 +36,6 @@ jobs: - run: name: Install ineffassign command: go get github.com/gordonklaus/ineffassign - - run: - name: Install Task - command: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin - - run: - name: Create test key - command: | - ssh-keygen -t rsa -b 4096 -C "testkey" -N "testpass" -f config/ssh_keys - touch i_agree_to_the_acme_terms - echo qemu-virt-a72 > TARGET - task config:generate - run: name: vet command: go vet $(go list ./...) @@ -67,10 +55,8 @@ jobs: name: Install Task command: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin - run: - name: Create test key + name: Generate config command: | - ssh-keygen -t rsa -b 4096 -C "testkey" -N "testpass" -f config/ssh_keys - touch i_agree_to_the_acme_terms echo qemu-virt-a72 > TARGET task config:generate - run: @@ -79,24 +65,8 @@ jobs: - run: name: Test coverage command: task coverage - race: - docker: - - image: cimg/go:1.17.1 - working_directory: ~/go/src/github.com/u-root/u-bmc - steps: - - checkout - run: - name: Install Task - command: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin - - run: - name: Create test key - command: | - ssh-keygen -t rsa -b 4096 -C "testkey" -N "testpass" -f config/ssh_keys - touch i_agree_to_the_acme_terms - echo qemu-virt-a72 > TARGET - task config:generate - - run: - name: Race detector + name: Test race conditions command: task race compile: docker: @@ -108,11 +78,9 @@ jobs: name: Install Task command: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin - run: - name: Create test key + name: Generate config command: | - ssh-keygen -t rsa -b 4096 -C "testkey" -N "testpass" -f config/ssh_keys - touch i_agree_to_the_acme_terms - echo qemu-virt-a72 > TARGET + echo qemu-virt-a7 > TARGET task config:generate - run: name: build all commands @@ -149,11 +117,10 @@ jobs: sudo make install sudo ln -sf /usr/local/bin/mkfs.erofs /usr/bin/mkfs.erofs - run: - name: Create test key + name: Generate config command: | - ssh-keygen -t rsa -b 4096 -C "testkey" -N "testpass" -f config/ssh_keys - touch i_agree_to_the_acme_terms echo qemu-virt-a72 > TARGET + task config:generate - run: name: Build image command: task build @@ -163,16 +130,17 @@ jobs: - store_artifacts: path: build/linux/zImage.boot destination: zImage.boot - - run: - name: Run integration tests - command: task integration - - store_artifacts: - path: integration/serial - - run: - name: Copy failed integration tests - command: | - mkdir /tmp/integration-data/ - tar -cvf /tmp/integration-data/integration.tar /tmp/ubmc-integration*/ - when: on_fail - - store_artifacts: - path: /tmp/integration-data/ + #TODO(MDr164): Fix integration tests uinit + # - run: + # name: Run integration tests + # command: task integration + # - store_artifacts: + # path: integration/serial + # - run: + # name: Copy failed integration tests + # command: | + # mkdir /tmp/integration-data/ + # tar -cvf /tmp/integration-data/integration.tar /tmp/ubmc-integration*/ + # when: on_fail + # - store_artifacts: + # path: /tmp/integration-data/ diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 783c1ef9..b4fc2a54 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,21 +1,9 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# name: "CodeQL" on: push: branches: [ master ] pull_request: - # The branches below must be a subset of the branches above branches: [ master ] schedule: - cron: '43 8 * * 0' @@ -33,39 +21,18 @@ jobs: fail-fast: false matrix: language: [ 'go' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - name: Checkout repository uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v1 - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000..a9553383 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,34 @@ +name: golangci-lint + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + strategy: + matrix: + go-version: [ '1.17.x' ] + steps: + - uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - uses: actions/checkout@v2 + - name: Install TASK + run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin + - name: Generate config + run: | + echo qemu-virt-a72 > TARGET + task config:generate + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: v1.42.1 + skip-go-installation: true diff --git a/.gitignore b/.gitignore index 85302e8a..84e3c4e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,9 @@ build/* .task/* -i_agree_to_the_acme_terms TARGET -config/ssh_keys.pub -config/ssh_keys.go -config/version.go -config/acme.go -config/sim_pebble.go +config/generate/ssh-pubkeys +config/generate/sim-pebble.crt +config/generate/sim-pebble.key config/sim-pebble.crt config/sim-pebble.key -**/.bb +config/generated.go diff --git a/README.md b/README.md index 84839800..ec1f604e 100644 --- a/README.md +++ b/README.md @@ -107,17 +107,16 @@ git clone https://github.com/u-root/u-bmc Setup configuration: ``` -# SSH ECDSA public keys does not work for now +# RSA keys will be considered legacy and support will be added again later -cp ~/.ssh/*.pub config/ssh_keys.pub +cp ~/.ssh/*.pub config/generate/ssh-pubkeys # Agree to the terms of the configured ACME server # By default it's just a toy ACME server so this is fine, but if you're # using another ACME server like Let's Encrypt (LE) ensure you agree to their terms. # For LE, you can find them at https://letsencrypt.org/repository/. -touch i_agree_to_the_acme_terms -task config:generate +task config:generate -- acme ``` Build image: @@ -176,7 +175,7 @@ go install github.com/u-root/u-bmc/cmd/ubmcctl # The root CA is regenerated every time pebble is started to prevent # testing to accidentally become production -curl https://localhost:14000/root --cacert config/sim-pebble.crt > root.crt +curl https://localhost:14000/root --cacert config/generate/sim-pebble.crt > root.crt echo '127.0.1.2 ubmc.example.com' | sudo tee -a /etc/hosts SSL_CERT_FILE=root.crt ubmcctl -host ubmc.example.com:6443 ``` diff --git a/Taskfile.yml b/Taskfile.yml index 0e8bedfb..c9911f02 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -69,14 +69,12 @@ tasks: cmds: - echo "Wiping the whole build directory and config files!" - rm -rf build/ - - rm -f config/acme.go - - rm -f config/version.go - - rm -f config/sim_pebble.go + - rm -f config/generated.go - rm -f config/sim-pebble.crt - rm -f config/sim-pebble.key - - rm -f config/ssh_keys.go - - rm -f config/ssh_keys.pub - - rm -f i_agree_to_the_acme_terms + - rm -f config/generate/sim-pebble.crt + - rm -f config/generate/sim-pebble.key + - rm -f config/generate/ssh-pubkeys - rm -f TARGET - echo "Done!" diff --git a/config/acme.go.tmpl b/config/acme.go.tmpl deleted file mode 100644 index 88181209..00000000 --- a/config/acme.go.tmpl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2019 the u-root Authors. All rights reserved -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package config - -var ( - // This is copied in if the file 'i_agree_to_the_acme_terms' is present. - // This assumes that the builder has agreed to the ACME server's terms. - termsAgreed = true -) diff --git a/config/config.go b/config/config.go index eb076649..f53f92b0 100644 --- a/config/config.go +++ b/config/config.go @@ -50,12 +50,12 @@ var DefaultConfig = &Config{ {Protocol: "udp", Address: "roughtime.int80h.com:2002", PublicKeyType: ttime.KEY_TYPE_ED25519, PublicKey: "AW5uAoTSTDfG5NfY1bTh08GUnOqlRb+HVhbJ3ODJvsE="}, }, - // Enable this to have the SSH server start on bootup. // This is useful if you're debugging startup problems in u-bmc. // NOTE: The SSH server starts before trusted time has been acquired, // do not use in production environments. - StartDebugSshServer: true, - // authorizedKeys is generated by the Makefile + StartDebugSshServer: debugSSH, + + // authorizedKeys is being read by the compiler using go embed DebugSshServerKeys: authorizedKeys, Version: Version{ @@ -73,9 +73,8 @@ var DefaultConfig = &Config{ }, } -const ( - // Source: https://letsencrypt.org/certs/letsencryptauthorityx3.pem.txt - letsEncryptAPICA = ` +// Source: https://letsencrypt.org/certs/letsencryptauthorityx3.pem.txt +const letsEncryptAPICA = ` -----BEGIN CERTIFICATE----- MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh @@ -109,4 +108,3 @@ PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt -----END CERTIFICATE----- ` -) diff --git a/config/generate/debug_ssh.go b/config/generate/debug_ssh.go new file mode 100644 index 00000000..b55e7b3c --- /dev/null +++ b/config/generate/debug_ssh.go @@ -0,0 +1,6 @@ +//go:build debugssh +// +build debugssh + +package main + +var debugSSH = true diff --git a/config/generate/generate.go b/config/generate/generate.go new file mode 100644 index 00000000..b114368c --- /dev/null +++ b/config/generate/generate.go @@ -0,0 +1,69 @@ +// Copyright 2021 the u-root Authors. All rights reserved +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + _ "embed" + "log" + "os" + "strings" + "text/template" +) + +var ( + gitVersion = `"0"` + gitHash = `"none"` + + //go:embed sim-pebble.crt + simPebbleAPICA string + + //go:embed ssh-pubkeys + keyFile string + + genTemplate = template.Must(template.New("").Parse(`// Code generated via go generate; DO NOT EDIT. +// This file was generated by generate.go + +package config + +var ( + termsAgreed = {{.Terms}} + debugSSH = {{.DebugSSH}} + gitVersion = {{.Version}} + gitHash = {{.Hash}} + simPebbleAPICA = {{.APICA}} + authorizedKeys = []string{ + {{- range .Keys}} + {{printf "%q" .}}, + {{- end}} + } +) +`)) +) + +func main() { + authorizedKeys := strings.Split(keyFile, "\n") + + f, err := os.Create("../generated.go") + if err != nil { + log.Fatal(err) + } + defer f.Close() + + genTemplate.Execute(f, struct { + Version string + Hash string + Terms bool + DebugSSH bool + APICA string + Keys []string + }{ + Version: "`" + gitVersion + "`", + Hash: "`" + gitHash + "`", + Terms: termsAgreed, + DebugSSH: debugSSH, + APICA: "`" + simPebbleAPICA + "`", + Keys: authorizedKeys, + }) +} diff --git a/config/generate/no_debug_ssh.go b/config/generate/no_debug_ssh.go new file mode 100644 index 00000000..bdfb9cb8 --- /dev/null +++ b/config/generate/no_debug_ssh.go @@ -0,0 +1,6 @@ +//go:build !debugssh +// +build !debugssh + +package main + +var debugSSH = false diff --git a/config/generate/no_terms_agreed.go b/config/generate/no_terms_agreed.go new file mode 100644 index 00000000..23da8d3b --- /dev/null +++ b/config/generate/no_terms_agreed.go @@ -0,0 +1,6 @@ +//go:build !acme +// +build !acme + +package main + +var termsAgreed = false diff --git a/config/generate/terms_agreed.go b/config/generate/terms_agreed.go new file mode 100644 index 00000000..2adfecd2 --- /dev/null +++ b/config/generate/terms_agreed.go @@ -0,0 +1,6 @@ +//go:build acme +// +build acme + +package main + +var termsAgreed = true diff --git a/config/sim_pebble.sh b/config/sim_pebble.sh deleted file mode 100755 index 2a70da01..00000000 --- a/config/sim_pebble.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# Copyright 2019 the u-root Authors. All rights reserved -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -cat << _EOF_ -// AUTOGENERATED BY sim_pebble.sh -package config - -var ( - simPebbleAPICA = \` -$( 3000 { - return fmt.Errorf("Expected temperature to be %v +/- 3 C, was %v", celcius, millitemp) + return fmt.Errorf("expected temperature to be %v +/- 3 C, was %v", celcius, millitemp) } return nil } @@ -65,8 +65,8 @@ func uinit() error { func main() { if err := uinit(); err != nil { - utils.FailTest(err) + util.FailTest(err) } else { - utils.PassTest() + util.PassTest() } } diff --git a/integration/utils/acme.go b/integration/util/acme.go similarity index 99% rename from integration/utils/acme.go rename to integration/util/acme.go index 5cf526c2..85e8a732 100644 --- a/integration/utils/acme.go +++ b/integration/util/acme.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package utils +package util import ( "context" diff --git a/integration/utils/network.go b/integration/util/network.go similarity index 88% rename from integration/utils/network.go rename to integration/util/network.go index f33bd43b..a6b60e6c 100644 --- a/integration/utils/network.go +++ b/integration/util/network.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package utils +package util import ( "fmt" @@ -14,7 +14,7 @@ import ( func AddIP(cidr string, iface string) error { l, err := netlink.LinkByName(iface) if err != nil { - return fmt.Errorf("Unable to get interface %s: %v", iface, err) + return fmt.Errorf("unable to get interface %s: %v", iface, err) } addr, err := netlink.ParseAddr(cidr) if err != nil { @@ -34,7 +34,7 @@ func AddIP(cidr string, iface string) error { func SetLinkUp(iface string) error { l, err := netlink.LinkByName(iface) if err != nil { - return fmt.Errorf("Unable to get interface %s: %v", iface, err) + return fmt.Errorf("unable to get interface %s: %v", iface, err) } h, err := netlink.NewHandle(unix.NETLINK_ROUTE) if err != nil { diff --git a/integration/utils/roughtime.go b/integration/util/roughtime.go similarity index 99% rename from integration/utils/roughtime.go rename to integration/util/roughtime.go index 52ec968b..8c247193 100644 --- a/integration/utils/roughtime.go +++ b/integration/util/roughtime.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package utils +package util import ( "crypto/rand" diff --git a/integration/utils/test.go b/integration/util/test.go similarity index 97% rename from integration/utils/test.go rename to integration/util/test.go index 20ed38c9..7760f5d4 100644 --- a/integration/utils/test.go +++ b/integration/util/test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package utils +package util import ( "fmt" diff --git a/integration/vm_test.go b/integration/vm_test.go index 68717448..921c0152 100644 --- a/integration/vm_test.go +++ b/integration/vm_test.go @@ -5,72 +5,21 @@ package integration import ( - "encoding/json" - "fmt" + "testing" "time" - "github.com/digitalocean/go-qemu/qmp" - "github.com/u-root/u-root/pkg/qemu" + "github.com/anatol/vmtest" ) -type FlashDevice struct { - Image string -} - -func (d FlashDevice) Cmdline() []string { - return []string{"-drive", "file=" + d.Image + ",format=raw,if=mtd"} -} - -func (d FlashDevice) KArgs() []string { - return nil -} - -type MemoryDevice struct { - MB int -} - -func (d MemoryDevice) Cmdline() []string { - return []string{"-m", fmt.Sprintf("%d", d.MB)} -} - -func (d MemoryDevice) KArgs() []string { - return nil -} - -type MachineDevice struct { - Board string -} - -func (d MachineDevice) Cmdline() []string { - return []string{"-M", d.Board} -} - -func (d MachineDevice) KArgs() []string { - return nil -} - -type QemuMonitorDevice struct { - Socket string -} - -func (d QemuMonitorDevice) Cmdline() []string { - return []string{"-qmp", "unix:" + d.Socket + ",server,nowait"} -} - -func (d QemuMonitorDevice) KArgs() []string { - return nil -} - -type VirtioRngDevice struct { -} - -func (d VirtioRngDevice) Cmdline() []string { - return []string{"-device", "virtio-rng-pci"} -} - -func (d VirtioRngDevice) KArgs() []string { - return nil -} +var ( + machine = []string{"-machine", "virt"} + cpu32 = []string{"-cpu", "cortex-a15"} + cpu64 = []string{"-cpu", "cortex-a72"} + mem = []string{"-m", "512"} + blkdev = []string{"-drive", "file=../build/img/rootfs.img,format=raw,if=virtio"} + nic = []string{"-nic", "user,hostfwd=udp::6053-:53,hostfwd=tcp::6443-:443,hostfwd=tcp::9370-:9370,model=virtio"} + rng = []string{"-device", "virtio-rng"} +) type QOMInteger struct { Path string `json:"path"` @@ -80,41 +29,53 @@ type QOMInteger struct { type TestVM struct { cleanup func() - m qmp.Monitor - qemu.VM + *vmtest.Qemu } -func NewTestVM(vm *qemu.VM, monsock string, cleanup func()) (*TestVM, error) { - mon, err := qmp.NewSocketMonitor("unix", monsock, 2*time.Second) - if err != nil { - return nil, fmt.Errorf("Failed to attach to QMP monitor: %v", err) +func cmdline(args ...[]string) (cmdline []string) { + for _, arg := range args { + cmdline = append(cmdline, arg...) } - - if err := mon.Connect(); err != nil { + return +} + +func NewTestVM(t *testing.T, bit int, timeout time.Duration, cleanup func()) (*TestVM, error) { + var cpu []string + var arch string + switch bit { + case 32: + cpu = cpu32 + arch = "arm" + case 64: + cpu = cpu64 + arch = "aarch64" + default: + t.Fatalf("invalid arch: %dbit", bit) + } + opts := vmtest.QemuOptions{ + OperatingSystem: vmtest.OS_OTHER, + Architecture: vmtest.QemuArchitecture(arch), + Kernel: "../build/linux/zImage.boot", + Params: cmdline( + machine, + cpu, + mem, + blkdev, + nic, + rng, + ), + Verbose: testing.Verbose(), + Timeout: timeout, + } + vm, err := vmtest.NewQemu(&opts) + if err != nil { return nil, err } - return &TestVM{cleanup, mon, *vm}, nil + return &TestVM{cleanup, vm}, nil } -func (v TestVM) Close() { - v.m.Disconnect() +func (v *TestVM) Close() { + v.Qemu.Kill() v.cleanup() } - -func (v TestVM) SetQOMInteger(path, property string, value int) error { - cmd := qmp.Command{ - Execute: "qom-set", - Args: QOMInteger{ - Path: path, - Property: property, - Value: value, - }, - } - d, err := json.Marshal(cmd) - if err != nil { - return err - } - _, err = v.m.Run(d) - return err -} diff --git a/pkg/bmc/grpc.go b/pkg/bmc/grpc.go index af128397..7c85fbf2 100644 --- a/pkg/bmc/grpc.go +++ b/pkg/bmc/grpc.go @@ -12,7 +12,7 @@ import ( "io" "net" - "github.com/grpc-ecosystem/go-grpc-prometheus" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/prometheus/client_golang/prometheus" "github.com/u-root/u-bmc/config" pb "github.com/u-root/u-bmc/proto" @@ -92,6 +92,9 @@ func (m *mgmtServer) GetFans(ctx context.Context, _ *pb.GetFansRequest) (*pb.Get } func (m *mgmtServer) streamIn(stream pb.ManagementService_StreamConsoleServer, done <-chan struct{}) error { + if m.uart == nil { + return nil + } r := m.uart.NewReader(done) for d := range r { err := stream.Send(&pb.ConsoleData{Data: d}) @@ -103,6 +106,9 @@ func (m *mgmtServer) streamIn(stream pb.ManagementService_StreamConsoleServer, d } func (m *mgmtServer) StreamConsole(stream pb.ManagementService_StreamConsoleServer) error { + if m.uart == nil { + return nil + } done := make(chan struct{}) go func() { err := m.streamIn(stream, done) diff --git a/pkg/bmc/uart.go b/pkg/bmc/uart.go index 76f5988b..934cbc61 100644 --- a/pkg/bmc/uart.go +++ b/pkg/bmc/uart.go @@ -141,6 +141,9 @@ func (u *uartSystem) uartReceiver() { } func startUart(f string, baud int) (*uartSystem, error) { + if f == "" { + return nil, nil + } c := &serial.Config{Name: f, Baud: baud} s, err := serial.OpenPort(c) if err != nil { diff --git a/platform/qemu-virt-a72/pkg/platform/platform.go b/platform/qemu-virt-a72/pkg/platform/platform.go index df30689c..a8a16dae 100644 --- a/platform/qemu-virt-a72/pkg/platform/platform.go +++ b/platform/qemu-virt-a72/pkg/platform/platform.go @@ -35,7 +35,7 @@ func (p *platform) ThermometerMap() map[int]string { } func (p *platform) HostUart() (string, int) { - return "/dev/ttyAMA0", 115200 + return "", 115200 } func (p *platform) Close() { diff --git a/taskfiles/Config.yml b/taskfiles/Config.yml index dac1fab1..6c29b094 100644 --- a/taskfiles/Config.yml +++ b/taskfiles/Config.yml @@ -1,51 +1,35 @@ version: '3' tasks: - # Meta task to generate go files containing configuration values + # Meta task to generate files containing configuration values generate: deps: - ssh-keys - - version - - acme - - sim-pebble + - sim-crt + dir: config/generate cmds: + - echo "Generating config..." + - | + go run \ + -ldflags "\ + -X main.gitVersion={{.GIT_VERSION}} \ + -X main.gitHash={{.GIT_HASH}}" \ + -tags "config {{.CLI_ARGS}}" \ + . - echo "Config generated successfully!" + vars: + GIT_VERSION: + sh: git describe --tags --long --always + GIT_HASH: + sh: git rev-parse HEAD - # Generate list of allowed ssh public keys + # Make sure list of allowed ssh public keys exists ssh-keys: - dir: config - cmds: - - touch ssh_keys.pub - - cat ssh_keys.pub | ./ssh_keys.sh > ssh_keys.go - sources: - - ssh_keys.sh - generates: - - ssh_keys.go - - # Generate version file - version: - dir: config - cmds: - - ./version.sh > version.go - sources: - - version.sh - generates: - - version.go - - # Generate acme file - acme: - dir: config + dir: config/generate cmds: - - cp ./acme.go.tmpl acme.go - sources: - - acme.go.tmpl - generates: - - acme.go + - touch ssh-pubkeys status: - - test ! -f ../i_agree_to_the_acme_terms # Make non-blocking using 'status' #TODO use precondition and split up - #preconditions: - # - sh: test -f ../i_agree_to_the_acme_terms - # msg: You need to agree to the ACME terms to use the simulator + - ssh-pubkeys # Create pebble key sim-key: @@ -53,12 +37,14 @@ tasks: cmds: - | openssl ecparam \ - -name secp256r1 \ + -name prime256v1 \ -genkey \ -noout \ -out sim-pebble.key + - cp sim-pebble.key generate/sim-pebble.key status: - test -f sim-pebble.key + - test -f generate/sim-pebble.key # Create pebble certificate sim-crt: @@ -75,22 +61,12 @@ tasks: -subj /CN=sim-pebble \ -reqexts SAN \ -extensions SAN \ - -config ./sim-pebble.cnf \ + -config sim-pebble.cnf \ -sha256 \ -days 36500 + - cp sim-pebble.crt generate/sim-pebble.crt sources: - sim-pebble.cnf generates: - sim-pebble.crt - - # Generate pebble configuration - sim-pebble: - deps: - - sim-crt - dir: config - cmds: - - ./sim_pebble.sh > sim_pebble.go - sources: - - sim_pebble.sh - generates: - - test -f sim_pebble.go + - generate/sim-pebble.crt diff --git a/taskfiles/Devtree.yml b/taskfiles/Devtree.yml index 6a2f595e..8758bab1 100644 --- a/taskfiles/Devtree.yml +++ b/taskfiles/Devtree.yml @@ -11,13 +11,13 @@ tasks: # The bootloader for ast2400 is something like 10KiB, and the DTB is 25 KiB. # Here we give the extra space a total of 100 KiB to have some space. - | - go run ../../platform/cmd/flash-layout/main.go \ + go run ../../helper/flash-layout/main.go \ -extra 102400 \ ../linux/zImage.boot \ > ubmc-flash-layout.dtsi - echo "Done!" sources: - - ../../platform/cmd/flash-layout/main.go + - ../../helper/flash-layout/main.go - ../linux/zImage.boot generates: - ubmc-flash-layout.dtsi @@ -30,7 +30,7 @@ tasks: cmds: - echo "Building dummy dtb..." - | - go run ../platform/cmd/boot-config/main.go \ + go run ../helper/boot-config/main.go \ --ram-start {{.__RAM_START}} \ --ram-size {{.__RAM_SIZE}} \ --dtb /dev/null \ @@ -48,7 +48,7 @@ tasks: ../platform/{{.__TARGET}}/platform.dts | dtc -O dtb -o boot/platform.dtb.boot.dummy - - echo "Done!" sources: - - ../platform/cmd/boot-config/*.go + - ../helper/boot-config/*.go - ../platform/{{.__TARGET}}/platform.dts generates: - boot/boot-config.auto.h @@ -62,7 +62,7 @@ tasks: cmds: - echo "Building LinuxBoot dtb..." - | - go run ../platform/cmd/boot-config/main.go \ + go run ../helper/boot-config/main.go \ --ram-start {{.__RAM_START}} \ --ram-size {{.__RAM_SIZE}} \ --dtb boot/platform.dtb.boot.dummy \ @@ -80,7 +80,7 @@ tasks: ../platform/{{.__TARGET}}/platform.dts | dtc -O dtb -o boot/platform.dtb.boot - - echo "Done!" sources: - - ../platform/cmd/boot-config/*.go + - ../helper/boot-config/*.go - ../platform/{{.__TARGET}}/platform.dts - boot/platform.dtb.boot.dummy generates: diff --git a/taskfiles/Tests.yml b/taskfiles/Tests.yml index 19772531..a4a4cd46 100644 --- a/taskfiles/Tests.yml +++ b/taskfiles/Tests.yml @@ -1,17 +1,18 @@ version: '3' +vars: + GO_SOURCE_DIRS: ./pkg/... ./platform/... ./cmd/... ./config/... ./helper/... ./boot/... + tasks: # Call go test on all files all: cmds: - - rm -rf vendor/ - - go test ./... + - go test {{.GO_SOURCE_DIRS}} # Call go test with coverage on all files coverage: cmds: - - rm -rf vendor/ - - go test -cover ./... + - go test -cover {{.GO_SOURCE_DIRS}} # Run go test integration: @@ -22,5 +23,4 @@ tasks: # Call go test with race condition detection race: cmds: - - rm -rf vendor - - go test -race ./... + - go test -race {{.GO_SOURCE_DIRS}} diff --git a/u-bmc.go b/u-bmc.go index 62939c8f..e4a790f8 100644 --- a/u-bmc.go +++ b/u-bmc.go @@ -135,6 +135,7 @@ func Main() error { commands = append(commands, bmccmds...) commands = append(commands, urootcmds...) commands = append(commands, extracmds...) + commands = removeDuplicate(commands) pwd, err := os.Getwd() if err != nil { return err @@ -192,3 +193,21 @@ func urootAbsEach(in []string) []string { } return out } + +func removeDuplicate(in []string) []string { + base := make(map[string]int) + for i, s := range in { + base[filepath.Base(s)] = i + } + unique := make([]string, len(in)) + for _, i := range base { + unique[i] = in[i] + } + var out []string + for _, s := range unique { + if s != "" { + out = append(out, s) + } + } + return out +}