cloud storage: unable to upload any content while local with golang - go

I have this piece of code:
ctx:=context.Background()
cliente, err := storage.NewClient(ctx)
if err != nil {
log.Fatal(err)
}
clienteCS := cliente.Bucket("prueba123456789")
w:=clienteCS.Object("prueba").NewWriter(ctx)
w.ContentType = "text/plain"
if _, err := w.Write([]byte("abcde\n")); err != nil {
log.Fatal(err)
}
attrs, err := clienteCS.Attrs(ctx)
fmt.Printf("atrr: %+v err:%v\n",attrs,err)
When I run this program, in the console I can see the attributes printed from my bucket, that would mean for me that there is nothing wrong with the configuration
, but the problem is that when I see on console.cloud.google.com I see no file on my bucket even on api dashboard does not seem like any api has been called(that peak before the red line is other api I was using) , even though no error is showing on my console that could indicate something went wrong

I just forgot about closing the client, this page alert this problem, always must close the client or the file won't be send, so just need to add some lines:
if err := w.Close(); err != nil {
log.Fatal(err)
return
}

Related

Golang windows service not writting to logfile

I have a simple TCP-server written in Go and running as windows service. It installs/uninstalls just fine, it is working as service and doing it's job but it's not writing a single word in a log file. When I run it simply as an executable in a console - logging works fine. But when it starts as a service - log file is created, application process opens it (thus disallowing to delete it for example) but file remains empty. What I'm doing wrong?
Any word of advice is appreciated.
logging is confured like this
func (p *Program) run() {
exec, _ := os.Executable()
WORK_DIR = filepath.Join(filepath.Dir(exec), "ATT")
_, err := checkDir(WORK_DIR)
if err != nil {
panic("Не удалось создать рабочий каталог")
}
f, err := os.OpenFile(filepath.Join(filepath.Dir(exec), "server.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Не удалось создать лог-файл: %v", err)
}
defer f.Close()
wrt := io.MultiWriter(os.Stdout, f)
log.SetOutput(wrt)
server, err := net.Listen("tcp", ":"+PORT)
if err != nil {
log.Fatal(err)
}
defer server.Close()
log.Println("Сервер запущен на порту:", PORT)
for {
connection, err := server.Accept()
if err != nil {
log.Println("Не удалось установить соединение с клиентом", err)
}
go HandleServer(connection)
}
}
The issue you're encountering with logging can be related to file permissions when running as a service. When a service starts, it runs with a different set of permissions than when it runs as a regular executable. In some cases, the service might not have permission to write to a log file in the same location as the executable.
One possible solution is to specify a different location for the log file, such as C:\Windows\System32\LogFiles, which is a common location for log files in Windows. You could also try specifying the absolute path to the log file in the OpenFile call to avoid any confusion about the working directory.
Another potential issue could be with the defer statement that closes the log file. When the service terminates, any deferred statements will be executed, which could cause the log file to be closed before all log messages have been written. To avoid this, you could remove the defer statement and manually close the log file when the service stops.
It may also be a good idea to add error handling to the logging calls to ensure that all log messages are being written even if the log file becomes unavailable. Here is an example:
func (p *Program) run() {
exec, _ := os.Executable()
WORK_DIR = filepath.Join(filepath.Dir(exec), "ATT")
_, err := checkDir(WORK_DIR)
if err != nil {
panic("Не удалось создать рабочий каталог")
}
// Specify the absolute path for the log file
logFilePath := filepath.Join(filepath.Dir(exec), "server.log")
f, err := os.OpenFile(logFilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("Не удалось создать лог-файл: %v", err)
}
// Remove the defer statement to close the log file manually later
// defer f.Close()
wrt := io.MultiWriter(os.Stdout, f)
log.SetOutput(wrt)
server, err := net.Listen("tcp", ":"+PORT)
if err != nil {
log.Fatal(err)
}
defer server.Close()
log.Println("Сервер запущен на порту:", PORT)
for {
connection, err := server.Accept()
if err != nil {
log.Println("Не удалось установить соединение с клиентом", err)
}
go HandleServer(connection)
}
// Manually close the log file when the service stops
f.Close()
}
// Add error handling to the logging calls
func logMessage(message string) {
_, logErr := log.Println(message)
if logErr != nil {
fmt.Printf("Error logging message: %v\n", logErr)
}
}
I hope these suggestions help you resolve the issue with logging in your service. Please let me know.

File has no content after downloading xlsx file using http/net

I tried downloading an Excel file from a URL using http/net by calling the GET method. I don't know if this is releveant, but as for my case, I use dropbox to store the file on the cloud (it's open for public, not restricted, it can be accessed on incognito).
But when I open the file that's saved on the local, it has no content at all. It has just an empty sheet. The file is supposed to have filled with lots of data in cell.
What's happening here? Anyone knows how to solve it? There's no error at all when I print it.
func main() {
filePath := "./file/filename.xlsx"
url := "http://www.dropbox.com/somethingsomething.xlsx"
out, err := os.Create(filePath)
if err != nil {
fmt.Println(err)
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
fmt.Println(err)
}
return
}
Does the dropbox URL have dl=0 query param?
If so, try changing it to dl=1 to force download the file.
I tried the same with one of my files and it worked.
Thanks!

Open a Micrsoft DFS share in golang using smb2

I have a dfs share on Windows server 2012. I can open the share and read files from another system in a windows file explorer with a path like: \\dfsserver\usernamepace\Tom\go.png. However, using golang's smb2 package by https://github.com/hirochachacha/go-smb2 I get an error as
response error: The contacted server does not support the indicated
part of the DFS namespace
But if I try to open the file with it's actual share path \\dfsserver\public share\Tom\go.png then the code works fine. So the problem is that I have no knowledge of the actual path during runtime and I want to be able to open the file with path provided by DFS.
Could it be the case that DFS does not work properly with smb2? or some other issues. Thanks in advance for your comments.
func main(){
// actualPath := `\\dfsserver\public share\Tom\go.png`
// dfsPath := `\\dfsserver\usernamespace\Tom\go.png`
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", "dfsserver", "445"))
if err != nil {
fmt.Println(err)
}
defer conn.Close()
dial := &smb2.Dialer{
Initiator: &smb2.NTLMInitiator{
User: "user",
Password: "password",
Domain: "dfsserver",
},
}
session, err := dial.Dial(conn)
if err != nil {
fmt.Println(err)
}
defer session.Logoff()
mountPoint, err := session.Mount("usernamespace")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// error occures here, if the mountPoint was "public share" instead of "usernamespace" then no error
remoteFile, err := mountPoint.Open(`Tom\go.png`)
defer remoteFile.Close()
if err != nil {
fmt.Println(err)
}
}

http.Post in go not working?

I'm trying to hit a file upload API with this bit of go code in a cli tool. The post doesn't seem to even hit the server, but this code runs with no error, and the result message is an empty string.
curl works.
Other Posts work.
Any advice?
file, err := os.Open(c.Args().Get(0))
if err != nil {
exitErr(err)
}
defer file.Close()
fmt.Print("About to upload file ", c.Args().Get(0), "\n");
res, err := http.Post(fmt.Sprintf("%s/upload", config.Host), "application/octet-stream", file)
if err != nil {
exitErr(err)
}
defer res.Body.Close()
message, err := ioutil.ReadAll(res.Body)
if err != nil {
exitErr(err)
}
fmt.Print("Uploaded result: ", string(message), "\n")
Thanks for the pointers. I never thought to check the status code. I was getting a 307 (Temporary Redirect), not 200. My solution is to loop around, following 'location', up to a max redirect count. I've read that the default http client code in go follows redirects, so I'm a little surprised that I have to do this. Both go and http programming are new to me, and I appreciate the help!

SFTP In Go Error: User does not have appropriate read permission

I am trying to upload a product feed to a Google Merchant SFTP account. I am able to upload a file manually through the command prompt but encounter the following error when trying to do it through Go.
Error: sftp: "User does not have appropriate read permission." (SSH_FX_PERMISSION_DENIED)
I am using the github.com/pkg/sftp package, following the example in https://godoc.org/github.com/pkg/sftp#Client.Open. I suspect that the Create/Write pattern here ends up being different from a simple put from command line.
Code
func (g *GoogleExporter) ExportToSFTP(file []byte) error {
// Creating an SSH connection
sshConfig := &ssh.ClientConfig{
User: g.Creds.AccessData.SFTPUser,
Auth: []ssh.AuthMethod{
ssh.Password(g.Creds.AccessData.SFTPPassword),
},
}
hostPort := fmt.Sprintf("%s:%d", SFTPHostName, SFTPHostPort)
connection, err := ssh.Dial("tcp", hostPort, sshConfig)
if err != nil {
return err
}
fmt.Println(">> SSH Connection Created!")
// Creating an SFPT connection over SSH
sftp, err := sftp.NewClient(connection)
if err != nil {
return err
}
defer sftp.Close()
fmt.Println(">> SFTP Client Created!")
// Uploading the file
remoteFileName := "products.xml" // TODO: Make this name configurable
remoteFile, err := sftp.Create(remoteFileName)
if err != nil {
return err
}
fmt.Println(">> SFTP File Created!")
if _, err := remoteFile.Write(file); err != nil {
return err
}
fmt.Println("Successfully uploaded product feed to SFTP, file:%s user:%s", remoteFileName, g.Creds.AccessData.SFTPUser)
util.Log("Successfully uploaded product feed to SFTP, file:%s user:%s", remoteFileName, g.Creds.AccessData.SFTPUser)
// Confirming if the file is there
if _, err := sftp.Lstat(remoteFileName); err != nil {
return err
}
return nil
}
The error is cause by this line:
remoteFile, err := sftp.Create(remoteFileName)
I am answering my own question to help anyone else that is having this problem. I was able to find a solution.
The Google Merchant SFTP account only gives you write only access. However, according to the docs, when using the sftp.Create(..) function, it creates a file with the flags as 0666, which does not agree with the permissions set on your user.
To mimic the behavior of sftp.Create(..) with write only permissions, you can use the more general sftp.OpenFile(..) function.
remoteFile, err := sftp.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
The flags os.O_WRONLY|os.O_CREATE|os.O_TRUNC will mimic the behavior of Create() i.e. create a file it doesn't exist and truncate the file if it does.

Resources