Просмотр исходного кода

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

Signed-off-by: Andrea Barberio <insomniac@slackware.it>
Andrea Barberio 6 лет назад
Родитель
Сommit
d4d713df5b
4 измененных файлов с 103 добавлено и 7 удалено
  1. 16 3
      README.md
  2. 40 0
      cmds/coredhcp-generator/README.md
  3. 7 0
      cmds/coredhcp-generator/core-plugins.txt
  4. 40 4
      cmds/coredhcp-generator/main.go

+ 16 - 3
README.md

@@ -36,8 +36,9 @@ See also [config.yml.example](cmds/coredhcp/config.yml.example).
 
 
 ## Build and run
 ## 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:
 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
 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
 implemented as plugins. Therefore, knowing how to write one is the key to add
 new features to CoreDHCP.
 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
 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
 [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.
 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
 package main
 
 
 import (
 import (
+	"bufio"
 	"flag"
 	"flag"
 	"html/template"
 	"html/template"
 	"io/ioutil"
 	"io/ioutil"
@@ -21,6 +22,7 @@ const (
 var (
 var (
 	flagTemplate = flag.String("template", defaultTemplateFile, "Template file name")
 	flagTemplate = flag.String("template", defaultTemplateFile, "Template file name")
 	flagOutfile  = flag.String("outfile", "", "Output file path")
 	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() {
 func main() {
@@ -33,13 +35,37 @@ func main() {
 	if err != nil {
 	if err != nil {
 		log.Fatalf("Template parsing failed: %v", err)
 		log.Fatalf("Template parsing failed: %v", err)
 	}
 	}
-	var plugins []string
+	plugins := make(map[string]bool)
 	for _, pl := range flag.Args() {
 	for _, pl := range flag.Args() {
 		pl := strings.TrimSpace(pl)
 		pl := strings.TrimSpace(pl)
 		if pl == "" {
 		if pl == "" {
 			continue
 			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 {
 	if len(plugins) == 0 {
 		log.Fatalf("No plugin specified!")
 		log.Fatalf("No plugin specified!")
@@ -52,7 +78,12 @@ func main() {
 		}
 		}
 		outfile = path.Join(tmpdir, "coredhcp.go")
 		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)
 	outFD, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY, 0644)
 	if err != nil {
 	if err != nil {
 		log.Fatalf("Failed to create output file '%s': %v", outfile, err)
 		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)
 			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.Fatalf("Template execution failed: %v", err)
 	}
 	}
 	log.Printf("Generated file '%s'. You can build it by running 'go build' in the output directory.", outfile)
 	log.Printf("Generated file '%s'. You can build it by running 'go build' in the output directory.", outfile)