<commit_before>package clients

import (
	"context"
	"fmt"
	"log"

	"github.com/boltdb/bolt"
	"github.com/docker/docker/api/types/container"
	"github.com/moby/moby/client"
)

// Docker struct to manage all CryutoDev action with Docker
type Docker struct {
	Client *client.Client
}

var images = map[string]string{
	"bitcoin":  "heraware/bitcoin:latest",
	"litecoin": "heraware/litecoin:latest",
}

// NewDockerClient Return a Docker instance with Docker client
// configured from OS ENV
func NewDockerClient() *Docker {
	client, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}
	docker := Docker{Client: client}
	return &docker
}

func (d *Docker) getContainerInfo(containerName string) ([]byte, error) {
	var result []byte
	if err := DB.View(func(tx *bolt.Tx) error {
		txBucket := tx.Bucket([]byte("containers"))
		if txBucket == nil {
			return fmt.Errorf("Bucket doesn't exists")
		}
		result = txBucket.Get([]byte(containerName))
		return nil
	}); err != nil {
		return nil, err
	}
	return result, nil
}

func (d *Docker) saveContainerInfo(containerName string, containerID string) error {
	if err := DB.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte("containers"))
		if err != nil {
			return err
		}
		if err := b.Put([]byte(containerName), []byte(containerID)); err != nil {
			return err
		}
		return nil
	}); err != nil {
		return err
	}
	return nil
}

func (d *Docker) containerExists(containerName string) bool {
	_, err := d.getContainerInfo(containerName)
	if err != nil {
		return false
	}
	return true
}

func (d *Docker) createAndRunContainer(name string, image string) *container.ContainerCreateCreatedBody {
	containerName := fmt.Sprintf("cryptodev-%s", name)
	if d.containerExists(containerName) {
		log.Fatalf("Container: %s already exists", containerName)
	}
	containerConfig := container.Config{
		Image: images[name],
	}
	containerBody, err := d.Client.ContainerCreate(context.Background(), &containerConfig, nil, nil, containerName)
	if err != nil {
		panic(err)
	}
	d.saveContainerInfo(containerName, containerBody.ID)
	return &containerBody
}

// CreateNode create a container with the cryptocurrency client
func (d *Docker) CreateNode(name string) {
	d.createAndRunContainer(name, images[name])
}<commit_msg>Add runContainer, deleteContainerInfo and RunNode functions<commit_after>package clients

import (
	"context"
	"fmt"
	"log"

	"github.com/boltdb/bolt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/moby/moby/client"
)

// Docker struct to manage all CryutoDev action with Docker
type Docker struct {
	Client *client.Client
}

var images = map[string]string{
	"bitcoin":  "heraware/bitcoin:latest",
	"litecoin": "heraware/litecoin:latest",
}

// NewDockerClient Return a Docker instance with Docker client
// configured from OS ENV
func NewDockerClient() *Docker {
	client, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}
	docker := Docker{Client: client}
	return &docker
}

func (d *Docker) getContainerInfo(containerName string) ([]byte, error) {
	var result []byte
	if err := DB.View(func(tx *bolt.Tx) error {
		txBucket := tx.Bucket([]byte("containers"))
		if txBucket == nil {
			return fmt.Errorf("Bucket doesn't exists")
		}
		result = txBucket.Get([]byte(containerName))
		return nil
	}); err != nil {
		return nil, err
	}
	return result, nil
}

func (d *Docker) deleteContainerInfo(containerName string) error {
	return DB.Update(func(tx *bolt.Tx) error {
		txBucket := tx.Bucket([]byte("containers"))
		if txBucket == nil {
			return fmt.Errorf("Bucket doesn't exists")
		}
		return txBucket.Delete([]byte(containerName))
	})
}

func (d *Docker) saveContainerInfo(containerName string, containerID string) error {
	if err := DB.Update(func(tx *bolt.Tx) error {
		b, err := tx.CreateBucketIfNotExists([]byte("containers"))
		if err != nil {
			return err
		}
		if err := b.Put([]byte(containerName), []byte(containerID)); err != nil {
			return err
		}
		return nil
	}); err != nil {
		return err
	}
	return nil
}

func (d *Docker) containerExists(containerName string) bool {
	value, err := d.getContainerInfo(containerName)
	if err != nil {
		return false
	}
	if len(value) == 0 {
		return false
	}
	return true
}

func (d *Docker) runContainer(containerID string) error {
	return d.Client.ContainerStart(context.Background(), containerID, types.ContainerStartOptions{})
}

func (d *Docker) createAndRunContainer(name string, image string) {
	containerName := fmt.Sprintf("cryptodev-%s", name)
	if d.containerExists(containerName) {
		log.Fatalf("Container: %s already exists", containerName)
	}
	containerConfig := container.Config{
		Image: images[name],
	}
	containerBody, err := d.Client.ContainerCreate(context.Background(), &containerConfig, nil, nil, containerName)
	if err != nil {
		panic(err)
	}
	d.saveContainerInfo(containerName, containerBody.ID)
	if err := d.runContainer(containerBody.ID); err != nil {
		panic(err)
	}
	fmt.Println(fmt.Sprintf("Node: %s is created and running - Container ID: %s", containerName, containerBody.ID))
}

// CreateNode create a container with the cryptocurrency client
func (d *Docker) CreateNode(name string) {
	d.createAndRunContainer(name, images[name])
}

func (d *Docker) RunNode(name string) {
	containerName := fmt.Sprintf("cryptodev-%s", name)
	containerID, err := d.getContainerInfo(containerName)
	if err != nil {
		panic(err)
	}
	containerIDString := string(containerID)
	err = d.runContainer(containerIDString)
	if err != nil {
		fmt.Println(d.deleteContainerInfo(containerName))
		log.Fatalf("Container: %s doesn't exists, try to run `cryptodev create %s`", containerName, name)
	}
	fmt.Println(fmt.Sprintf("Node: %s is running - Container ID: %s", containerName, containerIDString))
}
{'fraction_non_alphanumeric': 0.13603448275862068, 'fraction_numerical': 0.00017241379310344826, 'mean_word_length': 4.754960317460317, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2309448', 'n_tokens_mistral': 2001, 'n_tokens_neox': 1899, 'n_words': 495}