Browse Source

[coredhcp-generator] Added README and list of core plugins

Signed-off-by: Andrea Barberio <insomniac@slackware.it>
Andrea Barberio 6 years ago
parent
commit
d4d713df5b

+ 16 - 3
README.md

@@ -36,8 +36,9 @@ See also [config.yml.example](cmds/coredhcp/config.yml.example).
 
 ## Build and run
 
-The server is located under [cmds/coredhcp/](cmds/coredhcp/), so enter that
-directory first.
+An example server is located under [cmds/coredhcp/](cmds/coredhcp/), so enter that
+directory first. To build a server with a custom set of plugins, see the "Server
+with custom plugins" section below.
 
 Once you have a working configuration in `config.yml` (see [config.yml.example](cmds/coredhcp/config.yml.example)), you can build and run the server:
 ```
@@ -82,12 +83,24 @@ INFO[2019-01-05T22:29:21Z] DHCPv6Message
 ...
 ```
 
-# How to write a plugin
+# Plugins
 
 CoreDHCP is heavily based on plugins: even the core functionalities are
 implemented as plugins. Therefore, knowing how to write one is the key to add
 new features to CoreDHCP.
 
+Core plugins can be found under the [plugins](/plugins/) directory. Additional
+plugins can also be found in the
+[coredhcp/plugins](https://github.com/coredhcp/plugins) repository.
+
+## Server with custom plugins
+
+To build a server with a custom set of plugins you can use the
+[coredhcp-generator](/cmds/coredhcp-generator/) tool. Head there for
+documentation on how to use it.
+
+# How to write a plugin
+
 The best way to learn is to read the comments and source code of the
 [example plugin](plugins/example/), which guides you through the implementation
 of a simple plugin that prints a packet every time it is received by the server.

+ 40 - 0
cmds/coredhcp-generator/README.md

@@ -0,0 +1,40 @@
+## CoreDHCP Generator
+
+`coredhcp-generator` is a tool used to build CoreDHCP with the plugins you want.
+
+Why is it even needed? Go is a compiled language with no dynamic loading
+support. In order to load a plugin, it has to be compiled in. We are happy to
+provide a standard [main.go](/cmds/coredhcp/main.go), and at the same time we
+don't want to include plugins that not everyone would use, otherwise the binary
+size would grow without control.
+
+You can use `coredhcp-generator` to generate a `main.go` that includes all the
+plugins you wish. Just use it as follows:
+
+```
+$ ./coredhcp-generator -from core-plugins.txt
+2019/11/21 23:32:04 Generating output file '/tmp/coredhcp547019106/coredhcp.go' with 7 plugin(s):
+2019/11/21 23:32:04   1) github.com/coredhcp/coredhcp/plugins/file
+2019/11/21 23:32:04   2) github.com/coredhcp/coredhcp/plugins/lease_time
+2019/11/21 23:32:04   3) github.com/coredhcp/coredhcp/plugins/netmask
+2019/11/21 23:32:04   4) github.com/coredhcp/coredhcp/plugins/range
+2019/11/21 23:32:04   5) github.com/coredhcp/coredhcp/plugins/router
+2019/11/21 23:32:04   6) github.com/coredhcp/coredhcp/plugins/server_id
+2019/11/21 23:32:04   7) github.com/coredhcp/coredhcp/plugins/dns
+2019/11/21 23:32:04 Generated file '/tmp/coredhcp547019106/coredhcp.go'. You can build it by running 'go build' in the output directory.
+```
+
+You can also specify the plugin list on the command line, or mix it with
+`-from`:
+```
+$ ./coredhcp-generator -from core-plugins.txt \
+    github.com/coredhcp/plugins/redis
+```
+
+Notice that it created a file called `coredhcp.go` in a temporary directory. You
+can now `go build` that file and have your own custom CoreDHCP.
+
+## Bugs
+
+CoreDHCP uses Go versioned modules. The generated file does not do that yet. We
+will add this feature soon.

+ 7 - 0
cmds/coredhcp-generator/core-plugins.txt

@@ -0,0 +1,7 @@
+github.com/coredhcp/coredhcp/plugins/dns
+github.com/coredhcp/coredhcp/plugins/file
+github.com/coredhcp/coredhcp/plugins/lease_time
+github.com/coredhcp/coredhcp/plugins/netmask
+github.com/coredhcp/coredhcp/plugins/range
+github.com/coredhcp/coredhcp/plugins/router
+github.com/coredhcp/coredhcp/plugins/server_id

+ 40 - 4
cmds/coredhcp-generator/main.go

@@ -5,6 +5,7 @@
 package main
 
 import (
+	"bufio"
 	"flag"
 	"html/template"
 	"io/ioutil"
@@ -21,6 +22,7 @@ const (
 var (
 	flagTemplate = flag.String("template", defaultTemplateFile, "Template file name")
 	flagOutfile  = flag.String("outfile", "", "Output file path")
+	flagFromFile = flag.String("from", "", "Optional file name to get the plugin list from, one import path per line")
 )
 
 func main() {
@@ -33,13 +35,37 @@ func main() {
 	if err != nil {
 		log.Fatalf("Template parsing failed: %v", err)
 	}
-	var plugins []string
+	plugins := make(map[string]bool)
 	for _, pl := range flag.Args() {
 		pl := strings.TrimSpace(pl)
 		if pl == "" {
 			continue
 		}
-		plugins = append(plugins, pl)
+		plugins[pl] = true
+	}
+	if *flagFromFile != "" {
+		// additional plugin names from a text file, one line per plugin import
+		// path
+		fd, err := os.Open(*flagFromFile)
+		if err != nil {
+			log.Fatalf("Failed to read file '%s': %v", *flagFromFile, err)
+		}
+		defer func() {
+			if err := fd.Close(); err != nil {
+				log.Printf("Error closing file '%s': %v", *flagFromFile, err)
+			}
+		}()
+		sc := bufio.NewScanner(fd)
+		for sc.Scan() {
+			pl := strings.TrimSpace(sc.Text())
+			if pl == "" {
+				continue
+			}
+			plugins[pl] = true
+		}
+		if err := sc.Err(); err != nil {
+			log.Fatalf("Error reading file '%s': %v", *flagFromFile, err)
+		}
 	}
 	if len(plugins) == 0 {
 		log.Fatalf("No plugin specified!")
@@ -52,7 +78,12 @@ func main() {
 		}
 		outfile = path.Join(tmpdir, "coredhcp.go")
 	}
-	log.Printf("Generating output file '%s' with %d plugins", outfile, len(plugins))
+	log.Printf("Generating output file '%s' with %d plugin(s):", outfile, len(plugins))
+	idx := 1
+	for pl := range plugins {
+		log.Printf("% 3d) %s", idx, pl)
+		idx++
+	}
 	outFD, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY, 0644)
 	if err != nil {
 		log.Fatalf("Failed to create output file '%s': %v", outfile, err)
@@ -62,7 +93,12 @@ func main() {
 			log.Printf("Error while closing file descriptor for '%s': %v", outfile, err)
 		}
 	}()
-	if err := t.Execute(outFD, plugins); err != nil {
+	// WARNING: no escaping of the provided strings is done
+	pluginList := make([]string, 0, len(plugins))
+	for pl := range plugins {
+		pluginList = append(pluginList, pl)
+	}
+	if err := t.Execute(outFD, pluginList); err != nil {
 		log.Fatalf("Template execution failed: %v", err)
 	}
 	log.Printf("Generated file '%s'. You can build it by running 'go build' in the output directory.", outfile)