Esempio n. 1
0
// CopyFromHost copies a set of files from the Docker host to the local file system
func (h *HostHelper) CopyFromHost(sourceDir, destDir string) error {
	container, err := h.runner().
		Image(h.image).
		Bind(fmt.Sprintf("%[1]s:%[1]s:ro", sourceDir)).
		Create()
	if err != nil {
		return err
	}
	defer func() {
		errors.LogError(h.client.RemoveContainer(docker.RemoveContainerOptions{ID: container}))
	}()
	localTarFile, err := ioutil.TempFile("", "local-copy-tar-")
	if err != nil {
		return err
	}
	localTarClosed := false
	defer func() {
		if !localTarClosed {
			errors.LogError(localTarFile.Close())
		}
		errors.LogError(os.Remove(localTarFile.Name()))
	}()
	glog.V(4).Infof("Downloading from host path %s to local tar file: %s", sourceDir, localTarFile.Name())
	err = h.client.DownloadFromContainer(container, docker.DownloadFromContainerOptions{
		Path:         sourceDir,
		OutputStream: localTarFile,
	})
	if err != nil {
		return err
	}
	if err = localTarFile.Close(); err != nil {
		return err
	}
	localTarClosed = true
	inputTar, err := os.Open(localTarFile.Name())
	if err != nil {
		return err
	}
	defer func() {
		errors.LogError(inputTar.Close())
	}()
	tarHelper := tarhelper.New()
	tarHelper.SetExclusionPattern(nil)
	glog.V(4).Infof("Extracting temporary tar %s to directory %s", inputTar.Name(), destDir)
	var tarLog io.Writer
	if glog.V(5) {
		tarLog = os.Stderr
	}
	return tarHelper.ExtractTarStreamWithLogging(destDir, inputTar, tarLog)
}
Esempio n. 2
0
func (h *Helper) TestIP(ip string) error {

	// Start test server on host
	id, err := h.runHelper.New().Image(h.image).
		Privileged().
		HostNetwork().
		Entrypoint("socat").
		Command("TCP-LISTEN:8443,crlf,reuseaddr,fork", "SYSTEM:\"echo 'hello world'\"").Start()
	if err != nil {
		return errors.NewError("cannnot start simple server on Docker host").WithCause(err)
	}
	defer func() {
		errors.LogError(h.dockerHelper.StopAndRemoveContainer(id))
	}()

	// Attempt to connect to test container
	testHost := fmt.Sprintf("%s:8443", ip)
	glog.V(4).Infof("Attempting to dial %s", testHost)
	if err = cmdutil.WaitForSuccessfulDial(false, "tcp", testHost, 200*time.Millisecond, 1*time.Second, 10); err != nil {
		glog.V(2).Infof("Dial error: %v", err)
		return err
	}
	glog.V(4).Infof("Successfully dialed %s", testHost)
	return nil
}
Esempio n. 3
0
func (h *Helper) TestForwardedIP(ip string) error {
	// Start test server on host
	id, err := h.runHelper.New().Image(h.image).
		PortForward(8443, 8443).
		Entrypoint("socat").
		Command("TCP-LISTEN:8443,crlf,reuseaddr,fork", "SYSTEM:\"echo 'hello world'\"").Start()
	if err != nil {
		return errors.NewError("cannnot start simple server on Docker host").WithCause(err)
	}
	defer func() {
		errors.LogError(h.dockerHelper.StopAndRemoveContainer(id))
	}()
	return testIPDial(ip)
}
Esempio n. 4
0
// makeTempCopy creates a temporary directory and places a copy of the source file
// in it. It returns the directory where the temporary copy was made.
func makeTempCopy(file string) (string, error) {
	tempDir, err := ioutil.TempDir("", "")
	if err != nil {
		return "", err
	}
	destPath := filepath.Join(tempDir, filepath.Base(file))
	destFile, err := os.Create(destPath)
	if err != nil {
		return "", err
	}
	defer func() {
		errors.LogError(destFile.Close())
	}()
	sourceFile, err := os.Open(file)
	if err != nil {
		return "", err
	}
	defer func() {
		errors.LogError(sourceFile.Close())
	}()
	_, err = io.Copy(destFile, sourceFile)
	return tempDir, err
}
Esempio n. 5
0
// DownloadDirFromContainer copies a set of files from the Docker host to the local file system
func (h *HostHelper) DownloadDirFromContainer(sourceDir, destDir string) error {
	container, err := h.runner().
		Image(h.image).
		Bind(h.defaultBinds()...).
		Entrypoint("/bin/true").
		Create()
	if err != nil {
		return err
	}
	defer func() {
		errors.LogError(h.client.RemoveContainer(docker.RemoveContainerOptions{ID: container}))
	}()
	err = dockerhelper.DownloadDirFromContainer(h.client, container, sourceDir, destDir)
	if err != nil {
		glog.V(4).Infof("An error occurred downloading the directory: %v", err)
	} else {
		glog.V(4).Infof("Successfully downloaded directory.")
	}
	return err
}
Esempio n. 6
0
// UploadFileToContainer copies a local file to the Docker host
func (h *HostHelper) UploadFileToContainer(src, dst string) error {
	container, err := h.runner().
		Image(h.image).
		Bind(h.defaultBinds()...).
		Entrypoint("/bin/true").
		Create()
	if err != nil {
		return err
	}
	defer func() {
		errors.LogError(h.client.RemoveContainer(docker.RemoveContainerOptions{ID: container}))
	}()
	err = dockerhelper.UploadFileToContainer(h.client, container, src, dst)
	if err != nil {
		glog.V(4).Infof("An error occurred uploading the file: %v", err)
	} else {
		glog.V(4).Infof("Successfully uploaded file.")
	}
	return err
}
Esempio n. 7
0
// Start starts the OpenShift master as a Docker container
// and returns a directory in the local file system where
// the OpenShift configuration has been copied
func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) {
	// Ensure that socat is available locally
	if opt.PortForwarding {
		err := CheckSocat()
		if err != nil {
			return "", err
		}
	}

	binds := openShiftContainerBinds
	env := []string{}
	if opt.UseSharedVolume {
		binds = append(binds, fmt.Sprintf("%[1]s:%[1]s:shared", opt.HostVolumesDir))
		env = append(env, "OPENSHIFT_CONTAINERIZED=false")
	} else {
		binds = append(binds, "/:/rootfs:ro")
		propagationMode := ""
		if opt.SetPropagationMode {
			propagationMode = ":rslave"
		}
		binds = append(binds, fmt.Sprintf("%[1]s:%[1]s%[2]s", opt.HostVolumesDir, propagationMode))
	}
	env = append(env, opt.Environment...)
	binds = append(binds, fmt.Sprintf("%s:/var/lib/origin/openshift.local.config:z", opt.HostConfigDir))

	// Check if a configuration exists before creating one if UseExistingConfig
	// was specified
	var configDir string
	cleanupConfig := func() {
		errors.LogError(os.RemoveAll(configDir))
	}
	skipCreateConfig := false
	if opt.UseExistingConfig {
		var err error
		configDir, err = h.copyConfig(opt.HostConfigDir)
		if err == nil {
			_, err = os.Stat(filepath.Join(configDir, "master", "master-config.yaml"))
			if err == nil {
				skipCreateConfig = true
			}
		}
	}

	// Create configuration if needed
	var nodeHost string
	if !skipCreateConfig {
		glog.V(1).Infof("Creating openshift configuration at %s on Docker host", opt.HostConfigDir)
		fmt.Fprintf(out, "Creating initial OpenShift configuration\n")
		createConfigCmd := []string{
			"start",
			fmt.Sprintf("--images=%s", opt.Images),
			fmt.Sprintf("--volume-dir=%s", opt.HostVolumesDir),
			fmt.Sprintf("--dns=0.0.0.0:%d", opt.DNSPort),
			"--write-config=/var/lib/origin/openshift.local.config",
		}
		if opt.PortForwarding {
			internalIP, err := h.ServerIP()
			if err != nil {
				return "", err
			}
			nodeHost = internalIP
			createConfigCmd = append(createConfigCmd, fmt.Sprintf("--master=%s", internalIP))
			createConfigCmd = append(createConfigCmd, fmt.Sprintf("--public-master=https://%s:8443", opt.ServerIP))
		} else {
			nodeHost = opt.ServerIP
			createConfigCmd = append(createConfigCmd, fmt.Sprintf("--master=%s", opt.ServerIP))
			if len(h.publicHost) > 0 {
				createConfigCmd = append(createConfigCmd, fmt.Sprintf("--public-master=https://%s:8443", h.publicHost))
			}
		}
		createConfigCmd = append(createConfigCmd, fmt.Sprintf("--hostname=%s", nodeHost))
		_, err := h.runHelper.New().Image(h.image).
			Privileged().
			DiscardContainer().
			HostNetwork().
			HostPid().
			Bind(binds...).
			Env(env...).
			Command(createConfigCmd...).Run()
		if err != nil {
			return "", errors.NewError("could not create OpenShift configuration").WithCause(err)
		}
		configDir, err = h.copyConfig(opt.HostConfigDir)
		if err != nil {
			return "", errors.NewError("could not copy OpenShift configuration").WithCause(err)
		}
		err = h.updateConfig(configDir, opt.HostConfigDir, opt.RouterIP, opt.MetricsHost, opt.LoggingHost)
		if err != nil {
			cleanupConfig()
			return "", errors.NewError("could not update OpenShift configuration").WithCause(err)
		}
	}
	if nodeHost == "" {
		if opt.PortForwarding {
			var err error
			nodeHost, err = h.ServerIP()
			if err != nil {
				return "", err
			}
		} else {
			var err error
			hostName, err := h.hostHelper.Hostname()
			if err != nil {
				return "", err
			}
			nodeHost, err = h.DetermineNodeHost(opt.HostConfigDir, opt.ServerIP, hostName)
			if err != nil {
				return "", err
			}
		}
	}
	masterConfig, nodeConfig, err := h.getOpenShiftConfigFiles(nodeHost)
	if err != nil {
		cleanupConfig()
		return "", errors.NewError("could not get OpenShift configuration file paths").WithCause(err)
	}

	fmt.Fprintf(out, "Starting OpenShift using container '%s'\n", h.containerName)
	startCmd := []string{
		"start",
		fmt.Sprintf("--master-config=%s", masterConfig),
		fmt.Sprintf("--node-config=%s", nodeConfig),
	}
	if opt.LogLevel > 0 {
		startCmd = append(startCmd, fmt.Sprintf("--loglevel=%d", opt.LogLevel))
	}

	if opt.PortForwarding {
		err = h.startSocatTunnel()
		if err != nil {
			return "", err
		}
	}

	if len(opt.HostDataDir) > 0 {
		binds = append(binds, fmt.Sprintf("%s:/var/lib/origin/openshift.local.etcd:z", opt.HostDataDir))
	}
	_, err = h.runHelper.New().Image(h.image).
		Name(h.containerName).
		Privileged().
		HostNetwork().
		HostPid().
		Bind(binds...).
		Env(env...).
		Command(startCmd...).
		Start()
	if err != nil {
		return "", errors.NewError("cannot start OpenShift daemon").WithCause(err)
	}

	// Wait a minimum amount of time and check whether we're still running. If not, we know the daemon didn't start
	time.Sleep(initialStatusCheckWait)
	_, running, err := h.dockerHelper.GetContainerState(h.containerName)
	if err != nil {
		return "", errors.NewError("cannot get state of OpenShift container %s", h.containerName).WithCause(err)
	}
	if !running {
		return "", ErrOpenShiftFailedToStart(h.containerName).WithDetails(h.OriginLog())
	}

	// Wait until the API server is listening
	fmt.Fprintf(out, "Waiting for API server to start listening\n")
	masterHost := fmt.Sprintf("%s:8443", opt.ServerIP)
	if err = cmdutil.WaitForSuccessfulDial(true, "tcp", masterHost, 200*time.Millisecond, 1*time.Second, serverUpTimeout); err != nil {
		return "", ErrTimedOutWaitingForStart(h.containerName).WithDetails(h.OriginLog())
	}
	// Check for healthz endpoint to be ready
	client, err := masterHTTPClient(configDir)
	if err != nil {
		return "", err
	}
	for {
		resp, ierr := client.Get(h.healthzReadyURL(opt.ServerIP))
		if ierr != nil {
			return "", errors.NewError("cannot access master readiness URL %s", h.healthzReadyURL(opt.ServerIP)).WithCause(err).WithDetails(h.OriginLog())
		}
		if resp.StatusCode == http.StatusOK {
			break
		}
		if resp.StatusCode == http.StatusServiceUnavailable ||
			resp.StatusCode == http.StatusForbidden {
			time.Sleep(500 * time.Millisecond)
			continue
		}
		var responseBody string
		body, rerr := ioutil.ReadAll(resp.Body)
		if rerr == nil {
			responseBody = string(body)
		}
		return "", errors.NewError("server is not ready. Response (%d): %s", resp.StatusCode, responseBody).WithCause(ierr).WithDetails(h.OriginLog())
	}
	fmt.Fprintf(out, "OpenShift server started\n")
	return configDir, nil
}
Esempio n. 8
0
// CopyMasterConfigToHost copies a local file to the Docker host
func (h *HostHelper) CopyMasterConfigToHost(sourceFile, destDir string) error {
	localDir, err := makeTempCopy(sourceFile)
	if err != nil {
		return err
	}
	tarHelper := tarhelper.New()
	tarHelper.SetExclusionPattern(nil)
	var tarLog io.Writer
	if glog.V(5) {
		tarLog = os.Stderr
	}
	localTarFile, err := ioutil.TempFile("", "master-config")
	if err != nil {
		return err
	}
	localTarClosed := false
	defer func() {
		if !localTarClosed {
			errors.LogError(localTarFile.Close())
		}
	}()
	glog.V(4).Infof("Creating temporary tar %s to upload to %s", localTarFile.Name(), destDir)
	err = tarHelper.CreateTarStreamWithLogging(localDir, false, localTarFile, tarLog)
	if err != nil {
		return err
	}
	err = localTarFile.Close()
	if err != nil {
		return err
	}
	localTarClosed = true
	localTarInputClosed := false
	localTarInput, err := os.Open(localTarFile.Name())
	if err != nil {
		return err
	}
	defer func() {
		if !localTarInputClosed {
			localTarInput.Close()
		}
	}()
	bind := fmt.Sprintf("%s:/var/lib/origin/openshift.local.config:z", destDir)
	container, err := h.runner().
		Image(h.image).
		Bind(bind).Create()
	_ = container
	if err != nil {
		return err
	}
	defer func() {
		errors.LogError(h.client.RemoveContainer(docker.RemoveContainerOptions{ID: container}))
	}()

	glog.V(4).Infof("Uploading tar file %s to remote dir: %s", localTarFile.Name(), destDir)
	err = h.client.UploadToContainer(container, docker.UploadToContainerOptions{
		InputStream: localTarInput,
		Path:        "/var/lib/origin/openshift.local.config/master",
	})
	if err != nil {
		glog.V(4).Infof("An error occurred uploading the file: %v", err)
	} else {
		// If the upload succeeded the local input stream will be closed automatically
		localTarInputClosed = true
		glog.V(4).Infof("Successfully uploaded file.")
	}
	return err
}