使用Go Cloud开发套件将exec stdout传递到s3存储桶时,Alrno Linux Docker映像上的Errno 32管道破裂

时间:2019-05-25 09:40:44

标签: mysql go alpine go-cdk

我写了一个小实用程序,将mysqldump命令的输出传递到golang中的s3存储桶,我打算用它在端到端测试环境中快照和还原数据库。当我在本地运行此命令时,一切都按预期工作:该实用程序将mysqldump输出正确地管道传输到s3存储桶。但是,在Alpine Linux Docker映像中运行时,出现了管道破裂错误。然后,该实用程序将一个空文件发送到s3存储桶。

要执行mysqldump,我只需使用exec包。 mysqldump的代码:

func (conf *MySQLConfig) DumpDatabases(stdout io.Writer) error {
    args := []string{"-u", conf.User, fmt.Sprintf("--password=%s", conf.Password), "-h", conf.Host, "--databases"}
    args = append(args, conf.Databases...)
    cmd := exec.Command("mysqldump", args...)

    cmd.Stdout = stdout
    cmd.Stderr = os.Stderr

    err := cmd.Start()
    if err != nil {
        return err
    }
    cmd.Wait()

    return nil
}

上传到S3存储桶的过程使用go-cdk。它期望一个函数,该函数期望一个io.Writer作为输入并返回一个error。在这种情况下,将执行以下代码片段,将mysqldump的输出传递给s3:

bucket.Upload(func(w io.Writer) error { return mysqlConf.DumpDatabases(w) })

上传代码:

func (b *Bucket) Upload(writeFunc func(io.Writer) error) error {
    // Open a connection to the bucket.
    ctx := context.Background()

    bucket, err := blob.OpenBucket(ctx, b.Url)

    if err != nil {
        return err
    }
    defer bucket.Close()

    // Add encryption header
    beforeWrite := func(asFunc func(interface{}) bool) error {
        var input *s3manager.UploadInput
        if asFunc(&input) {
            input.ServerSideEncryption = aws.String("AES256")
        }
        return nil
    }

    opts := &blob.WriterOptions{}
    opts.BeforeWrite = beforeWrite

    w, err := bucket.NewWriter(ctx, generateKey(), opts)
    if err != nil {
        return err
    }

    err = writeFunc(w)
    if err != nil {
        return err
    }

    if err := w.Close(); err != nil {
        return err
    }

    return nil
}

在Alpine Linux上运行此代码时,为什么它在本地正常工作,但为什么会出现管道错误的提示?关于如何调试此问题以找出实际情况的任何建议?我应该利用缓冲的IO吗?

0 个答案:

没有答案