jkawamoto/roadie

View on GitHub
cloud/azure/instance.go

Summary

Maintainability
A
1 hr
Test Coverage
//
// cloud/azure/instance_manager.go
//
// Copyright (c) 2016-2017 Junpei Kawamoto
//
// This file is part of Roadie.
//
// Roadie is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Roadie is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Roadie.  If not, see <http://www.gnu.org/licenses/>.
//

package azure

import (
    "context"
    "fmt"
    "log"
    "strings"

    "github.com/jkawamoto/roadie/cloud"
    "github.com/jkawamoto/roadie/script"
)

// InstanceManager implements cloud.InstanceManager interface to run a script
// on Azure.
type InstanceManager struct {
    service *BatchService
    Config  *Config
    Logger  *log.Logger
}

// NewInstanceManager creates a new instance manager.
func NewInstanceManager(ctx context.Context, cfg *Config, logger *log.Logger) (m *InstanceManager, err error) {

    service, err := NewBatchService(ctx, cfg, logger)
    if err != nil {
        return
    }

    m = &InstanceManager{
        service: service,
        Config:  cfg,
        Logger:  logger,
    }
    return

}

// CreateInstance creates an instance which has a given name.
func (m *InstanceManager) CreateInstance(ctx context.Context, task *script.Script) (err error) {

    err = m.service.CreateJob(ctx, task.Name)
    if err != nil {
        return
    }

    err = m.service.CreateTask(ctx, task.Name, task)
    if err != nil {
        m.service.DeleteJob(ctx, task.Name)
    }
    return

}

// DeleteInstance deletes the given named instance.
func (m *InstanceManager) DeleteInstance(ctx context.Context, name string) error {

    return m.service.DeleteJob(ctx, name)

}

// Instances returns a list of running instances
func (m *InstanceManager) Instances(ctx context.Context, handler cloud.InstanceHandler) (err error) {

    jobs, err := m.service.Jobs(ctx)
    if err != nil {
        return
    }

    for name, info := range jobs {
        // If name has the queue prefix, omit it.
        if strings.HasPrefix(name, QueuePrefix) {
            continue
        }

        state := info.State
        if pool, err2 := m.service.GetPoolInfo(ctx, info.ExecutionInfo.PoolID); err2 != nil {
            state += " (0 instances)"
        } else {
            state += fmt.Sprintf(" (%v instances)", pool.CurrentDedicated)
        }
        err = handler(name, state)
        if err != nil {
            return
        }
    }
    return

}

// AvailableRegions returns a list of available regions.
func (m *InstanceManager) AvailableRegions(ctx context.Context) (regions []cloud.Region, err error) {

    m.Logger.Println("Retrieving available regions")
    regions, err = Locations(ctx, &m.Config.Token, m.Config.SubscriptionID)
    if err != nil {
        m.Logger.Println("Cannot retrieve available regions")
    } else {
        m.Logger.Println("Retrieved available regions")
    }
    return

}

// AvailableMachineTypes returns a list of available machine types.
func (m *InstanceManager) AvailableMachineTypes(ctx context.Context) (types []cloud.MachineType, err error) {
    return m.service.AvailableMachineTypes(ctx)
}