예제 #1
0
파일: utils.go 프로젝트: mefellows/parity
// WaitForNetworkWithTimeout waits for a network connection to become available within a timeout
func WaitForNetworkWithTimeout(name string, host string, timeout time.Duration) {
	waitDone := make(chan bool, 1)
	go func() {
		log.Info("Waiting for %s to become available (%s)", name, host)
		for {
			select {
			case <-time.After(5 * time.Second):
			}

			_, err := net.DialTimeout("tcp", host, 10*time.Second)
			if err != nil {
				continue
			}
			waitDone <- true
		}
	}()

WaitLoop:
	for {
		select {
		case <-waitDone:
			log.Info("Connected to %s", name)
			break WaitLoop
		case <-time.After(timeout):
			log.Fatalf("Unable to connect to %s %s", name, "Is Docker running?")
		}
	}

	return
}
예제 #2
0
파일: utils.go 프로젝트: mefellows/parity
// ReadComposeVolumes reads a docker-compose.yml and return a slice of
// directories to sync into the Docker Host
//
// "." and "./." is converted to the current directory parity is running from.
// Any volume starting with "/" will be treated as an absolute path.
// All other volumes (e.g. starting with "./" or without a prefix "/") will be treated as
// relative paths.
func ReadComposeVolumes() []string {
	var volumes []string

	files := FindDockerComposeFiles()
	for i, file := range files {
		if _, err := os.Stat(file); err == nil {
			project, err := docker.NewProject(&docker.Context{
				Context: project.Context{
					ComposeFiles: []string{file},
					ProjectName:  fmt.Sprintf("parity-%d", i),
				},
			})

			if err != nil {
				log.Info("Could not parse compose file")
			}

			for _, c := range project.Configs {
				for _, v := range c.Volumes {
					v = strings.SplitN(v, ":", 2)[0]

					if v == "." || v == "./." {
						v, _ = os.Getwd()
					} else if strings.Index(v, "/") != 0 {
						cwd, _ := os.Getwd()
						v = fmt.Sprintf("%s/%s", cwd, v)
					}
					volumes = append(volumes, mutils.LinuxPath(v))
				}
			}
		}
	}

	return volumes
}
예제 #3
0
파일: compose.go 프로젝트: mefellows/parity
// XServerProxy creates a TCP proxy on port 6000 to a the Unix
// socket that XQuartz is listening on.
//
// NOTE: this function does not start/install the XQuartz service
func XServerProxy(port int) {
	if runtime.GOOS != "darwin" {
		log.Debug("Not running an OSX environment, skip run X Server Proxy")
		return
	}

	l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()

	// Send all traffic back to unix $DISPLAY socket on a running XQuartz server
	addr, err := net.ResolveUnixAddr("unix", os.Getenv("DISPLAY"))
	if err != nil {
		log.Error("Error: ", err.Error())
	}
	log.Info("X Service Proxy available on all network interfaces on port %d", port)
	if host, err := utils.DockerVMHost(); err == nil {
		log.Info("Parity has detected your Docker environment and recommends running 'export DISPLAY=%s:0' in your container to forward the X display", host)
	}

	for {
		xServerClient, err := net.DialUnix("unix", nil, addr)
		if err != nil {
			log.Error("Error: ", err.Error())
		}
		defer xServerClient.Close()

		conn, err := l.Accept()
		log.Debug("X Service Proxy connected to client on: %s (remote: %s)", conn.LocalAddr(), conn.RemoteAddr())
		if err != nil {
			log.Fatal(err)
		}
		go func(c net.Conn, s *net.UnixConn) {
			buf := make([]byte, 8092)
			io.CopyBuffer(s, c, buf)
			s.CloseWrite()
		}(conn, xServerClient)

		go func(c net.Conn, s *net.UnixConn) {
			buf := make([]byte, 8092)
			io.CopyBuffer(c, s, buf)
			c.Close()
		}(conn, xServerClient)
	}
}
예제 #4
0
파일: compose.go 프로젝트: mefellows/parity
// Build will build all images in the Parity setup
func (c *DockerCompose) Build() error {
	log.Stage("Bulding containers")
	base := "Dockerfile"
	cwd, _ := os.Getwd()
	baseVersion := c.generateContainerVersion(cwd, base)
	imageName := fmt.Sprintf("%s:%s", c.ImageName, baseVersion)
	client, _ := dockerclient2.NewEnvClient()

	log.Step("Checking if image %s exists locally", imageName)
	if images, err := client.ImageList(context.Background(), types.ImageListOptions{MatchName: imageName}); err == nil {
		for _, i := range images {
			log.Info("Found image: %s", i.ID)
			return nil
		}
	}

	log.Step("Image %s not found locally, pulling", imageName)
	client.ImagePull(context.Background(), types.ImagePullOptions{ImageID: imageName}, nil)

	log.Step("Image %s not found anywhere, building", imageName)

	ctx, err := c.CreateTar(".", "Dockerfile")
	if err != nil {
		return err
	}
	defer ctx.Close()

	var progBuff io.Writer = os.Stdout
	var buildBuff io.Writer = os.Stdout

	// Setup an upload progress bar
	progressOutput := streamformatter.NewStreamFormatter().NewProgressOutput(progBuff, true)

	var body io.Reader = progress.NewProgressReader(ctx, progressOutput, 0, "", "Sending build context to Docker daemon")

	logrus.Infof("Building %s...", imageName)

	outFd, isTerminalOut := term.GetFdInfo(os.Stdout)

	// Publish latest and specific version
	response, err := client.ImageBuild(context.Background(), types.ImageBuildOptions{
		Context:    body,
		Tags:       []string{imageName, fmt.Sprintf("%s:latest", c.ImageName)},
		NoCache:    false,
		Remove:     true,
		Dockerfile: "Dockerfile",
	})

	if err != nil {
		log.Error(err.Error())
		return err
	}

	err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, outFd, isTerminalOut, nil)
	if err != nil {
		if jerr, ok := err.(*jsonmessage.JSONError); ok {
			// If no error code is set, default to 1
			if jerr.Code == 0 {
				jerr.Code = 1
			}
			fmt.Fprintf(os.Stderr, "%s%s", progBuff, buildBuff)
			return fmt.Errorf("Status: %s, Code: %d", jerr.Message, jerr.Code)
		}
	}

	return err
}