Skip to content

Commit

Permalink
Merge pull request #364 from jacobweinstock/unify
Browse files Browse the repository at this point in the history
bring back the code from tinkerbell/dhcp

## Description

<!--- Please describe what this PR is going to change -->

The DHCP library was created in order to provide a mechanism for the DHCP functionality to be written in a very clean and composible way. This was not possible with the previous state of Boots and the personnel involved at that time.

The current state of Smee is ready for this functionality to be returned and placed in a very clean and composable way into the code base.

Moving this functionality back in will improve the development process/experience. It is important to note that we do take on the trade off of not having the combined commit history of the DHCP library within Smee. We won't lose the commit history entirely as the DHCP library GitHub repo will remain (archived) in order to have the commit history available.

## Why is this needed

<!--- Link to issue you have raised -->

Fixes: #

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->


## How are existing users impacted? What migration steps/scripts do we need?

<!--- Fixes a bug, unblocks installation, removes a component of the stack etc -->
<!--- Requires a DB migration script, etc. -->


## Checklist:

I have:

- [ ] updated the documentation and/or roadmap (if required)
- [ ] added unit or e2e tests
- [ ] provided instructions on how to upgrade
  • Loading branch information
jacobweinstock authored Jan 15, 2024
2 parents ea26152 + 170e57a commit a416dd9
Show file tree
Hide file tree
Showing 45 changed files with 5,045 additions and 36 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ Smee is the network boot service in the [Tinkerbell stack](https://tinkerbell.or
- Syslog server
- receives syslog messages and logs them

## Definitions

**DHCP Reservation:**
A fixed IP address that is reserved for a specific client.

**DHCP Lease:**
An IP address, that can potentially change, that is assigned to a client by the DHCP server.
The IP is typically pulled from a pool or subnet of available IP addresses.

## Running Smee

The DHCP server of Smee serves explicit host reservations only. This means that only hosts that are configured will be served an IP address and network boot details.
Expand Down
6 changes: 3 additions & 3 deletions cmd/smee/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"context"

"github.com/go-logr/logr"
"github.com/tinkerbell/dhcp/backend/file"
"github.com/tinkerbell/dhcp/backend/kube"
"github.com/tinkerbell/dhcp/handler"
"github.com/tinkerbell/smee/internal/backend/file"
"github.com/tinkerbell/smee/internal/backend/kube"
"github.com/tinkerbell/smee/internal/dhcp/handler"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
Expand Down
16 changes: 8 additions & 8 deletions cmd/smee/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import (
"github.com/go-logr/zapr"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/insomniacslk/dhcp/dhcpv4/server4"
"github.com/tinkerbell/dhcp"
"github.com/tinkerbell/dhcp/handler"
"github.com/tinkerbell/dhcp/handler/reservation"
"github.com/tinkerbell/ipxedust"
"github.com/tinkerbell/ipxedust/ihttp"
"github.com/tinkerbell/smee/ipxe/http"
"github.com/tinkerbell/smee/ipxe/script"
"github.com/tinkerbell/smee/metrics"
"github.com/tinkerbell/smee/syslog"
"github.com/tinkerbell/smee/internal/dhcp"
"github.com/tinkerbell/smee/internal/dhcp/handler"
"github.com/tinkerbell/smee/internal/dhcp/handler/reservation"
"github.com/tinkerbell/smee/internal/ipxe/http"
"github.com/tinkerbell/smee/internal/ipxe/script"
"github.com/tinkerbell/smee/internal/metric"
"github.com/tinkerbell/smee/internal/syslog"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/sync/errgroup"
Expand Down Expand Up @@ -116,7 +116,7 @@ func main() {
defer done()
ctx, otelShutdown := otelinit.InitOpenTelemetry(ctx, name)
defer otelShutdown(ctx)
metrics.Init()
metric.Init()

log := defaultLogger(cfg.logLevel)
log.Info("starting", "version", GitRev)
Expand Down
62 changes: 62 additions & 0 deletions docs/Backend-File.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# File Watcher Backend

This document gives an overview of the file watcher backend.
This backend will read in and watch a file on disk for changes.
The data from this file will then be used for serving DHCP requests.

## Why

This backend exists mainly for testing and development.
It allows the DHCP server to be run without having to spin up any additional backend servers, like [Tink](https://github.com/tinkerbell/tink) or [Cacher](https://github.com/packethost/cacher).

## Usage

```bash
# See the file example/main.go for details on how to select and use this backend in code.
go run example/main.go
```

Below is an example of the format used for this file watcher backend.
See this [example.yaml](../backend/file/testdata/example.yaml) for a full working example of the data model.

```yaml
---
08:00:27:29:4E:67:
ipAddress: "192.168.2.153"
subnetMask: "255.255.255.0"
defaultGateway: "192.168.2.1"
nameServers:
- "8.8.8.8"
- "1.1.1.1"
hostname: "pxe-virtualbox"
domainName: "example.com"
broadcastAddress: "192.168.2.255"
ntpServers:
- "132.163.96.2"
- "132.163.96.3"
leaseTime: 86400
domainSearch:
- "example.com"
netboot:
allowPxe: true
ipxeScriptUrl: "https://boot.netboot.xyz"
52:54:00:aa:88:2a:
ipAddress: "192.168.2.15"
subnetMask: "255.255.255.0"
defaultGateway: "192.168.2.1"
nameServers:
- "8.8.8.8"
- "1.1.1.1"
hostname: "sandbox"
domainName: "example.com"
broadcastAddress: "192.168.2.255"
ntpServers:
- "132.163.96.2"
- "132.163.96.3"
leaseTime: 86400
domainSearch:
- "example.com"
netboot:
allowPxe: true
ipxeScriptUrl: "https://boot.netboot.xyz"
```
25 changes: 25 additions & 0 deletions docs/Code-Structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Code Structure

## Backend

Responsible for communicating with an external persistence source and returning data from said source.
Backends live in the `backend/` directory.

## Handler

Responsible for reading a DHCP packet from a source, calling a backend, and responding to the source.
All business logic for responding or reacting to DHCP messages lives here.
Handlers live in the `handler/` directory.

## Listener

Responsible for listening for UDP packets on the specified address and port.
A default listener can be used.

## Server

Responsible for filtering for DHCP packets received by the listener and calling the specified handler.

## Functional description

Server(listener, handler(backend))
88 changes: 88 additions & 0 deletions docs/Design-Philosophy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Design Philosophy

This living document describes some Go design philosophies we endeavor to incorporate when working, building, or writing in Go.

## General

1. Prefer easy to understand over easy to do
2. First do it, then do it right, then do it better, then make it testable [14]
3. When you spawn goroutines, make it clear when - or whether - they exit. [2]
4. Packages that are imported only for their side effects should be avoided [4]
5. Package level and global variables should be avoided
6. magic is bad; global state is magic → no package level vars; no func init [13]

## Dependencies

1. External dependencies should be tried and fail fast or just keep trying
- For example, external connections, port binding, environment variables, secrets, etc
- Examples of "failing fast"
- Try external connections immediately
- Binding to ports immediately
- Examples of "keep trying"
- Block ingress traffic or calls until external connections are successful
- Should be accompanied by some way to check health status of external connections
2. Make all dependencies explicit [11]

## Naming

1. Naming general rules [12]
- Structs are plain nouns: API, Replica, Object
- Interfaces are active nouns: Reader, Writer, JobProcessor
- Functions and methods are verbs: Read, Process, Sync
2. Package names [15]
- Short: no more than one word
- No plural
- Lower case
- Informative about the service it provides
- Avoid packages named utility/utilities or model/models
3. Avoid renaming imports except to avoid a name collision; good package names should not require renaming [3]

## Interfaces

1. Accept interfaces, return structs [5]
2. Small interfaces are better [6]
3. Define an interface when you actually need it, not when you foresee needing it [7]
4. Interfaces [15]
- Use interfaces as function/method arguments & as field types
- Small interfaces are better

## Functions/Methods

1. All top-level, exported names should have doc comments, as should non-trivial unexported type or function declarations. [1]
2. Methods/functions [15]
- One function has one goal
- Simple names
- Reduce the number of nesting levels
3. Only func main has the right to decide which flags, env variables, config files are available to the user [10a],[10b]
4. `context.Context` should, in most cases, be the first argument of all functions or methods
5. Prefer synchronous functions - functions which return their results directly or finish any callbacks or channel ops before returning - over asynchronous ones. [8]

## Errors

1. Error Handling [15]
- Func `main` should normally be the only one calling fatal errors or `os.Exit`

## Source files

1. One file should be named like the package [9]
2. One file = One responsibility [9]
3. If you only have one command prefer a top level `main.go`, if you have more than one command put them in a `cmd/` package

---

[1]: https://github.com/golang/go/wiki/CodeReviewComments#doc-comments
[2]: https://github.com/golang/go/wiki/CodeReviewComments#goroutine-lifetimes
[3]: https://github.com/golang/go/wiki/CodeReviewComments#imports
[4]: https://github.com/golang/go/wiki/CodeReviewComments#import-blank
[5]: https://medium.com/@cep21/what-accept-interfaces-return-structs-means-in-go-2fe879e25ee8
[6]: https://www.practical-go-lessons.com/chap-40-design-recommendations?s=03#use-interfaces
[7]: http://c2.com/xp/YouArentGonnaNeedIt.html
[8]: https://github.com/golang/go/wiki/CodeReviewComments#synchronous-functions
[9]: https://www.practical-go-lessons.com/chap-40-design-recommendations?s=03#source-files
[10a]: https://thoughtbot.com/blog/where-to-define-command-line-flags-in-go
[10b]: https://peter.bourgon.org/go-best-practices-2016/#configuration
[11]: https://peter.bourgon.org/go-best-practices-2016/#top-tip-9
[12]: https://twitter.com/peterbourgon/status/1121023995107782656
[13]: https://peter.bourgon.org/blog/2017/06/09/theory-of-modern-go.html
[14]: https://code.tutsplus.com/articles/master-developers-addy-osmani--net-31661
[15]: https://www.practical-go-lessons.com/chap-40-design-recommendations?s=03#key-takeaways
18 changes: 10 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,27 @@ toolchain go1.21.2

require (
github.com/equinix-labs/otel-init-go v0.0.9
github.com/fsnotify/fsnotify v1.7.0
github.com/ghodss/yaml v1.0.0
github.com/go-logr/logr v1.4.1
github.com/go-logr/stdr v1.2.2
github.com/go-logr/zapr v1.3.0
github.com/google/go-cmp v0.6.0
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
github.com/packethost/xff v0.0.0-20190305172552-d3e9190c41b3
github.com/peterbourgon/ff/v3 v3.4.0
github.com/prometheus/client_golang v1.18.0
github.com/tinkerbell/dhcp v0.0.0-20231215222245-f5112b96a67c
github.com/tinkerbell/ipxedust v0.0.0-20231215220341-a535c5deb47a
github.com/tinkerbell/tink v0.9.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/trace v1.21.0
go.uber.org/zap v1.26.0
golang.org/x/net v0.19.0
golang.org/x/sync v0.6.0
k8s.io/apimachinery v0.29.0
k8s.io/client-go v0.29.0
sigs.k8s.io/controller-runtime v0.16.3
)

require (
Expand All @@ -30,12 +36,10 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.7.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zerologr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
Expand All @@ -59,6 +63,8 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mdlayher/packet v1.1.2 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
Expand All @@ -70,7 +76,6 @@ require (
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rs/zerolog v1.31.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tinkerbell/tink v0.9.0 // indirect
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
Expand All @@ -80,7 +85,6 @@ require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
Expand All @@ -95,11 +99,9 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.29.0 // indirect
k8s.io/apimachinery v0.29.0 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 // indirect
k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect
sigs.k8s.io/controller-runtime v0.16.3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
Expand Down Expand Up @@ -166,8 +168,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tinkerbell/dhcp v0.0.0-20231215222245-f5112b96a67c h1:3DP2/hZ4ew/H6OT3don45xM55W/Og7NYID7x0NZIBtA=
github.com/tinkerbell/dhcp v0.0.0-20231215222245-f5112b96a67c/go.mod h1:BZr9oLvt55h9XhrCC7/83+3ap5lH/n8MeX+rsDQAX2U=
github.com/tinkerbell/ipxedust v0.0.0-20231215220341-a535c5deb47a h1:BNbuuQp8m/L0eS9BLToKx1KQSuK/RvUuzSOXVuFKruI=
github.com/tinkerbell/ipxedust v0.0.0-20231215220341-a535c5deb47a/go.mod h1:zrFXKJHUplvuggD9MzSQuZldQZU4CLter7QYqSLiiE4=
github.com/tinkerbell/tink v0.9.0 h1:W7X/OEmhyYXE/kPVu1U31fpugVHoc2qsAvBtsZ7mkDg=
Expand Down
Loading

0 comments on commit a416dd9

Please sign in to comment.