2013-10-23 5 views
1

sshfs를 사용하여 도커 컨테이너에서 호스트에있는 디렉토리를 마운트하려고합니다. 오전 데 문제는 golang 애플 리케이션이 지속 가정 반면 마운트 지점이 없어 실행이 완료되면 (동일한 단계를 수동으로 수행 지속적인 결과를 생산하고 있다는 점이다golang : sshfs -o "독서 디렉토리 : 입력/출력 오류"와 함께 도커 컨테이너에서 사용하면 sshfs가 다시 연결되지 않습니다.

SSH 클라이언트 코드 :.

package main 

import (
//"bytes" 
"code.google.com/p/go.crypto/ssh" 
//"fmt" 
"io" 
"log" 
"os" 
) 

var (
server = "172.17.42.1:49155" 
username = "root" 
password = clientPassword("orobix2013") 
) 

type clientPassword string 

func (p clientPassword) Password(user string) (string, error) { 
return string(p), nil 
} 

type TerminalModes map[uint8]uint32 

const (
VINTR = 1 
VQUIT = 2 
VERASE = 3 
VKILL = 4 
VEOF = 5 
VEOL = 6 
VEOL2 = 7 
VSTART = 8 
VSTOP = 9 
VSUSP = 10 
VDSUSP = 11 
VREPRINT = 12 
VWERASE = 13 
VLNEXT = 14 
VFLUSH = 15 
VSWTCH = 16 
VSTATUS = 17 
VDISCARD = 18 
IGNPAR = 30 
PARMRK = 31 
INPCK = 32 
ISTRIP = 33 
INLCR = 34 
IGNCR = 35 
ICRNL = 36 
IUCLC = 37 
IXON = 38 
IXANY = 39 
IXOFF = 40 
IMAXBEL = 41 
ISIG = 50 
ICANON = 51 
XCASE = 52 
ECHO = 53 
ECHOE = 54 
ECHOK = 55 
ECHONL = 56 
NOFLSH = 57 
TOSTOP = 58 
IEXTEN = 59 
ECHOCTL = 60 
ECHOKE = 61 
PENDIN = 62 
OPOST = 70 
OLCUC = 71 
ONLCR = 72 
OCRNL = 73 
ONOCR = 74 
ONLRET = 75 
CS7 = 90 
CS8 = 91 
PARENB = 92 
PARODD = 93 
TTY_OP_ISPEED = 128 
TTY_OP_OSPEED = 129 
) 

func main() { 
// An SSH client is represented with a slete). Currently only 
// the "password" authentication method is supported. 
// 
// To authenticate with the remote server you must pass at least one 
// implementation of ClientAuth via the Auth field in ClientConfig. 

config := &ssh.ClientConfig{ 
User: username, 
Auth: []ssh.ClientAuth{ 
// ClientAuthPassword wraps a ClientPassword implementation 
// in a type that implements ClientAuth. 
ssh.ClientAuthPassword(password), 
}, 
} 
client, err := ssh.Dial("tcp", "172.17.42.1:49155", config) 
if err != nil { 
panic("Failed to dial: " + err.Error()) 
} 

// Each ClientConn can support multiple interactive sessions, 
// represented by a Session. 
defer client.Close() 
// Create a session 
session, err := client.NewSession() 
if err != nil { 
log.Fatalf("unable to create session: %s", err) 
} 
defer session.Close() 
// Set up terminal modes 
modes := ssh.TerminalModes{ 
ECHO: 0, // disable echoing 
TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud 
TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud 
} 
// Request pseudo terminal 
if err := session.RequestPty("xterm", 80, 40, modes); err != nil { 
log.Fatalf("request for pseudo terminal failed: %s", err) 
} 
//var b bytes.Buffer 
//session.Stdout = &bi 

stdin, _ := session.StdinPipe() 

stdout, _ := session.StdoutPipe() 

go io.Copy(os.Stdout, stdout) 
go io.Copy(stdin, os.Stdin) 
//go io.Copy(os.Stderr, stderr) 
if err := session.Run("/bin/bash -c \"sshfs [email protected]:/home/piotr/helloworld/ /mnt -o idmap=user -o reconnect;touch /mnt/ofoo\""); err != nil { 
panic("Failed to run: " + err.Error()) 
} 

컨테이너 배경 (-d)에서 실행하고 나는 마운트 포인트가 (을/mnt /)가 여전히 있음을 confrim하는 데에 ssh를이 내가 얻고있는 무슨이다 :

[email protected]:~# mount 
none on/type aufs (rw,relatime,si=77b99811b9d139a9) 
/dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /etc/hostname type ext4 (ro,relatime,errors=remount-ro,data=ordered) 
/dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /etc/hosts type ext4 (ro,relatime,errors=remount-ro,data=ordered) 
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime) 
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) 
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k) 
/dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /.dockerinit type ext4 (ro,relatime,errors=remount-ro,data=ordered) 
/dev/disk/by-uuid/7e1d6bab-b3f2-4ac3-8bff-0779f5bf40f2 on /etc/resolv.conf type ext4 (ro,relatime,errors=remount-ro,data=ordered) 
devpts on /dev/tty1 type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000) 
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=666) 
devpts on /dev/ptmx type devpts (rw,relatime,mode=600,ptmxmode=666) 
[email protected]:/home/piotr/helloworld/ on /mnt type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,max_read=65536) 
[email protected]:~# cd /mnt/ 
[email protected]:/mnt# ls 
ls: reading directory .: Input/output error 
[email protected]:/mnt# 

은 "마운트"명령을 보여줍니다 그 mountpoint는 내가 t을 시도 할 때 거기에있다. o 액세스 : ls : 디렉토리 읽기 : 입력/출력 오류

누군가 내가 그 문제를 해결할 수있는 방법을 말해 줄 수 있습니까? 성공하지 못하면서 많은 시간을 보냅니다. 어떤 의견이라도 환영합니다!

테스트 방법 :

먼저 실행 SSHD와 백그라운드에서 컨테이너를 시작해야합니다 : 당신이 실행하고 자신이 지금 테스트 할 수 있도록 내가 대중 저장소에 내 테스트 고정 표시기 컨테이너를 업로드

:

sudo는 고정 표시기 실행 -i -t -privileged -dns = 172.25.0.10 -p (22) -d orobix/sshfs_startup_key2/빈/bash는 -c "/는 sbin에/SSHD -D는/usr"

특권이다 sshfs 퓨즈 시스템이 작동하는 데 필요한, 나는 dns 옵션을 사용한다. 로컬 네트워크에 있기 때문에 내 DNS 서버를 지정하십시오 (필요하지 않음) 공용 저장소에서 이미지 (orobix/ssfs_startuo_key2)를 자동으로 가져와야합니다.

컨테이너가 실행되면 이동 코드를 실행할 수 있어야합니다 (물론 ip 주소는 변경해야합니다).

당신은 예컨대 수동으로 용기에 ssh를 할 수 있습니다 :

ssh [email protected] -p 49153 

다시, IP 및 포트가 다릅니다.

+0

호기심에서 벗어났습니다. 왜 쉘 스크립트 대신 Go를 사용합니까? 쉘 스크립트를 대신 사용하면 어떻게됩니까? IMHO에서 많은 변수가 필요합니다. – jpetazzo

+0

먼저 스크립팅이 좋지 않아서 프로그래밍을 즐깁니다. 멋진 기능은 크로스 컴파일 할 수있는 단일 바이너리 파일 안에 모든 것을 넣을 수 있다는 것입니다. 마지막으로 나보다 bash 경험이 많은 사람이라면 스크립트를 사용하여 설정 파일을 처리하는 것은 꽤 번거롭다. 반면에 설정 파일을 처리하는 것은 매우 간단하다. 그건 위의 코드가 실패하고 그것을 수동으로 일을하고 있기 때문에 나는 지금 bash 스크립트를 사용하여 같은 목표를 달성하려고 노력하고 있다고 말했다. 다행히도 잘될 것입니다! –

+0

이것은 golang-nuts https://groups.google.com/d/msg/golang-nuts/-z106Dt9Qxs/ZfE7AYzTIeMJ에서 물었습니다. PTY 문제로 인한 논의가있는 곳입니다. 테스트 도커 이미지는 https://index.docker.io/u/orobix/sshfs_startup_key2/ –

답변

0

도커 0.8.1을 사용해 본 적이 있습니까? 'tmux'실행시 tty 문제가 해결되었습니다. 아마 당신의 문제도 해결할 수 있습니다.