unexport more funcs

pull/6441/head
Medya Gh 2020-01-30 21:01:27 -08:00
parent 006c781fbc
commit 968fe86869
4 changed files with 184 additions and 184 deletions

View File

@ -61,7 +61,7 @@ func NewDriver(c Config) *Driver {
// Create a host using the driver's config
func (d *Driver) Create() error {
params := createParams{
params := oci.CreateParams{
Name: d.NodeConfig.MachineName,
Image: d.NodeConfig.ImageDigest,
ClusterLabel: oci.ClusterLabelKey + "=" + d.MachineName,
@ -87,7 +87,7 @@ func (d *Driver) Create() error {
ContainerPort: constants.DockerDaemonPort,
},
)
err := createNode(params)
err := oci.CreateContainerNode(params)
if err != nil {
return errors.Wrap(err, "create kic node")
}
@ -296,56 +296,3 @@ func (d *Driver) nodeID(nameOrID string) (string, error) {
}
return string(id), err
}
// createNode creates a new container node
func createNode(p createParams) error {
runArgs := []string{
fmt.Sprintf("--cpus=%s", p.CPUs),
fmt.Sprintf("--memory=%s", p.Memory),
"-d", // run the container detached
"-t", // allocate a tty for entrypoint logs
// running containers in a container requires privileged
// NOTE: we could try to replicate this with --cap-add, and use less
// privileges, but this flag also changes some mounts that are necessary
// including some ones docker would otherwise do by default.
// for now this is what we want. in the future we may revisit this.
"--privileged",
"--security-opt", "seccomp=unconfined", // also ignore seccomp
"--tmpfs", "/tmp", // various things depend on working /tmp
"--tmpfs", "/run", // systemd wants a writable /run
// logs,pods be stroed on filesystem vs inside container,
"--volume", "/var",
// some k8s things want /lib/modules
"-v", "/lib/modules:/lib/modules:ro",
"--hostname", p.Name, // make hostname match container name
"--name", p.Name, // ... and set the container name
// label the node with the cluster ID
"--label", p.ClusterLabel,
// label the node with the role ID
"--label", fmt.Sprintf("%s=%s", oci.NodeRoleKey, p.Role),
}
for key, val := range p.Envs {
runArgs = append(runArgs, "-e", fmt.Sprintf("%s=%s", key, val))
}
// adds node specific args
runArgs = append(runArgs, p.ExtraArgs...)
if oci.UsernsRemap(p.OCIBinary) {
// We need this argument in order to make this command work
// in systems that have userns-remap enabled on the docker daemon
runArgs = append(runArgs, "--userns=host")
}
_, err := oci.CreateContainer(p.OCIBinary,
p.Image,
oci.WithRunArgs(runArgs...),
oci.WithMounts(p.Mounts),
oci.WithPortMappings(p.PortMappings),
)
if err != nil {
return errors.Wrap(err, "create a kic node")
}
return nil
}

View File

@ -30,8 +30,154 @@ import (
"strings"
)
// Inspect return low-level information on containers
func Inspect(ociBinary string, containerNameOrID, format string) ([]string, error) {
// CreateContainerNode creates a new container node
func CreateContainerNode(p CreateParams) error {
runArgs := []string{
fmt.Sprintf("--cpus=%s", p.CPUs),
fmt.Sprintf("--memory=%s", p.Memory),
"-d", // run the container detached
"-t", // allocate a tty for entrypoint logs
// running containers in a container requires privileged
// NOTE: we could try to replicate this with --cap-add, and use less
// privileges, but this flag also changes some mounts that are necessary
// including some ones docker would otherwise do by default.
// for now this is what we want. in the future we may revisit this.
"--privileged",
"--security-opt", "seccomp=unconfined", // also ignore seccomp
"--tmpfs", "/tmp", // various things depend on working /tmp
"--tmpfs", "/run", // systemd wants a writable /run
// logs,pods be stroed on filesystem vs inside container,
"--volume", "/var",
// some k8s things want /lib/modules
"-v", "/lib/modules:/lib/modules:ro",
"--hostname", p.Name, // make hostname match container name
"--name", p.Name, // ... and set the container name
// label the node with the cluster ID
"--label", p.ClusterLabel,
// label the node with the role ID
"--label", fmt.Sprintf("%s=%s", NodeRoleKey, p.Role),
}
for key, val := range p.Envs {
runArgs = append(runArgs, "-e", fmt.Sprintf("%s=%s", key, val))
}
// adds node specific args
runArgs = append(runArgs, p.ExtraArgs...)
if isUsernsRemapEnabled(p.OCIBinary) {
// We need this argument in order to make this command work
// in systems that have userns-remap enabled on the docker daemon
runArgs = append(runArgs, "--userns=host")
}
_, err := createContainer(p.OCIBinary,
p.Image,
withRunArgs(runArgs...),
withMounts(p.Mounts),
withPortMappings(p.PortMappings),
)
if err != nil {
return errors.Wrap(err, "create a kic node")
}
return nil
}
// CreateContainer creates a container with "docker/podman run"
func createContainer(ociBinary string, image string, opts ...createOpt) ([]string, error) {
o := &createOpts{}
for _, opt := range opts {
o = opt(o)
}
// convert mounts to container run args
runArgs := o.RunArgs
for _, mount := range o.Mounts {
runArgs = append(runArgs, generateMountBindings(mount)...)
}
for _, portMapping := range o.PortMappings {
runArgs = append(runArgs, generatePortMappings(portMapping)...)
}
// construct the actual docker run argv
args := []string{"run"}
args = append(args, runArgs...)
args = append(args, image)
args = append(args, o.ContainerArgs...)
cmd := exec.Command(ociBinary, args...)
var buff bytes.Buffer
cmd.Stdout = &buff
cmd.Stderr = &buff
err := cmd.Run()
scanner := bufio.NewScanner(&buff)
var output []string
for scanner.Scan() {
output = append(output, scanner.Text())
}
if err != nil {
return output, errors.Wrapf(err, "args: %v output: %s ", args, output)
}
return output, nil
}
// Copy copies a local asset into the container
func Copy(ociBinary string, ociID string, targetDir string, fName string) error {
if _, err := os.Stat(fName); os.IsNotExist(err) {
return errors.Wrapf(err, "error source %s does not exist", fName)
}
destination := fmt.Sprintf("%s:%s", ociID, targetDir)
cmd := exec.Command(ociBinary, "cp", fName, destination)
err := cmd.Run()
if err != nil {
return errors.Wrapf(err, "error copying %s into node", fName)
}
return nil
}
// HostPortBinding will return port mapping for a container using cli.
// example : HostPortBinding("docker", "minikube", "22")
// will return the docker assigned port:
// 32769, nil
// only supports TCP ports
func HostPortBinding(ociBinary string, ociID string, contPort int) (int, error) {
cmd := exec.Command(ociBinary, "inspect", "-f", fmt.Sprintf("'{{(index (index .NetworkSettings.Ports \"%d/tcp\") 0).HostPort}}'", contPort), ociID)
out, err := cmd.CombinedOutput()
if err != nil {
return 0, errors.Wrapf(err, "getting host-bind port %d for container ID %q, output %s", contPort, ociID, out)
}
o := strings.Trim(string(out), "\n")
o = strings.Trim(o, "'")
p, err := strconv.Atoi(o)
if err != nil {
return p, errors.Wrapf(err, "convert host-port %q to number", p)
}
return p, nil
}
// ContainerIPs returns ipv4,ipv6, error of a container by their name
func ContainerIPs(ociBinary string, name string) (string, string, error) {
// retrieve the IP address of the node using docker inspect
lines, err := inspect(ociBinary, name, "{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}")
if err != nil {
return "", "", errors.Wrap(err, "inspecting NetworkSettings.Networks")
}
if len(lines) != 1 {
return "", "", errors.Errorf("IPs output should only be one line, got %d lines", len(lines))
}
ips := strings.Split(lines[0], ",")
if len(ips) != 2 {
return "", "", errors.Errorf("container addresses should have 2 values, got %d values: %+v", len(ips), ips)
}
return ips[0], ips[1], nil
}
// ListOwnedContainers lists all the containres that kic driver created on user's machine using a label
func ListOwnedContainers(ociBinary string) ([]string, error) {
return listContainersByLabel(ociBinary, ClusterLabelKey)
}
// inspect return low-level information on containers
func inspect(ociBinary string, containerNameOrID, format string) ([]string, error) {
cmd := exec.Command(ociBinary, "inspect",
"-f", format,
containerNameOrID) // ... against the "node" container
@ -93,8 +239,8 @@ func generateMountBindings(mounts ...Mount) []string {
return result
}
// UsernsRemap checks if userns-remap is enabled in dockerd
func UsernsRemap(ociBinary string) bool {
// isUsernsRemapEnabled checks if userns-remap is enabled in docker
func isUsernsRemapEnabled(ociBinary string) bool {
cmd := exec.Command(ociBinary, "info", "--format", "'{{json .SecurityOptions}}'")
var buff bytes.Buffer
cmd.Stdout = &buff
@ -127,112 +273,31 @@ func generatePortMappings(portMappings ...PortMapping) []string {
return result
}
// createOpt is an option for Create
type createOpt func(*createOpts) *createOpts
// actual options struct
type createOpts struct {
RunArgs []string
ContainerArgs []string
Mounts []Mount
PortMappings []PortMapping
}
// CreateContainer creates a container with "docker/podman run"
func CreateContainer(ociBinary string, image string, opts ...createOpt) ([]string, error) {
o := &createOpts{}
for _, opt := range opts {
o = opt(o)
}
// convert mounts to container run args
runArgs := o.RunArgs
for _, mount := range o.Mounts {
runArgs = append(runArgs, generateMountBindings(mount)...)
}
for _, portMapping := range o.PortMappings {
runArgs = append(runArgs, generatePortMappings(portMapping)...)
}
// construct the actual docker run argv
args := []string{"run"}
args = append(args, runArgs...)
args = append(args, image)
args = append(args, o.ContainerArgs...)
cmd := exec.Command(ociBinary, args...)
var buff bytes.Buffer
cmd.Stdout = &buff
cmd.Stderr = &buff
err := cmd.Run()
scanner := bufio.NewScanner(&buff)
var output []string
for scanner.Scan() {
output = append(output, scanner.Text())
}
if err != nil {
return output, errors.Wrapf(err, "args: %v output: %s ", args, output)
}
return output, nil
}
// WithRunArgs sets the args for docker run
// withRunArgs sets the args for docker run
// as in the args portion of `docker run args... image containerArgs...`
func WithRunArgs(args ...string) createOpt {
func withRunArgs(args ...string) createOpt {
return func(r *createOpts) *createOpts {
r.RunArgs = args
return r
}
}
// WithMounts sets the container mounts
func WithMounts(mounts []Mount) createOpt {
// withMounts sets the container mounts
func withMounts(mounts []Mount) createOpt {
return func(r *createOpts) *createOpts {
r.Mounts = mounts
return r
}
}
// WithPortMappings sets the container port mappings to the host
func WithPortMappings(portMappings []PortMapping) createOpt {
// withPortMappings sets the container port mappings to the host
func withPortMappings(portMappings []PortMapping) createOpt {
return func(r *createOpts) *createOpts {
r.PortMappings = portMappings
return r
}
}
// Copy copies a local asset into the container
func Copy(ociBinary string, ociID string, targetDir string, fName string) error {
if _, err := os.Stat(fName); os.IsNotExist(err) {
return errors.Wrapf(err, "error source %s does not exist", fName)
}
destination := fmt.Sprintf("%s:%s", ociID, targetDir)
cmd := exec.Command(ociBinary, "cp", fName, destination)
err := cmd.Run()
if err != nil {
return errors.Wrapf(err, "error copying %s into node", fName)
}
return nil
}
// HostPortBinding will return port mapping for a container using cli.
// example : HostPortBinding("docker", "minikube", "22")
// will return the docker assigned port:
// 32769, nil
// only supports TCP ports
func HostPortBinding(ociBinary string, ociID string, contPort int) (int, error) {
cmd := exec.Command(ociBinary, "inspect", "-f", fmt.Sprintf("'{{(index (index .NetworkSettings.Ports \"%d/tcp\") 0).HostPort}}'", contPort), ociID)
out, err := cmd.CombinedOutput()
if err != nil {
return 0, errors.Wrapf(err, "getting host-bind port %d for container ID %q, output %s", contPort, ociID, out)
}
o := strings.Trim(string(out), "\n")
o = strings.Trim(o, "'")
p, err := strconv.Atoi(o)
if err != nil {
return p, errors.Wrapf(err, "convert host-port %q to number", p)
}
return p, nil
}
// listContainersByLabel lists all the containres that kic driver created on user's machine using a label
// io.x-k8s.kic.cluster
func listContainersByLabel(ociBinary string, label string) ([]string, error) {
@ -248,26 +313,3 @@ func listContainersByLabel(ociBinary string, label string) ([]string, error) {
}
return lines, err
}
// ContainerIPs returns ipv4,ipv6, error of a container by their name
func ContainerIPs(ociBinary string, name string) (string, string, error) {
// retrieve the IP address of the node using docker inspect
lines, err := Inspect(ociBinary, name, "{{range .NetworkSettings.Networks}}{{.IPAddress}},{{.GlobalIPv6Address}}{{end}}")
if err != nil {
return "", "", errors.Wrap(err, "inspecting NetworkSettings.Networks")
}
if len(lines) != 1 {
return "", "", errors.Errorf("IPs output should only be one line, got %d lines", len(lines))
}
ips := strings.Split(lines[0], ",")
if len(ips) != 2 {
return "", "", errors.Errorf("container addresses should have 2 values, got %d values: %+v", len(ips), ips)
}
return ips[0], ips[1], nil
}
// ListOwnedContainers lists all the containres that kic driver created on user's machine using a label
func ListOwnedContainers(ociBinary string) ([]string, error) {
return listContainersByLabel(ociBinary, ClusterLabelKey)
}

View File

@ -25,6 +25,32 @@ const (
NodeRoleKey = "io.k8s.sigs.kic.role"
)
type CreateParams struct {
Name string // used for container name and hostname
Image string // container image to use to create the node.
ClusterLabel string // label the containers we create using minikube so we can clean up
Role string // currently only role supported is control-plane
Mounts []Mount // volume mounts
APIServerPort int // kubernetes api server port
PortMappings []PortMapping // ports to map to container from host
CPUs string // number of cpu cores assign to container
Memory string // memory (mbs) to assign to the container
Envs map[string]string // environment variables to pass to the container
ExtraArgs []string // a list of any extra option to pass to oci binary during creation time, for example --expose 8080...
OCIBinary string // docker or podman
}
// createOpt is an option for Create
type createOpt func(*createOpts) *createOpts
// actual options struct
type createOpts struct {
RunArgs []string
ContainerArgs []string
Mounts []Mount
PortMappings []PortMapping
}
/*
These types are from
https://github.com/kubernetes/kubernetes/blob/063e7ff358fdc8b0916e6f39beedc0d025734cb1/pkg/kubelet/apis/cri/runtime/v1alpha2/api.pb.go#L183

View File

@ -44,18 +44,3 @@ type Config struct {
PortMappings []oci.PortMapping // container port mappings
Envs map[string]string // key,value of environment variables passed to the node
}
type createParams struct {
Name string // used for container name and hostname
Image string // container image to use to create the node.
ClusterLabel string // label the containers we create using minikube so we can clean up
Role string // currently only role supported is control-plane
Mounts []oci.Mount // volume mounts
APIServerPort int // kubernetes api server port
PortMappings []oci.PortMapping // ports to map to container from host
CPUs string // number of cpu cores assign to container
Memory string // memory (mbs) to assign to the container
Envs map[string]string // environment variables to pass to the container
ExtraArgs []string // a list of any extra option to pass to oci binary during creation time, for example --expose 8080...
OCIBinary string // docker or podman
}