package repositories import ( "context" "git.cesium.pw/niku/virteen/internal/podman/models" "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v4/pkg/bindings" "github.com/containers/podman/v4/pkg/bindings/containers" "github.com/containers/podman/v4/pkg/bindings/images" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/specgen" "github.com/pkg/errors" ) func newPodmanContext() (context.Context, error) { conn, err := bindings.NewConnection(context.Background(), "unix:///run/user/1000/podman/podman.sock") if err != nil { return nil, err } return conn, nil } type PodmanRepository struct { ctx context.Context } func (pcs *PodmanRepository) ListContainers() ([]entities.ListContainer, error) { return containers.List(pcs.ctx, &containers.ListOptions{}) } func (pcs *PodmanRepository) CreateContainer(bp models.ContainerBlueprint) error { pullQuiet := true _, err := images.Pull(pcs.ctx, bp.Image, &images.PullOptions{Quiet: &pullQuiet}) if err != nil { return errors.Wrapf(err, "failed to pull image") } s := specgen.NewSpecGenerator("nginx", false) portMapping := make([]types.PortMapping, len(bp.PortMapping)) for i, pm := range bp.PortMapping { portMapping[i] = types.PortMapping{ContainerPort: pm.ContainerPort, HostPort: pm.HostPort} } s.ContainerNetworkConfig.PortMappings = append(s.ContainerNetworkConfig.PortMappings, portMapping...) createResponse, err := containers.CreateWithSpec(pcs.ctx, s, nil) if err != nil { return errors.Wrapf(err, "failed to create spec") } if err := containers.Start(pcs.ctx, createResponse.ID, nil); err != nil { return errors.Wrapf(err, "failed to start container") } return nil } func (pcs *PodmanRepository) UpdateContainerStatus(name string, state models.ContainerStatus) error { switch state { case models.StopContainer: return containers.Stop(pcs.ctx, name, nil) case models.StartContainer: return containers.Start(pcs.ctx, name, nil) case models.RestartContainer: return containers.Restart(pcs.ctx, name, nil) default: return nil } } func (pcs *PodmanRepository) DeleteContainer(name string) error { err := pcs.UpdateContainerStatus(name, models.StopContainer) if err != nil { return err } _, err = containers.Remove(pcs.ctx, name, nil) if err != nil { return err } return err } func NewPodmanRepository() (*PodmanRepository, error) { ctx, err := newPodmanContext() if err != nil { return nil, err } return &PodmanRepository{ctx: ctx}, nil }