Merge pull request #5530 from BaxterStockman/lxc-builder-cli-options
Add options to LXC builder for influencing for how containers are built and started
This commit is contained in:
commit
d00f884e71
|
@ -16,6 +16,7 @@ import (
|
|||
type LxcAttachCommunicator struct {
|
||||
RootFs string
|
||||
ContainerName string
|
||||
AttachOptions []string
|
||||
CmdWrapper CommandWrapper
|
||||
}
|
||||
|
||||
|
@ -110,8 +111,13 @@ func (c *LxcAttachCommunicator) DownloadDir(src string, dst string, exclude []st
|
|||
|
||||
func (c *LxcAttachCommunicator) Execute(commandString string) (*exec.Cmd, error) {
|
||||
log.Printf("Executing with lxc-attach in container: %s %s %s", c.ContainerName, c.RootFs, commandString)
|
||||
|
||||
attachCommand := []string{"sudo", "lxc-attach"}
|
||||
attachCommand = append(attachCommand, c.AttachOptions...)
|
||||
attachCommand = append(attachCommand, []string{"--name", "%s", "--", "/bin/sh -c \"%s\""}...)
|
||||
|
||||
command, err := c.CmdWrapper(
|
||||
fmt.Sprintf("sudo lxc-attach --name %s -- /bin/sh -c \"%s\"", c.ContainerName, commandString))
|
||||
fmt.Sprintf(strings.Join(attachCommand, " "), c.ContainerName, commandString))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ type Config struct {
|
|||
ContainerName string `mapstructure:"container_name"`
|
||||
CommandWrapper string `mapstructure:"command_wrapper"`
|
||||
RawInitTimeout string `mapstructure:"init_timeout"`
|
||||
CreateOptions []string `mapstructure:"create_options"`
|
||||
StartOptions []string `mapstructure:"start_options"`
|
||||
AttachOptions []string `mapstructure:"attach_options"`
|
||||
Name string `mapstructure:"template_name"`
|
||||
Parameters []string `mapstructure:"template_parameters"`
|
||||
EnvVars []string `mapstructure:"template_environment_vars"`
|
||||
|
|
|
@ -28,12 +28,15 @@ func (s *stepLxcCreate) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
|
||||
commands := make([][]string, 3)
|
||||
commands[0] = append(config.EnvVars, []string{"lxc-create", "-n", name, "-t", config.Name, "--"}...)
|
||||
commands[0] = append(config.EnvVars, "lxc-create")
|
||||
commands[0] = append(commands[0], config.CreateOptions...)
|
||||
commands[0] = append(commands[0], []string{"-n", name, "-t", config.Name, "--"}...)
|
||||
commands[0] = append(commands[0], config.Parameters...)
|
||||
// prevent tmp from being cleaned on boot, we put provisioning scripts there
|
||||
// todo: wait for init to finish before moving on to provisioning instead of this
|
||||
commands[1] = []string{"touch", filepath.Join(rootfs, "tmp", ".tmpfs")}
|
||||
commands[2] = []string{"lxc-start", "-d", "--name", name}
|
||||
commands[2] = append([]string{"lxc-start"}, config.StartOptions...)
|
||||
commands[2] = append(commands[2], []string{"-d", "--name", name}...)
|
||||
|
||||
ui.Say("Creating container...")
|
||||
for _, command := range commands {
|
||||
|
|
|
@ -19,6 +19,7 @@ func (s *StepProvision) Run(state multistep.StateBag) multistep.StepAction {
|
|||
// Create our communicator
|
||||
comm := &LxcAttachCommunicator{
|
||||
ContainerName: config.ContainerName,
|
||||
AttachOptions: config.AttachOptions,
|
||||
RootFs: mountPath,
|
||||
CmdWrapper: wrappedCommand,
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ func (s *StepWaitInit) waitForInit(state multistep.StateBag, cancel <-chan struc
|
|||
|
||||
comm := &LxcAttachCommunicator{
|
||||
ContainerName: config.ContainerName,
|
||||
AttachOptions: config.AttachOptions,
|
||||
RootFs: mountPath,
|
||||
CmdWrapper: wrappedCommand,
|
||||
}
|
||||
|
|
|
@ -1,40 +1,106 @@
|
|||
#!/usr/bin/env bats
|
||||
#
|
||||
# This tests the lxc builder. The teardown function will
|
||||
# delete any images in the output-lxc-* folders.
|
||||
# This tests the lxc builder by creating minimal containers and checking that
|
||||
# custom lxc container configuration files are successfully applied. The
|
||||
# teardown function will delete any images in the output-lxc-* folders along
|
||||
# with the auto-generated lxc container configuration files and hook scripts.
|
||||
|
||||
#load test_helper
|
||||
#fixtures builder-lxc
|
||||
FIXTURE_ROOT="$BATS_TEST_DIRNAME/fixtures/builder-lxc"
|
||||
|
||||
have_command() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Required parameters
|
||||
command -v lxc-create >/dev/null 2>&1 || {
|
||||
have_command lxc-create || {
|
||||
echo "'lxc-create' must be installed via the lxc (or lxc1 for ubuntu >=16.04) package" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
DESTROY_HOOK_SCRIPT=$FIXTURE_ROOT/destroy-hook.sh
|
||||
DESTROY_HOOK_LOG=$FIXTURE_ROOT/destroy-hook.log
|
||||
printf > "$DESTROY_HOOK_SCRIPT" '
|
||||
echo "$LXC_NAME" > "%s"
|
||||
' "$DESTROY_HOOK_LOG"
|
||||
chmod +x "$DESTROY_HOOK_SCRIPT"
|
||||
|
||||
INIT_CONFIG=$FIXTURE_ROOT/lxc.custom.conf
|
||||
printf > "$INIT_CONFIG" '
|
||||
lxc.hook.destroy = %s
|
||||
' "$DESTROY_HOOK_SCRIPT"
|
||||
|
||||
teardown() {
|
||||
for f in "$INIT_CONFIG" "$DESTROY_HOOK_SCRIPT" "$DESTROY_HOOK_LOG"; do
|
||||
[ -e "$f" ] && rm -f "$f"
|
||||
done
|
||||
|
||||
rm -rf output-lxc-*
|
||||
}
|
||||
|
||||
@test "lxc: build centos minimal.json" {
|
||||
run packer build -var template_name=centos $FIXTURE_ROOT/minimal.json
|
||||
[ "$status" -eq 0 ]
|
||||
[ -f output-lxc-centos/rootfs.tar.gz ]
|
||||
[ -f output-lxc-centos/lxc-config ]
|
||||
assert_build() {
|
||||
local template_name="$1"
|
||||
shift
|
||||
|
||||
local build_status=0
|
||||
|
||||
run packer build -var template_name="$template_name" "$@"
|
||||
|
||||
[ "$status" -eq 0 ] || {
|
||||
echo "${template_name} build exited badly: $status" >&2
|
||||
echo "$output" >&2
|
||||
build_status="$status"
|
||||
}
|
||||
|
||||
for expected in "output-lxc-${template_name}"/{rootfs.tar.gz,lxc-config}; do
|
||||
[ -f "$expected" ] || {
|
||||
echo "missing expected artifact '${expected}'" >&2
|
||||
build_status=1
|
||||
}
|
||||
done
|
||||
|
||||
return $build_status
|
||||
}
|
||||
|
||||
assert_container_name() {
|
||||
local container_name="$1"
|
||||
|
||||
[ -f "$DESTROY_HOOK_LOG" ] || {
|
||||
echo "missing expected lxc.hook.destroy logfile '$DESTROY_HOOK_LOG'"
|
||||
return 1
|
||||
}
|
||||
|
||||
read -r lxc_name < "$DESTROY_HOOK_LOG"
|
||||
|
||||
[ "$lxc_name" = "$container_name" ]
|
||||
}
|
||||
|
||||
@test "lxc: build centos minimal.json" {
|
||||
have_command yum || skip "'yum' must be installed to build centos containers"
|
||||
local container_name=packer-lxc-centos
|
||||
assert_build centos -var init_config="$INIT_CONFIG" \
|
||||
-var container_name="$container_name" \
|
||||
$FIXTURE_ROOT/minimal.json
|
||||
assert_container_name "$container_name"
|
||||
}
|
||||
|
||||
@test "lxc: build trusty minimal.json" {
|
||||
run packer build -var template_name=ubuntu -var template_parameters="SUITE=trusty" $FIXTURE_ROOT/minimal.json
|
||||
[ "$status" -eq 0 ]
|
||||
[ -f output-lxc-ubuntu/rootfs.tar.gz ]
|
||||
[ -f output-lxc-ubuntu/lxc-config ]
|
||||
have_command debootstrap || skip "'debootstrap' must be installed to build ubuntu containers"
|
||||
local container_name=packer-lxc-ubuntu
|
||||
assert_build ubuntu -var init_config="$INIT_CONFIG" \
|
||||
-var container_name="$container_name" \
|
||||
-var template_parameters="SUITE=trusty" \
|
||||
$FIXTURE_ROOT/minimal.json
|
||||
assert_container_name "$container_name"
|
||||
}
|
||||
|
||||
@test "lxc: build debian minimal.json" {
|
||||
run packer build -var template_name=debian -var template_parameters="SUITE=jessie" $FIXTURE_ROOT/minimal.json
|
||||
[ "$status" -eq 0 ]
|
||||
[ -f output-lxc-debian/rootfs.tar.gz ]
|
||||
[ -f output-lxc-debian/lxc-config ]
|
||||
have_command debootstrap || skip "'debootstrap' must be installed to build debian containers"
|
||||
local container_name=packer-lxc-debian
|
||||
assert_build debian -var init_config="$INIT_CONFIG" \
|
||||
-var container_name="$container_name" \
|
||||
-var template_parameters="SUITE=jessie" \
|
||||
$FIXTURE_ROOT/minimal.json
|
||||
assert_container_name "$container_name"
|
||||
}
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
{
|
||||
"variables": {
|
||||
"template_name": "debian",
|
||||
"template_parameters": "SUITE=jessie"
|
||||
"template_parameters": "SUITE=jessie",
|
||||
"container_name": "packer-lxc",
|
||||
"set_var": "hello"
|
||||
},
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"if [ \"$SET_VAR\" != \"{{user `set_var`}}\" ]; then",
|
||||
" echo \"Got unexpected value '$SET_VAR' for SET_VAR\" 1>&2",
|
||||
" exit 1",
|
||||
"fi"
|
||||
]
|
||||
}
|
||||
],
|
||||
"builders": [
|
||||
{
|
||||
"type": "lxc",
|
||||
"name": "lxc-{{user `template_name`}}",
|
||||
"template_name": "{{user `template_name`}}",
|
||||
"container_name": "{{user `container_name`}}",
|
||||
"create_options": [ "-f", "{{user `init_config`}}" ],
|
||||
"attach_options": [ "--clear-env", "--set-var", "SET_VAR={{user `set_var`}}" ],
|
||||
"config_file": "/usr/share/lxc/config/{{user `template_name`}}.common.conf",
|
||||
"template_environment_vars": [ "{{user `template_parameters`}}" ]
|
||||
}
|
||||
|
|
|
@ -110,3 +110,18 @@ Below is a fully functioning example.
|
|||
`/usr/share/lxc/templates/lxc-<template_name>`. Note: This gets passed as
|
||||
ARGV to the template command. Ensure you have an array of strings, as
|
||||
a single string with spaces probably won't work. Defaults to `[]`.
|
||||
|
||||
- `create_options` (array of strings) - Options to pass to `lxc-create`. For
|
||||
instance, you can specify a custom LXC container configuration file with
|
||||
`["-f", "/path/to/lxc.conf"]`. Defaults to `[]`. See `man 1 lxc-create` for
|
||||
available options.
|
||||
|
||||
- `start_options` (array of strings) - Options to pass to `lxc-start`. For
|
||||
instance, you can override parameters from the LXC container configuration
|
||||
file via `["--define", "KEY=VALUE"]`. Defaults to `[]`. See `man 1
|
||||
lxc-start` for available options.
|
||||
|
||||
- `attach_options` (array of strings) - Options to pass to `lxc-attach`. For
|
||||
instance, you can prevent the container from inheriting the host machine's
|
||||
environment by specifying `["--clear-env"]`. Defaults to `[]`. See `man 1
|
||||
lxc-attach` for available options.
|
||||
|
|
Loading…
Reference in New Issue