Skip to content

Commit

Permalink
Merge pull request tinkerbell#3 from packethost/workflow
Browse files Browse the repository at this point in the history
Packet Workflow
  • Loading branch information
nathangoulding authored and mmlb committed Apr 21, 2020
2 parents 786c34a + a517bde commit 5b2d951
Show file tree
Hide file tree
Showing 132 changed files with 11,613 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*
!/tls/
!tinkerbell-server
!entrypoint.sh
!deploy/migrate
!deploy/docker-entrypoint-initdb.d/tinkerbell-init.sql
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tinkerbell-server
**/tinkerbell-cli
**/tinkerbell-worker
bin/
certs/

11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM alpine:3.7

ENTRYPOINT [ "/tinkerbell" ]
EXPOSE 42113
EXPOSE 42114

RUN apk add --no-cache --update --upgrade ca-certificates postgresql-client
RUN apk add --no-cache --update --upgrade --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing cfssl
COPY deploy/migrate /migrate
COPY deploy/docker-entrypoint-initdb.d/tinkerbell-init.sql /init.sql
COPY tinkerbell-server /tinkerbell
29 changes: 29 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
server := tinkerbell-server
cli := tinkerbell-cli
worker := tinkerbell-worker
binaries := ${server} ${cli} ${worker}
all: ${binaries}

.PHONY: server ${binaries} cli worker test
server: ${server}
cli: ${cli}
worker : ${worker}

${bindir}:
mkdir -p $@/

${server}:
CGO_ENABLED=0 go build -o $@ .

${cli}:
CGO_ENABLED=0 go build -o ./cmd/tinkerbell/$@ ./cmd/tinkerbell

${worker}:
CGO_ENABLED=0 go build -o ./worker/$@ ./worker/

run: ${binaries}
docker-compose up -d --build db
docker-compose up --build tinkerbell boots
test:
go clean -testcache
go test ./test -v
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
# tinkerbell
# Tinkerbell [https://tinkerbell.org](https://tinkerbell.org)

https://tinkerbell.org
At the highest level `tinkerbell` is the service responsible for handling the workflows. It comprises of a server and a CLI, which communicate over gRPC. The CLI is used to create a workflow along with its building blocks, i.e., template and target.

# Packet Workflow

A Packet Workflow is an open-source microservice that’s responsible for handling flexible, bare metal
provisioning workflows, that is...
- standalone and does not need the Packet API to function
- contains `Boots`, `Tinkerbell`, `Osie`, and workers
- can bootstrap any remote worker using `Boots + Osie`
- can run any set of actions as Docker container runtimes
- receive, manipulate, and save runtime data

## Content

- [Setup](docs/setup.md)
- [Components](docs/components.md)
- [Boots](docs/components.md#boots)
- [Osie](docs/components.md#osie)
- [Tinkerbell](docs/components.md#tinkerbell)
- [Hegel](docs/components.md#hegel)
- [Database](docs/components.md#database)
- [Image Registry](docs/components.md#registry)
- [Elasticsearch](docs/components.md#elastic)
- [Fluent Bit](docs/components.md#cacher)
- [Kibana](docs/components.md#kibana)
- [Architecture](docs/architecture.md)
- [Example: First Good Workflow](docs/first-good-workflow.md)
- [Concepts](docs/concepts.md)
- [Template](docs/concepts.md#template)
- [Target](docs/concepts.md#target)
- [Provisioner](docs/concepts.md#provisioner)
- [Worker](docs/concepts.md#worker)
- [Ephemeral Data](docs/concepts.md#ephemeral-data)
- [Writing a Workflow](docs/writing-workflow.md)
- [Tinkerbell CLI Reference](docs/cli/README.md)
- [Troubleshooting](docs/troubleshoot.md)
80 changes: 80 additions & 0 deletions client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package client

import (
"crypto/x509"
"io/ioutil"
"log"
"net/http"
"os"

"github.com/packethost/tinkerbell/protos/hardware"
"github.com/packethost/tinkerbell/protos/target"
"github.com/packethost/tinkerbell/protos/template"
"github.com/packethost/tinkerbell/protos/workflow"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)

// gRPC clients
var (
TemplateClient template.TemplateClient
TargetClient target.TargetClient
WorkflowClient workflow.WorkflowSvcClient
HardwareClient hardware.HardwareServiceClient
)

// GetConnection returns a gRPC client connection
func GetConnection() (*grpc.ClientConn, error) {
certURL := os.Getenv("TINKERBELL_CERT_URL")
if certURL == "" {
return nil, errors.New("undefined TINKERBELL_CERT_URL")
}
resp, err := http.Get(certURL)
if err != nil {
return nil, errors.Wrap(err, "fetch cert")
}
defer resp.Body.Close()

certs, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "read cert")
}

cp := x509.NewCertPool()
ok := cp.AppendCertsFromPEM(certs)
if !ok {
return nil, errors.Wrap(err, "parse cert")
}

grpcAuthority := os.Getenv("TINKERBELL_GRPC_AUTHORITY")
if grpcAuthority == "" {
return nil, errors.New("undefined TINKERBELL_GRPC_AUTHORITY")
}
creds := credentials.NewClientTLSFromCert(cp, "")
conn, err := grpc.Dial(grpcAuthority, grpc.WithTransportCredentials(creds))
if err != nil {
return nil, errors.Wrap(err, "connect to tinkerbell server")
}
return conn, nil
}

// Setup : create a connection to server
func Setup() {
conn, err := GetConnection()
if err != nil {
log.Fatal(err)
}
TemplateClient = template.NewTemplateClient(conn)
TargetClient = target.NewTargetClient(conn)
WorkflowClient = workflow.NewWorkflowSvcClient(conn)
HardwareClient = hardware.NewHardwareServiceClient(conn)
}

func NewTinkerbellClient() (hardware.HardwareServiceClient, error) {
conn, err := GetConnection()
if err != nil {
log.Fatal(err)
}
return hardware.NewHardwareServiceClient(conn), nil
}
Empty file removed cmd/rover/.gitkeep
Empty file.
7 changes: 7 additions & 0 deletions cmd/tinkerbell/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM alpine:3.7

CMD sleep 60d

RUN apk add --no-cache --update --upgrade ca-certificates
COPY tinkerbell-cli /bin/tinkerbell
COPY sample.tmpl /tmp
25 changes: 25 additions & 0 deletions cmd/tinkerbell/cmd/hardware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cmd

import (
"fmt"

"github.com/packethost/tinkerbell/cmd/tinkerbell/cmd/hardware"
"github.com/spf13/cobra"
)

var hardwareCmd = &cobra.Command{
Use: "hardware",
Short: "tinkerbell hardware client",
Example: "tinkerbell hardware [command]",
Args: func(c *cobra.Command, args []string) error {
if len(args) == 0 {
return fmt.Errorf("%v requires arguments", c.UseLine())
}
return nil
},
}

func init() {
hardwareCmd.AddCommand(hardware.SubCommands...)
rootCmd.AddCommand(hardwareCmd)
}
37 changes: 37 additions & 0 deletions cmd/tinkerbell/cmd/hardware/all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package hardware

import (
"context"
"fmt"
"io"
"log"

"github.com/packethost/tinkerbell/client"
"github.com/packethost/tinkerbell/protos/hardware"
"github.com/spf13/cobra"
)

// allCmd represents the all command
var allCmd = &cobra.Command{
Use: "all",
Short: "Get all known hardware for facility",
Run: func(cmd *cobra.Command, args []string) {
alls, err := client.HardwareClient.All(context.Background(), &hardware.Empty{})
if err != nil {
log.Fatal(err)
}

var hw *hardware.Hardware
err = nil
for hw, err = alls.Recv(); err == nil && hw != nil; hw, err = alls.Recv() {
fmt.Println(hw.JSON)
}
if err != nil && err != io.EOF {
log.Fatal(err)
}
},
}

func init() {
SubCommands = append(SubCommands, allCmd)
}
25 changes: 25 additions & 0 deletions cmd/tinkerbell/cmd/hardware/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package hardware

import (
"fmt"

"github.com/pkg/errors"
uuid "github.com/satori/go.uuid"
"github.com/spf13/cobra"
)

// SubCommands holds the sub commands for template command
// Example: tinkerbell template [subcommand]
var SubCommands []*cobra.Command

func verifyUUIDs(args []string) error {
if len(args) < 1 {
return errors.New("requires at least one id")
}
for _, arg := range args {
if _, err := uuid.FromString(arg); err != nil {
return fmt.Errorf("invalid uuid: %s", arg)
}
}
return nil
}
36 changes: 36 additions & 0 deletions cmd/tinkerbell/cmd/hardware/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright © 2018 packet.net

package hardware

import (
"context"
"fmt"
"log"

"github.com/packethost/tinkerbell/client"
"github.com/packethost/tinkerbell/protos/hardware"
"github.com/spf13/cobra"
)

// idCmd represents the id command
var idCmd = &cobra.Command{
Use: "id",
Short: "Get hardware by id",
Example: "tinkerbell hardware id 224ee6ab-ad62-4070-a900-ed816444cec0 cb76ae54-93e9-401c-a5b2-d455bb3800b1",
Args: func(_ *cobra.Command, args []string) error {
return verifyUUIDs(args)
},
Run: func(cmd *cobra.Command, args []string) {
for _, id := range args {
hw, err := client.HardwareClient.ByID(context.Background(), &hardware.GetRequest{ID: id})
if err != nil {
log.Fatal(err)
}
fmt.Println(hw.JSON)
}
},
}

func init() {
SubCommands = append(SubCommands, idCmd)
}
32 changes: 32 additions & 0 deletions cmd/tinkerbell/cmd/hardware/ingest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright © 2018 packet.net

package hardware

import (
"context"
"fmt"
"log"

"github.com/packethost/tinkerbell/client"
"github.com/packethost/tinkerbell/protos/hardware"
"github.com/spf13/cobra"
)

// ingestCmd represents the ingest command
var ingestCmd = &cobra.Command{
Use: "ingest",
Short: "Trigger tinkerbell to ingest",
Long: "This command only signals tinkerbell to ingest if it has not already done so.",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("ingest called")
_, err := client.HardwareClient.Ingest(context.Background(), &hardware.Empty{})
if err != nil {
log.Fatal(err)
}
},
}

func init() {
SubCommands = append(SubCommands, ingestCmd)

}
42 changes: 42 additions & 0 deletions cmd/tinkerbell/cmd/hardware/ip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright © 2018 packet.net

package hardware

import (
"context"
"fmt"
"log"
"net"

"github.com/packethost/tinkerbell/client"
"github.com/packethost/tinkerbell/protos/hardware"
"github.com/spf13/cobra"
)

// ipCmd represents the ip command
var ipCmd = &cobra.Command{
Use: "ip",
Short: "Get hardware by any associated ip",
Example: "tinkerbell hardware ip 10.0.0.2 10.0.0.3",
Args: func(_ *cobra.Command, args []string) error {
for _, arg := range args {
if net.ParseIP(arg) == nil {
return fmt.Errorf("invalid ip: %s", arg)
}
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
for _, ip := range args {
hw, err := client.HardwareClient.ByIP(context.Background(), &hardware.GetRequest{IP: ip})
if err != nil {
log.Fatal(err)
}
fmt.Println(hw.JSON)
}
},
}

func init() {
SubCommands = append(SubCommands, ipCmd)
}
Loading

0 comments on commit 5b2d951

Please sign in to comment.