// formatAndMount uses unix utils to format and mount the given disk func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, fstype string, options []string) error { options = append(options, "defaults") // Run fsck on the disk to fix repairable issues args := []string{"-a", source} cmd := mounter.Runner.Command("fsck", args...) out, err := cmd.CombinedOutput() if err != nil { ee, isExitError := err.(utilExec.ExitError) switch { case err == utilExec.ErrExecutableNotFound: glog.Warningf("'fsck' not found on system; continuing mount without running 'fsck'.") case isExitError && ee.ExitStatus() == fsckErrorsCorrected: glog.Infof("Device %s has errors which were corrected by fsck.", source) case isExitError && ee.ExitStatus() == fsckErrorsUncorrected: return fmt.Errorf("'fsck' found errors on device %s but could not correct them: %s.", source, string(out)) case isExitError && ee.ExitStatus() > fsckErrorsUncorrected: glog.Infof("`fsck` error %s", string(out)) } } // Try to mount the disk err = mounter.Interface.Mount(source, target, fstype, options) if err != nil { // It is possible that this disk is not formatted. Double check using diskLooksUnformatted notFormatted, err := mounter.diskLooksUnformatted(source) if err == nil && notFormatted { args = []string{source} // Disk is unformatted so format it. // Use 'ext4' as the default if len(fstype) == 0 { fstype = "ext4" } if fstype == "ext4" || fstype == "ext3" { args = []string{"-E", "lazy_itable_init=0,lazy_journal_init=0", "-F", source} } cmd := mounter.Runner.Command("mkfs."+fstype, args...) _, err := cmd.CombinedOutput() if err == nil { // the disk has been formatted sucessfully try to mount it again. return mounter.Interface.Mount(source, target, fstype, options) } return err } } return err }
func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { reqInfo := newRequestInfo(req) if rt.levels[debugJustURL] { glog.Infof("%s %s", reqInfo.RequestVerb, reqInfo.RequestURL) } if rt.levels[debugCurlCommand] { glog.Infof("%s", reqInfo.toCurl()) } if rt.levels[debugRequestHeaders] { glog.Infof("Request Headers:") for key, values := range reqInfo.RequestHeaders { for _, value := range values { glog.Infof(" %s: %s", key, value) } } } startTime := time.Now() response, err := rt.delegatedRoundTripper.RoundTrip(req) reqInfo.Duration = time.Since(startTime) reqInfo.complete(response, err) if rt.levels[debugURLTiming] { glog.Infof("%s %s %s in %d milliseconds", reqInfo.RequestVerb, reqInfo.RequestURL, reqInfo.ResponseStatus, reqInfo.Duration.Nanoseconds()/int64(time.Millisecond)) } if rt.levels[debugResponseStatus] { glog.Infof("Response Status: %s in %d milliseconds", reqInfo.ResponseStatus, reqInfo.Duration.Nanoseconds()/int64(time.Millisecond)) } if rt.levels[debugResponseHeaders] { glog.Infof("Response Headers:") for key, values := range reqInfo.ResponseHeaders { for _, value := range values { glog.Infof(" %s: %s", key, value) } } } return response, err }
// getListener creates a listener on the interface targeted by the given hostname on the given port with // the given protocol. protocol is in net.Listen style which basically admits values like tcp, tcp4, tcp6 func (pf *PortForwarder) getListener(protocol string, hostname string, port *ForwardedPort) (net.Listener, error) { listener, err := net.Listen(protocol, fmt.Sprintf("%s:%d", hostname, port.Local)) if err != nil { util.HandleError(fmt.Errorf("Unable to create listener: Error %s", err)) return nil, err } listenerAddress := listener.Addr().String() host, localPort, _ := net.SplitHostPort(listenerAddress) localPortUInt, err := strconv.ParseUint(localPort, 10, 16) if err != nil { return nil, fmt.Errorf("Error parsing local port: %s from %s (%s)", err, listenerAddress, host) } port.Local = uint16(localPortUInt) glog.Infof("Forwarding from %s:%d -> %d", hostname, localPortUInt, port.Remote) return listener, nil }
// handleConnection copies data between the local connection and the stream to // the remote server. func (pf *PortForwarder) handleConnection(conn net.Conn, port ForwardedPort) { defer conn.Close() glog.Infof("Handling connection for %d", port.Local) requestID := pf.nextRequestID() // create error stream headers := http.Header{} headers.Set(api.StreamType, api.StreamTypeError) headers.Set(api.PortHeader, fmt.Sprintf("%d", port.Remote)) headers.Set(api.PortForwardRequestIDHeader, strconv.Itoa(requestID)) errorStream, err := pf.streamConn.CreateStream(headers) if err != nil { util.HandleError(fmt.Errorf("error creating error stream for port %d -> %d: %v", port.Local, port.Remote, err)) return } // we're not writing to this stream errorStream.Close() errorChan := make(chan error) go func() { message, err := ioutil.ReadAll(errorStream) switch { case err != nil: errorChan <- fmt.Errorf("error reading from error stream for port %d -> %d: %v", port.Local, port.Remote, err) case len(message) > 0: errorChan <- fmt.Errorf("an error occurred forwarding %d -> %d: %v", port.Local, port.Remote, string(message)) } close(errorChan) }() // create data stream headers.Set(api.StreamType, api.StreamTypeData) dataStream, err := pf.streamConn.CreateStream(headers) if err != nil { util.HandleError(fmt.Errorf("error creating forwarding stream for port %d -> %d: %v", port.Local, port.Remote, err)) return } localError := make(chan struct{}) remoteDone := make(chan struct{}) go func() { // Copy from the remote side to the local port. if _, err := io.Copy(conn, dataStream); err != nil && !strings.Contains(err.Error(), "use of closed network connection") { util.HandleError(fmt.Errorf("error copying from remote stream to local connection: %v", err)) } // inform the select below that the remote copy is done close(remoteDone) }() go func() { // inform server we're not sending any more data after copy unblocks defer dataStream.Close() // Copy from the local port to the remote side. if _, err := io.Copy(dataStream, conn); err != nil && !strings.Contains(err.Error(), "use of closed network connection") { util.HandleError(fmt.Errorf("error copying from local connection to remote stream: %v", err)) // break out of the select below without waiting for the other copy to finish close(localError) } }() // wait for either a local->remote error or for copying from remote->local to finish select { case <-remoteDone: case <-localError: } // always expect something on errorChan (it may be nil) err = <-errorChan if err != nil { util.HandleError(err) } }