grim/convey
Clone
Summary
Browse
Changes
Graph
Added tag v0.10.1 for changeset 6fcf770a1b72
2017-09-26, Gary Kramlich
7fd7299d950f
Added tag v0.10.1 for changeset 6fcf770a1b72
/*
* Convey
* Copyright 2016-2017 Gary Kramlich <grim@reaperworld.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package
main
import
(
"fmt"
"os"
"strings"
"github.com/alecthomas/kingpin"
"github.com/aphistic/gomol"
"bitbucket.org/rw_grim/convey/config"
"bitbucket.org/rw_grim/convey/environment"
"bitbucket.org/rw_grim/convey/loaders/bitbucket"
"bitbucket.org/rw_grim/convey/loaders/convey"
"bitbucket.org/rw_grim/convey/logging"
"bitbucket.org/rw_grim/convey/runners"
"bitbucket.org/rw_grim/convey/ssh"
"bitbucket.org/rw_grim/convey/state"
)
const
(
version
=
"0.10.1"
)
var
(
app
=
kingpin
.
New
(
"convey"
,
"container runner"
).
Version
(
version
)
color
=
app
.
Flag
(
"color"
,
"Enable colorized output"
).
Default
(
"true"
).
Bool
()
configLoader
=
app
.
Flag
(
"config-loader"
,
"Select the configuration loader"
).
Short
(
'l'
).
Default
(
"convey"
).
Enum
(
"convey"
,
"bitbucket"
)
configFile
=
app
.
Flag
(
"config"
,
"The config file name to use"
).
Short
(
'f'
).
String
()
cpuShares
=
app
.
Flag
(
"cpu-shares"
,
"The amount of cpu shares to give to a run task"
).
Short
(
'c'
).
String
()
dockerConfig
=
app
.
Flag
(
"docker-config"
,
"Location of docker client config files"
).
String
()
env
=
app
.
Flag
(
"env"
,
"Set environment variables"
).
Short
(
'e'
).
Strings
()
forceSequential
=
app
.
Flag
(
"force-sequential"
,
"Don't run anything concurrently"
).
Short
(
'S'
).
Default
(
"False"
).
Bool
()
graphviz
=
app
.
Flag
(
"graphviz"
,
"Output a graphviz diagram of the config file"
).
Short
(
'g'
).
Default
(
"False"
).
Bool
()
keep
=
app
.
Flag
(
"keep"
,
"Keep the workspace volume"
).
Short
(
'k'
).
Hidden
().
Default
(
"False"
).
Bool
()
listTasks
=
app
.
Flag
(
"list-tasks"
,
"List the supported tasks"
).
Short
(
'L'
).
Default
(
"false"
).
Bool
()
listMetaPlans
=
app
.
Flag
(
"list-meta-plans"
,
"List the meta plans that are available"
).
Short
(
'M'
).
Default
(
"false"
).
Bool
()
listPlans
=
app
.
Flag
(
"list-plans"
,
"List the plans that are available"
).
Short
(
'P'
).
Default
(
"false"
).
Bool
()
memory
=
app
.
Flag
(
"memory"
,
"The ammount of memor to give the run task"
).
Short
(
'm'
).
String
()
showConfig
=
app
.
Flag
(
"show-config"
,
"Show a dump of the config file"
).
Short
(
'C'
).
Hidden
().
Default
(
"false"
).
Bool
()
sshAgent
=
app
.
Flag
(
"ssh-agent"
,
"A shortcut for --ssh-identity=*"
).
Default
(
"false"
).
Bool
()
sshIdentities
=
app
.
Flag
(
"ssh-identity"
,
"Enable ssh-agent for the given identities"
).
Strings
()
taskTimeout
=
app
.
Flag
(
"timeout"
,
"The maximum amount of time a task can run. 0 to disable. Units must be specified."
).
Default
(
"15m"
).
Duration
()
verbose
=
app
.
Flag
(
"verbose"
,
"Be more verbose"
).
Short
(
'v'
).
Default
(
"False"
).
Bool
()
planNames
=
app
.
Arg
(
"plan"
,
"The plan or list of plans to run in specified order"
).
Strings
()
)
func
main
()
{
exitCode
:=
0
defer
func
()
{
os
.
Exit
(
exitCode
)
}()
app
.
Parse
(
os
.
Args
[
1
:])
// now load the config
var
loader
config
.
Loader
switch
*
configLoader
{
case
"convey"
:
loader
=
&
convey
.
Loader
{}
case
"bitbucket"
:
loader
=
&
bitbucket
.
Loader
{}
}
// if a config file was not provided search for the loader's default file
if
*
configFile
==
""
{
for
_
,
filename
:=
range
loader
.
Filenames
()
{
if
_
,
err
:=
os
.
Stat
(
filename
);
os
.
IsNotExist
(
err
)
{
continue
}
*
configFile
=
filename
break
}
}
// now make sure we found a config file
if
*
configFile
==
""
{
fmt
.
Printf
(
"config file not found, looking for %s\n"
,
strings
.
Join
(
loader
.
Filenames
(),
","
))
os
.
Exit
(
1
)
}
cfg
,
err
:=
config
.
LoadFile
(
*
configFile
,
loader
)
if
err
!=
nil
{
fmt
.
Printf
(
"%s\n"
,
err
)
os
.
Exit
(
1
)
}
// setup logging
if
err
:=
logging
.
Setup
(
*
color
,
*
verbose
);
err
!=
nil
{
fmt
.
Printf
(
"failed to setup logging: %s\n"
,
err
)
os
.
Exit
(
1
)
}
defer
gomol
.
ShutdownLoggers
()
// find our default environment variables and then update them with the
// values from the command line
defEnv
:=
environment
.
Initialize
()
// if the user specified the shortcut, add * to the list of acceptable keys
if
*
sshAgent
{
*
sshIdentities
=
append
(
*
sshIdentities
,
"*"
)
}
// now merge in the keys from the config
*
sshIdentities
=
append
(
*
sshIdentities
,
cfg
.
SSHIdentities
...
)
// now check if we have any keys and make sure one of them is usable
enableSSHAgent
,
err
:=
ssh
.
ShouldEnable
(
*
sshIdentities
)
if
err
!=
nil
{
fmt
.
Printf
(
"%s\n"
,
err
)
os
.
Exit
(
1
)
}
st
:=
&
state
.
State
{
KeepWorkspace
:
*
keep
,
ForceSequential
:
*
forceSequential
,
EnableSSHAgent
:
enableSSHAgent
,
TaskTimeout
:
*
taskTimeout
,
Environment
:
environment
.
Merge
(
defEnv
,
*
env
),
DockerConfig
:
*
dockerConfig
,
CPUShares
:
*
cpuShares
,
Memory
:
*
memory
,
}
if
err
:=
st
.
Valid
();
err
!=
nil
{
fmt
.
Printf
(
"%s\n"
,
err
)
exitCode
=
1
return
}
var
runner
runners
.
Runner
if
*
graphviz
{
runner
=
&
runners
.
Graphviz
{}
}
else
if
*
listMetaPlans
{
runner
=
&
runners
.
ListMetaPlans
{}
}
else
if
*
listPlans
{
runner
=
&
runners
.
ListPlans
{}
}
else
if
*
listTasks
{
runner
=
&
runners
.
ListTasks
{}
}
else
if
*
showConfig
{
runner
=
&
runners
.
ShowConfig
{}
}
else
{
runner
=
&
runners
.
Default
{}
}
if
len
(
*
planNames
)
==
0
{
*
planNames
=
[]
string
{
loader
.
DefaultPlan
()}
}
// resolve the plan name with the load and options
realPlans
:=
[]
string
{}
for
_
,
planName
:=
range
*
planNames
{
if
metaPlan
,
found
:=
cfg
.
MetaPlans
[
planName
];
found
{
realPlans
=
append
(
realPlans
,
metaPlan
.
Plans
...
)
}
else
{
realPlans
=
append
(
realPlans
,
loader
.
ResolvePlanName
(
planName
,
cfg
,
st
))
}
}
exitCode
=
runner
.
Run
(
cfg
,
realPlans
,
*
env
,
st
)
}