Can not call `vim` within go code - command-line

I try to call vim within go program, which code similar to this:
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
err := exec.Command("vim", "a.txt").Run()
if err != nil {
fmt.Println(err)
}
os.Exit(0)
}
I ran go run mycode.go then got:
exit status 1
I have tried several ways to succeed this e.g. replace Run() by Start(), Output(), ..., but it seems not work. Finally, What I try to do is I try to call vim and stop my current go program. I just want to see vim appear, that's all.

In order for vim to render its interface, you need to attach the standard input/output streams to the process:
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
cmd := exec.Command("vim", "a.txt")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
os.Exit(0)
}
Not attaching the streams is similar to running the following command from your shell:
vim < /dev/null > /dev/null 2> /dev/null

Related

Unable to connect to postgresql using Go and pq

I'm trying to connect a Go application with postgresql.
The app import postgresql driver:
"crypto/tls"
"database/sql"
"fmt"
"log"
"os"
"os/signal"
...
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
and uses like it to connect to the database:
driver, cnxn := dbFromURI(dbURI)
db, err := sql.Open(driver, cnxn)
if err != nil {
panic(err)
}
and the dbFromUri method just split the info
func dbFromURI(uri string) (string, string) {
parts := strings.Split(uri, "://")
return parts[0], parts[1]
}
My URI works locally when i run the command : psql postgresql://user:user#172.20.0.1:5432/lcp
But in go i Go, I got
./lcpserver
2021/03/07 02:00:42 Reading config /root/lcp-server-install/lcp-home/config/config.yaml
panic: pq: SSL is not enabled on the server
I tried this URI for Go without success : psql postgresql://user:user#172.20.0.1:5432/lcp?sslmode=disable
Do you have any idea why i can't connect ?
I tried with my aws rds postgres database, and got same result. Thnaks for the help.
complete code of the server
https://github.com/readium/readium-lcp-server/blob/master/lcpserver/lcpserver.go
I change the typo and the demo provided i succeed the connexion. But in the lcp server i style got the same issue.
postgres://user:user#172.20.0.1:5432/lcp?sslmode=disable
EDIT 2:
The error is due to the fact that the script tries prepare command. I update the minimal example and it fails too.
package main
import (
"database/sql"
"fmt"
"strings"
_ "github.com/lib/pq"
)
func dbFromURI(uri string) (string, string) {
parts := strings.Split(uri, "://")
return parts[0], parts[1]
}
func main() {
driver, cnxn := dbFromURI("postgres://user:user#172.20.0.1:5432/lcp?sslmode=disable")
fmt.Println("The driver " + driver)
fmt.Println("The cnxn " + cnxn)
db, err := sql.Open(driver, cnxn)
_, err = db.Prepare("SELECT id,encryption_key,location,length,sha256,type FROM content WHERE id = ? LIMIT 1")
if err != nil {
fmt.Println("Prepare failed")
fmt.Println(err)
}
if err == nil {
fmt.Println("Successfully connected")
} else {
panic(err)
}
}
I got :
prepare failed
pq: SSL is not enabled on the server
2021/03/07 17:20:13 This panic 3
panic: pq: SSL is not enabled on the server
The first problem is a typo in the connection string: postgresql://user:user#172.20.0.1:5432/lcp?sslmode=disable. In Go code it should be postgres://user:user#172.20.0.1:5432/lcp?sslmode=disable.
We also need to pass the full connection string as the second argument to sql.Open. For now, the dbFromURI function returns user:user#172.20.0.1:5432/lcp?sslmode=disable, but we need postgres://user:user#172.20.0.1:5432/lcp?sslmode=disable, because pq is waiting for this prefix to parse it.
After fixing this, I was able to establish a connection using a minimal postgres client based on your code.
To try this yourself, start the server with the following command:
docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=some_password postgres
And try to connect using the following client code:
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
func main() {
cnxn := "postgres://postgres:some_password#127.0.0.1:5432/lcp?sslmode=disable"
_, err := sql.Open("postgres", cnxn)
if err != nil {
panic(err)
}
_, err = db.Prepare("SELECT id,encryption_key,location,length,sha256,type FROM content WHERE id = ? LIMIT 1")
if err != nil {
fmt.Println("Prepare failed")
panic(err)
}
}

golang-migrate unable to find postgres driver

In my internal/platform/database/database.go
import (
"github.com/golang-migrate/migrate"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
func RunMigrations() error {
m, err := migrate.New(
"file://schema",
"postgres://postgres:postgres#localhost:5432/postgres?sslmode=disable")
if err != nil {
return errors.Wrap(err, "error creating migrations object")
}
This function is invoked from my cmd/my-api/main.go as follows:
import (
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"github.com/myrepo/myproject/internal/platform/database"
)
// =========================================================================
// Executing migrations
if err := database.RunMigrations(); err != nil {
log.Fatal(err)
}
Although I am importing postgres driver in both files, _ "github.com/lib/pq"
running the program fails as follows:
error creating migrations object: source driver: unknown driver file (forgotten import?)
exit status 1
Why is that?
It seems that golang-migrate needs its own version of the corresponding driver (?)
The following import solved it for me
_ "github.com/golang-migrate/migrate/v4/database/postgres"
When you import the following, postgres driver init function triggered and this function register the postgres driver.
_ "github.com/golang-migrate/migrate/v4/database/postgres"
You can inspect this.
https://www.calhoun.io/why-we-import-sql-drivers-with-the-blank-identifier/

Execute powershell command in running container via Docker API

I want to execute a powershell command in a docker container running on a windows host.
The specific command I want to execute is "powershell Get-PSDrive C | Select-Object Used,Free"
I have implemented this using the Docker API for python and it is simple like calling:
cmd = "powershell Get-PSDrive C | Select-Object Used,Free"
output = container.exec_run(cmd)
This works as intended, but I need to implement this in golang.
But somehow, it is not clear for me how to interact with the Docker API for golang. I looked into the API and was confused by the hijackedSession. How do I have to setup the calls for ContainerExecCreate, ContainerExecAttach and ContainerExecStart ?
I expect the golang script to deliver the same results like the python code does:
Used Free
---- ----
199181606912 307151622144
Which then can be parsed by me.
The HijackedResponse struct:
type HijackedResponse struct {
Conn net.Conn
Reader *bufio.Reader
}
You need to copy the response from the resp.Reader,here is my code:
package main
import (
"bytes"
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
"strings"
)
func readFromCommand() (string, error) {
cli, err := client.NewEnvClient()
if err != nil {
return "", err
}
ctx := context.Background()
config := types.ExecConfig{
Cmd: strings.Split("powershell Get-PSDrive C | Select-Object Used,Free", " "),
AttachStdout: true,
AttachStderr: true,
}
response, err := cli.ContainerExecCreate(ctx,
// container id
"cf59d65ab1", config)
if err != nil {
return "", err
}
execID := response.ID
resp, err := cli.ContainerExecAttach(ctx, execID, config)
if err != nil {
return "", err
}
defer resp.Close()
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
_, err = stdcopy.StdCopy(stdout, stderr, resp.Reader)
if err != nil {
return "", err
}
s := stdout.String()
fmt.Println(s)
i := stderr.String()
fmt.Println(i)
return s, nil
}
Do remember to change the container id.

undefined: revel.LoadConfig on revel app start

I was following this tutorial on using Go + Revel + MongoDB. But as I starting the application, I got this error:
The Go code api-go/app/init.go does not compile: undefined: revel.LoadConfig
along with other errors as I look in the terminal.
ERROR 2016/10/18 17:15:06 build.go:108: # api-go/app
api-go/app/init.go:41: undefined: revel.LoadConfig
api-go/app/init.go:43: undefined: log in log.Fatalf
api-go/app/init.go:45: undefined: mongodb in mongodb.MaxPool
api-go/app/init.go:45: cannot assign to mongodb.MaxPool
api-go/app/init.go:46: undefined: mongodb in mongodb.PATH
api-go/app/init.go:46: cannot assign to mongodb.PATH
api-go/app/init.go:47: undefined: mongodb in mongodb.DBNAME
api-go/app/init.go:47: cannot assign to mongodb.DBNAME
api-go/app/init.go:48: undefined: mongodb in mongodb.CheckAndInitServiceConnection
I used Mac Sierra. What's wrong with my application?
Comment this lines:
//Config, err := revel.LoadConfig("app.conf")
//if err != nil || Config == nil {
// log.Fatalf("%+v",err)
//}
As I see your errors I think you should add in your file "init.go" this code
import (
"log"
"github.com/revel/revel"
“myapp/app/models/mongodb”
)
This just under the first line of your init.go whitch contain "package"
Next in your code you have to replace:
revel.LoadConfig("app.conf")
by
revel.config.LoadContext("app.conf",ConfPaths)
where confPaths is the string path to your conf file. In your case it can be:
ConfPaths := "conf/"
or
ConfPaths := ""
That works for me. Imports:
import (
"github.com/melkor217/myapp/app/models/mongodb"
"github.com/revel/config"
"github.com/revel/revel"
"log"
)
Load config:
Config, err := config.LoadContext("app.conf", revel.ConfPaths)

Go writing to socket - invalid argument

Im trying to write to a TCP socket in Go but only receive "invalid argument" with this code:
_, err := conn.Write([]byte("test"))
if err != nil {
fmt.Println(err.Error())
}
Here is a simple sample of what you want to do(maybe?), be aware that you should make a tcp server listen to the port 8999 first before run it
nc -l 8999 #or maybe nc -l -p 8999
code:
package main
import (
"net"
)
func main() {
conn, _ := net.Dial("tcp", "localhost:8999")
conn.Write([]byte("test"))
}
If it's not your question, you should provide more information.