Is it possible to view files in stored in a Volume?

Hey! I’m looking to deploy a Go app to Fly, and attach a tiny volume (like 1gb) to it to persist a .db file. I’ve looked around the docs, and haven’t been able to find if I would be able to access the volume via command line (or otherwise).

If not, I can always write an export endpoint, but it would be convenient to poke around the db using something like bolter :slight_smile:

The simplest way to do this is just to ssh to your container: fly ssh console or even fly ssh console -C "bolter ..."

We don’t have any way of reading volume data from outside VMs, though, so either SSH or an export service are the way to go.

fly ssh console perfect! Didn’t know this existed :slight_smile:

Thanks @kurt!

1 Like

Hey @kurt , sorry for the necro.

I’m having a hell of a time accessing my volumes contents.

Given the below, I trust that the volume is being attached.

2021-08-24T17:45:44Z [info] Mounting /dev/vdc at /data

I am taking the volume “borp” and mounting it to “/data”, so far so good.

[mounts]
  source = "borp"
  destination = "/data"
	if _, err := os.Stat("data"); os.IsNotExist(err) {
		// path/to/whatever does not exist
		println("no data")
	}

This prints “no data”, it cannot find the volume. I tried ...Stat("/data") which seems to work, but i still end with a panic down the line. In addition, the behaviour is different when i run locally, the path /data doesnt work, data does.

Here is a small, but full excerpt of the function trying to access a file in the volume-

func PrepareDatabase() {
	if _, err := os.Stat("data"); os.IsNotExist(err) {
		// path/to/whatever does not exist
		println("no data")
	}

    // create sqlite db in volume if not exist
	os.OpenFile("data/sql.db", os.O_CREATE, 0666)
	
	if error != nil {
		log.Println("error creating db file", error)
	}

	database, error := sql.Open("sqlite3", "data/sql.db")
	if error != nil {
		log.Println(error)
	}
	defer database.Close()

	createStmt, createErr := database.Prepare("CREATE TABLE IF NOT EXISTS totals ( " +
		"name	TEXT," +
		"count	INTEGER," +
		"PRIMARY KEY('name')" +
		")")
	createStmt.Exec()

	if createErr != nil {
		println(createErr)
	}

	for key := range fields {
		log.Print(key)
		statement, _ := database.Prepare("INSERT into totals (name, count) VALUES (?, ?)")
		statement.Exec(key, 0)
        // ^^^ calling exec here is where the app panics
	}
}

I’m a Frontend Eng trying to learn, so there might be an obvious finding here :sweat_smile:

Are you able to see anything in /data when you ssh into a VM?

I don’t think 6 days counts as necro. :wink:

Will you try printing out your working directory? You can probably check your Dockerfile to find it, but here’s some Go:

path, err := os.Getwd()
if err != nil {
    log.Println(err)
}
fmt.Println(path)  // for example /home/user

I’m betting data is a different directory than /data. It’s weird that data works locally, though, unless it’s getting mounted somehow.

@michael when sshing into /data, I can see

# cd data
# ls
lost+found  sql.db
#

I created sql.db manually, as the programmatic creation kept panic-ing on me (couldn’t find the directory).

@kurt the working directory seems to be /workspace based on the logging you suggested.

I think you need to make the path absolute, like this

	if _, err := os.Stat("/data"); os.IsNotExist(err) {
		// path/to/whatever does not exist
		println("no data")
	}

The current directory is probably not / which is why data isn’t found.

Right, okay, i think im piecing it together now. Given that the pwd is /workspace, and the volume is mounted to data i would have to use a path like ../data/[..]

1 Like

The volume is mounted at /data in the root, so you don’t need anything else before the first slash since it’ll always be at /data

1 Like

Gotcha. Looks like the absolute path is working :tada:

Its the Exec being called in range that is getting a null pointer reference. I don’t expect you guys to know whats going on there so I can take this offline.

Thanks for the help, again :smiley:

2 Likes