2019-07-31 05:32:02 +02:00
|
|
|
package util
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"os"
|
2019-08-04 00:34:48 +02:00
|
|
|
"os/exec"
|
2019-07-31 05:32:02 +02:00
|
|
|
"os/user"
|
2019-08-04 00:34:48 +02:00
|
|
|
"path/filepath"
|
|
|
|
"strconv"
|
2020-05-19 23:13:01 +02:00
|
|
|
"time"
|
2019-07-31 05:32:02 +02:00
|
|
|
|
2019-10-10 16:50:33 +02:00
|
|
|
"github.com/lbryio/lbry.go/v2/extras/errors"
|
|
|
|
"github.com/lbryio/lbry.go/v2/lbrycrd"
|
2020-06-11 18:45:56 +02:00
|
|
|
"github.com/lbryio/ytsync/v5/timing"
|
2019-08-01 04:42:22 +02:00
|
|
|
|
2019-07-31 05:32:02 +02:00
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/filters"
|
|
|
|
"github.com/docker/docker/client"
|
2019-08-04 00:34:48 +02:00
|
|
|
"github.com/mitchellh/go-ps"
|
2019-08-01 04:42:22 +02:00
|
|
|
log "github.com/sirupsen/logrus"
|
2019-07-31 05:32:02 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func GetBlobsDir() string {
|
|
|
|
blobsDir := os.Getenv("BLOBS_DIRECTORY")
|
|
|
|
if blobsDir == "" {
|
|
|
|
usr, err := user.Current()
|
|
|
|
if err != nil {
|
2019-08-01 04:42:22 +02:00
|
|
|
log.Error(err.Error())
|
2019-07-31 05:32:02 +02:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
blobsDir = usr.HomeDir + "/.lbrynet/blobfiles/"
|
|
|
|
}
|
|
|
|
|
|
|
|
return blobsDir
|
|
|
|
}
|
|
|
|
|
2019-08-01 04:42:22 +02:00
|
|
|
func IsBlobReflectionOff() bool {
|
|
|
|
return os.Getenv("REFLECT_BLOBS") == "false"
|
|
|
|
}
|
|
|
|
|
2019-07-31 05:32:02 +02:00
|
|
|
func GetLBRYNetDir() string {
|
|
|
|
lbrynetDir := os.Getenv("LBRYNET_DIR")
|
|
|
|
if lbrynetDir == "" {
|
|
|
|
usr, err := user.Current()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorln(err.Error())
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return usr.HomeDir + "/.lbrynet/"
|
|
|
|
}
|
|
|
|
return lbrynetDir
|
|
|
|
}
|
|
|
|
|
2020-03-25 17:53:47 +01:00
|
|
|
func GetLbryumDir() string {
|
2020-08-04 00:55:26 +02:00
|
|
|
lbryumDir := os.Getenv("LBRYUM_DIR")
|
2020-03-25 17:53:47 +01:00
|
|
|
if lbryumDir == "" {
|
|
|
|
usr, err := user.Current()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorln(err.Error())
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return usr.HomeDir + "/.lbryum/"
|
|
|
|
}
|
|
|
|
return lbryumDir + "/"
|
|
|
|
}
|
|
|
|
|
2019-08-01 04:42:22 +02:00
|
|
|
const ALL = true
|
|
|
|
const ONLINE = false
|
|
|
|
|
2019-07-31 05:32:02 +02:00
|
|
|
func GetLBRYNetContainer(all bool) (*types.Container, error) {
|
2019-08-01 04:42:22 +02:00
|
|
|
return getDockerContainer("lbrynet", all)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getDockerContainer(name string, all bool) (*types.Container, error) {
|
2019-07-31 05:32:02 +02:00
|
|
|
cli, err := client.NewEnvClient()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
filters := filters.NewArgs()
|
2019-08-01 04:42:22 +02:00
|
|
|
filters.Add("name", name)
|
2019-07-31 05:32:02 +02:00
|
|
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: all, Filters: filters})
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
if len(containers) == 0 {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
if len(containers) > 1 {
|
2019-08-01 04:42:22 +02:00
|
|
|
return nil, errors.Err("more than one %s container found", name)
|
2019-07-31 05:32:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return &containers[0], nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsUsingDocker() bool {
|
2019-08-04 00:34:48 +02:00
|
|
|
useDocker, err := strconv.ParseBool(os.Getenv("LBRYNET_USE_DOCKER"))
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return useDocker
|
2019-07-31 05:32:02 +02:00
|
|
|
}
|
2019-08-01 04:42:22 +02:00
|
|
|
|
|
|
|
func IsRegTest() bool {
|
2019-08-04 00:34:48 +02:00
|
|
|
usesRegtest, err := strconv.ParseBool(os.Getenv("REGTEST"))
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return usesRegtest
|
2019-08-01 04:42:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func GetLbrycrdClient(lbrycrdString string) (*lbrycrd.Client, error) {
|
2020-02-03 07:25:54 +01:00
|
|
|
chainName := os.Getenv("CHAINNAME")
|
|
|
|
chainParams, ok := lbrycrd.ChainParamsMap[chainName]
|
|
|
|
if !ok {
|
|
|
|
chainParams = lbrycrd.MainNetParams
|
|
|
|
}
|
2019-08-01 04:42:22 +02:00
|
|
|
var lbrycrdd *lbrycrd.Client
|
|
|
|
var err error
|
|
|
|
if lbrycrdString == "" {
|
2020-02-03 07:25:54 +01:00
|
|
|
lbrycrdd, err = lbrycrd.NewWithDefaultURL(&chainParams)
|
2019-08-01 04:42:22 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else {
|
2020-02-03 07:25:54 +01:00
|
|
|
lbrycrdd, err = lbrycrd.New(lbrycrdString, &chainParams)
|
2019-08-01 04:42:22 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return lbrycrdd, nil
|
|
|
|
}
|
2019-08-04 00:34:48 +02:00
|
|
|
|
2019-08-13 05:20:09 +02:00
|
|
|
func ShouldCleanOnStartup() bool {
|
2019-08-04 00:34:48 +02:00
|
|
|
shouldClean, err := strconv.ParseBool(os.Getenv("CLEAN_ON_STARTUP"))
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return shouldClean
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsLbrynetRunning() (bool, error) {
|
|
|
|
if IsUsingDocker() {
|
|
|
|
container, err := GetLBRYNetContainer(ONLINE)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
return container != nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
processes, err := ps.Processes()
|
|
|
|
if err != nil {
|
|
|
|
return true, errors.Err(err)
|
|
|
|
}
|
|
|
|
var daemonProcessId = -1
|
|
|
|
for _, p := range processes {
|
|
|
|
if p.Executable() == "lbrynet" {
|
|
|
|
daemonProcessId = p.Pid()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
running := daemonProcessId != -1
|
|
|
|
return running, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func CleanForStartup() error {
|
|
|
|
if !IsRegTest() {
|
|
|
|
return errors.Err("never cleanup wallet outside of regtest and with caution. this should only be done in local testing and requires regtest to be on")
|
|
|
|
}
|
|
|
|
|
|
|
|
running, err := IsLbrynetRunning()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if running {
|
|
|
|
err := StopDaemon()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = CleanupLbrynet()
|
|
|
|
if err != nil {
|
2019-08-11 04:50:43 +02:00
|
|
|
return errors.Err(err)
|
2019-08-04 00:34:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
lbrycrd, err := GetLbrycrdClient(os.Getenv("LBRYCRD_STRING"))
|
|
|
|
if err != nil {
|
|
|
|
return errors.Prefix("error getting lbrycrd client: ", err)
|
|
|
|
}
|
|
|
|
height, err := lbrycrd.GetBlockCount()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
2019-08-28 06:10:54 +02:00
|
|
|
const minBlocksForUTXO = 200
|
2019-08-13 05:20:09 +02:00
|
|
|
if height < minBlocksForUTXO {
|
2019-08-28 06:10:54 +02:00
|
|
|
//Start reg test with some credits
|
|
|
|
txs, err := lbrycrd.Generate(uint32(minBlocksForUTXO) - uint32(height))
|
2019-08-04 00:34:48 +02:00
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
log.Debugf("REGTEST: Generated %d transactions to get some LBC!", len(txs))
|
|
|
|
}
|
|
|
|
|
|
|
|
defaultWalletDir := GetDefaultWalletPath()
|
2019-08-11 04:50:43 +02:00
|
|
|
_, err = os.Stat(defaultWalletDir)
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return errors.Err(os.Remove(defaultWalletDir))
|
2019-08-04 00:34:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func CleanupLbrynet() error {
|
|
|
|
//make sure lbrynet is off
|
|
|
|
running, err := IsLbrynetRunning()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if running {
|
|
|
|
return errors.Prefix("cannot cleanup lbrynet as the daemon is running", err)
|
|
|
|
}
|
|
|
|
lbrynetDir := GetLBRYNetDir()
|
|
|
|
files, err := filepath.Glob(lbrynetDir + "lbrynet.sqlite*")
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
for _, f := range files {
|
|
|
|
err = os.Remove(f)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
blobsDir := GetBlobsDir()
|
|
|
|
err = os.RemoveAll(blobsDir)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
2019-08-11 04:50:43 +02:00
|
|
|
err = os.Mkdir(blobsDir, 0777)
|
2019-08-04 00:34:48 +02:00
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
2020-03-25 17:53:47 +01:00
|
|
|
|
|
|
|
lbryumDir := GetLbryumDir()
|
|
|
|
ledger := "lbc_mainnet"
|
|
|
|
if IsRegTest() {
|
|
|
|
ledger = "lbc_regtest"
|
|
|
|
}
|
2020-03-25 18:12:50 +01:00
|
|
|
lbryumDir = lbryumDir + ledger
|
2020-03-25 17:53:47 +01:00
|
|
|
|
2020-11-19 03:11:23 +01:00
|
|
|
files, err = filepath.Glob(lbryumDir + "/blockchain.db*")
|
2020-03-25 17:53:47 +01:00
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
2020-11-19 03:11:23 +01:00
|
|
|
for _, f := range files {
|
|
|
|
err = os.Remove(f)
|
2020-03-25 17:53:47 +01:00
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
}
|
2019-08-04 00:34:48 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-06-17 17:51:21 +02:00
|
|
|
var metadataDirInitialized = false
|
|
|
|
|
|
|
|
func GetVideoMetadataDir() string {
|
|
|
|
dir := "./videos_metadata"
|
|
|
|
if !metadataDirInitialized {
|
|
|
|
metadataDirInitialized = true
|
|
|
|
_ = os.MkdirAll(dir, 0755)
|
|
|
|
}
|
|
|
|
return dir
|
|
|
|
}
|
|
|
|
|
|
|
|
func CleanupMetadata() error {
|
|
|
|
dir := GetVideoMetadataDir()
|
|
|
|
err := os.RemoveAll(dir)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
metadataDirInitialized = false
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-06-10 03:32:45 +02:00
|
|
|
func SleepUntilQuotaReset() {
|
|
|
|
PST, _ := time.LoadLocation("America/Los_Angeles")
|
|
|
|
t := time.Now().In(PST)
|
|
|
|
n := time.Date(t.Year(), t.Month(), t.Day(), 24, 2, 0, 0, PST)
|
|
|
|
d := n.Sub(t)
|
|
|
|
if d < 0 {
|
|
|
|
n = n.Add(24 * time.Hour)
|
|
|
|
d = n.Sub(t)
|
|
|
|
}
|
|
|
|
log.Infof("gotta sleep %s until the quota resets", d.String())
|
|
|
|
time.Sleep(d)
|
|
|
|
}
|
|
|
|
|
2019-08-04 00:34:48 +02:00
|
|
|
func StartDaemon() error {
|
2020-05-19 23:13:01 +02:00
|
|
|
start := time.Now()
|
|
|
|
defer func(start time.Time) {
|
|
|
|
timing.TimedComponent("startDaemon").Add(time.Since(start))
|
|
|
|
}(start)
|
2019-08-04 00:34:48 +02:00
|
|
|
if IsUsingDocker() {
|
|
|
|
return startDaemonViaDocker()
|
|
|
|
}
|
|
|
|
return startDaemonViaSystemd()
|
|
|
|
}
|
|
|
|
|
|
|
|
func StopDaemon() error {
|
2020-05-19 23:13:01 +02:00
|
|
|
start := time.Now()
|
|
|
|
defer func(start time.Time) {
|
|
|
|
timing.TimedComponent("stopDaemon").Add(time.Since(start))
|
|
|
|
}(start)
|
2019-08-04 00:34:48 +02:00
|
|
|
if IsUsingDocker() {
|
|
|
|
return stopDaemonViaDocker()
|
|
|
|
}
|
|
|
|
return stopDaemonViaSystemd()
|
|
|
|
}
|
|
|
|
|
|
|
|
func startDaemonViaDocker() error {
|
|
|
|
container, err := GetLBRYNetContainer(true)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
cli, err := client.NewEnvClient()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = cli.ContainerStart(context.Background(), container.ID, types.ContainerStartOptions{})
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func stopDaemonViaDocker() error {
|
|
|
|
container, err := GetLBRYNetContainer(ONLINE)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
cli, err := client.NewEnvClient()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = cli.ContainerStop(context.Background(), container.ID, nil)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func startDaemonViaSystemd() error {
|
|
|
|
err := exec.Command("/usr/bin/sudo", "/bin/systemctl", "start", "lbrynet.service").Run()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func stopDaemonViaSystemd() error {
|
|
|
|
err := exec.Command("/usr/bin/sudo", "/bin/systemctl", "stop", "lbrynet.service").Run()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetDefaultWalletPath() string {
|
|
|
|
defaultWalletDir := os.Getenv("HOME") + "/.lbryum/wallets/default_wallet"
|
|
|
|
if IsRegTest() {
|
|
|
|
defaultWalletDir = os.Getenv("HOME") + "/.lbryum_regtest/wallets/default_wallet"
|
|
|
|
}
|
|
|
|
|
2020-08-04 00:55:26 +02:00
|
|
|
walletPath := os.Getenv("LBRYUM_DIR")
|
2019-08-04 00:34:48 +02:00
|
|
|
if walletPath != "" {
|
|
|
|
defaultWalletDir = walletPath + "/wallets/default_wallet"
|
|
|
|
}
|
|
|
|
return defaultWalletDir
|
|
|
|
}
|
2020-08-04 00:55:26 +02:00
|
|
|
func GetBlockchainDBPath() string {
|
|
|
|
lbryumDir := os.Getenv("LBRYUM_DIR")
|
|
|
|
if lbryumDir == "" {
|
|
|
|
if IsRegTest() {
|
|
|
|
lbryumDir = os.Getenv("HOME") + "/.lbryum_regtest"
|
|
|
|
} else {
|
|
|
|
lbryumDir = os.Getenv("HOME") + "/.lbryum"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defaultDB := lbryumDir + "/lbc_mainnet/blockchain.db"
|
|
|
|
if IsRegTest() {
|
|
|
|
defaultDB = lbryumDir + "/lbc_regtest/blockchain.db"
|
|
|
|
}
|
|
|
|
return defaultDB
|
|
|
|
}
|
|
|
|
func GetBlockchainDirectoryName() string {
|
|
|
|
ledger := "lbc_mainnet"
|
|
|
|
if IsRegTest() {
|
|
|
|
ledger = "lbc_regtest"
|
|
|
|
}
|
|
|
|
return ledger
|
|
|
|
}
|
2021-06-17 17:51:21 +02:00
|
|
|
|
|
|
|
func DirSize(path string) (int64, error) {
|
|
|
|
var size int64
|
|
|
|
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !info.IsDir() {
|
|
|
|
size += info.Size()
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
})
|
|
|
|
return size, err
|
|
|
|
}
|