:bowtie: Initial commit
This commit is contained in:
Родитель
07f63df5ee
Коммит
e20a4249ae
|
@ -0,0 +1 @@
|
|||
~FC052
|
|
@ -0,0 +1,11 @@
|
|||
.vagrant
|
||||
.vagrant.d
|
||||
Gemfile.lock
|
||||
Berksfile.lock
|
||||
.bundle
|
||||
.cache
|
||||
.kitchen
|
||||
bin
|
||||
.kitchen.local.yml
|
||||
.coverage
|
||||
.kitchen/
|
|
@ -0,0 +1,87 @@
|
|||
---
|
||||
driver:
|
||||
name: vagrant
|
||||
gui: true
|
||||
customize:
|
||||
cpus: 2
|
||||
memory: 1024
|
||||
|
||||
provisioner:
|
||||
name: chef_zero
|
||||
client_rb:
|
||||
add_formatter: doc
|
||||
|
||||
platforms:
|
||||
- name: debian7
|
||||
driver_config:
|
||||
box: debian7
|
||||
provisioner:
|
||||
require_chef_omnibus: 11.18.6
|
||||
|
||||
- name: ubuntu1404
|
||||
driver_config:
|
||||
box: ubuntu/trusty64
|
||||
provisioner:
|
||||
require_chef_omnibus: 12.4.3
|
||||
|
||||
- name: centos6
|
||||
driver_config:
|
||||
box: bento/centos-6.7
|
||||
provisioner:
|
||||
require_chef_omnibus: 12.4.3
|
||||
|
||||
# private boxes
|
||||
- name: osx109-desktop
|
||||
driver_config:
|
||||
box: osx109-desktop #private
|
||||
provisioner:
|
||||
require_chef_omnibus: 12.4.3
|
||||
|
||||
- name: windows10
|
||||
driver_config:
|
||||
guest: windows
|
||||
communicator: 'winrm'
|
||||
box: win10x64-enterprise #private
|
||||
provisioner:
|
||||
require_chef_omnibus: 12.4.3
|
||||
|
||||
- name: windows81
|
||||
driver_config:
|
||||
guest: windows
|
||||
communicator: 'winrm'
|
||||
box: win81x64-enterprise #private
|
||||
provisioner:
|
||||
require_chef_omnibus: 11.18.6
|
||||
|
||||
|
||||
suites:
|
||||
- name: xplat-basic
|
||||
run_list:
|
||||
- recipe[xplat-basic::default]
|
||||
includes:
|
||||
- debian7
|
||||
- ubuntu1404
|
||||
- centos6
|
||||
- osx109-desktop
|
||||
|
||||
attributes:
|
||||
vsts_build_agent_test:
|
||||
vsts_url: <%= ENV['VSTS_URL'] %>
|
||||
vsts_pool: <%= ENV['VSTS_POOL'] %>
|
||||
vsts_user: <%= ENV['VSTS_USER'] %>
|
||||
vsts_token: <%= ENV['VSTS_TOKEN'] %>
|
||||
|
||||
|
||||
- name: windows-basic
|
||||
run_list:
|
||||
- recipe[windows-basic::default]
|
||||
includes:
|
||||
- windows10
|
||||
- windows81
|
||||
|
||||
attributes:
|
||||
vsts_build_agent_test:
|
||||
vsts_url: <%= ENV['VSTS_URL'] %>
|
||||
vsts_pool: <%= ENV['VSTS_POOL'] %>
|
||||
vsts_user: <%= ENV['VSTS_USER'] %>
|
||||
vsts_token: <%= ENV['VSTS_TOKEN'] %>
|
|
@ -0,0 +1,2 @@
|
|||
--color
|
||||
--format documentation
|
|
@ -0,0 +1,13 @@
|
|||
LineLength:
|
||||
Max: 300
|
||||
|
||||
Style/AlignParameters:
|
||||
Exclude:
|
||||
- '**/metadata.rb'
|
||||
|
||||
Style/SingleSpaceBeforeFirstArg:
|
||||
Exclude:
|
||||
- '**/metadata.rb'
|
||||
|
||||
HashSyntax:
|
||||
EnforcedStyle: hash_rockets
|
|
@ -0,0 +1,8 @@
|
|||
source 'https://supermarket.chef.io'
|
||||
|
||||
metadata
|
||||
|
||||
group :integration do
|
||||
cookbook 'windows-basic', :path => './test/cookbooks/windows-basic'
|
||||
cookbook 'xplat-basic', :path => './test/cookbooks/xplat-basic'
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
# How to contribute
|
||||
One of the easiest ways to contribute is to participate in discussions and discuss issues. You can also contribute by submitting pull requests with code changes.
|
||||
|
||||
## General feedback and discussions?
|
||||
Please start a discussion on the [issue tracker](https://github.com/Microsoft/vsts-build-agent-cookbook/issues).
|
||||
|
||||
## Contributing code and content
|
||||
Get familiar with github pull requests https://help.github.com/articles/using-pull-requests/
|
||||
|
||||
You will need to sign a [Contributor License Agreement](https://cla2.dotnetfoundation.org/) before submitting your pull request.
|
|
@ -0,0 +1,23 @@
|
|||
vsts-build-agent-cookbook
|
||||
|
||||
Copyright (c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
143
README.md
143
README.md
|
@ -1,2 +1,141 @@
|
|||
# vsts-build-agent-cookbook
|
||||
Visual Studio Team Services Build Agent Cookbook. It installs and configures Visual Studio Team Services Build Agents
|
||||
Visual Studio Team Services Build Agent Cookbook
|
||||
================
|
||||
Installs and configures Visual Studio Team Services [Build Agents](https://www.visualstudio.com/en-us/get-started/build/build-your-app-vs) (a.k.a VSO Build Agents)
|
||||
|
||||
Requirements
|
||||
------------
|
||||
- Chef 11 or higher
|
||||
|
||||
### Platforms
|
||||
The following platforms are tested and supported:
|
||||
- Debian 7 (Wheezy)
|
||||
- Ubuntu 14.04
|
||||
- CentOS 6
|
||||
- Windows 8.1
|
||||
- Windows 10
|
||||
- Mac OS X 10.9.5
|
||||
|
||||
The following platforms are known to work:
|
||||
- Microsoft Windows (8, 8.1, 10)
|
||||
|
||||
### Dependent Cookbooks
|
||||
This cookbook doesn't install nodejs executables for an XPlat(CrossPlatform) build agent.
|
||||
Please use [nodejs](https://supermarket.chef.io/cookbooks/nodejs) cookbook or any other ways which suits your case.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
* `node['vsts_build_agent']['xplat']['package_name']` - Set an xplat build agent [npm](https://www.npmjs.com/package/vsoagent-installer) package name
|
||||
* `node['vsts_build_agent']['xplat']['package_version']` - Set an npm package version. Possible values 'x.y.z' or 'latest'
|
||||
* `node['vsts_build_agent']['xplat']['skip_vsoagent_installer']` - Set to 'true' if you need another way to install npm package.
|
||||
|
||||
Resource/Provider
|
||||
-----------------
|
||||
### windows
|
||||
This resource installs and configures a build agent on windows host
|
||||
#### Actions
|
||||
- :install: Install and configure a build agent
|
||||
- :remove: Remove a build agent and unregister it from VSTS
|
||||
- :restart: Restart a build agent service
|
||||
|
||||
#### Parameters
|
||||
- agent_name: Name attribute. The name of a build agent
|
||||
- install_dir: A target directory to install a build agent
|
||||
- sv_name: Set a windows service name. Default vsoagent.host.agent_name
|
||||
- sv_user: Set a user name to run windows service. Possible values are "NT AUTHORITY\\NetworkService", "NT AUTHORITY\\LocalService" or any system valid username
|
||||
- sv_password: Set password with sv_user unless it is equal to NetworkService or LocalService
|
||||
- vsts_url: A target VSTS url
|
||||
- vsts_user: A user to connect with VSTS
|
||||
- vsts_token: A personal access token from VSTS. [See](http://roadtoalm.com/2015/07/22/using-personal-access-tokens-to-access-visual-studio-online/)
|
||||
- vsts_pool: A pool name on VSTS
|
||||
- work_folder: Set different workspace location. Default is "install_dir/\_work"
|
||||
|
||||
#### Examples
|
||||
Install, configure, restart and remove a build agent.
|
||||
Check [tests](test/cookbooks/basic/recipes/xplat.rb) for more examples.
|
||||
|
||||
```ruby
|
||||
include_recipe 'vsts_build_agent::default'
|
||||
|
||||
vsts_build_agent_windows 'agent' do
|
||||
install_dir 'c:\\agents\\agent1'
|
||||
sv_user 'vagrant'
|
||||
sv_password 'vagrant'
|
||||
vsts_url 'https://<account>.visualstudio.com'
|
||||
vsts_pool 'default'
|
||||
vsts_user 'builder'
|
||||
vsts_token 'my_secret_token_from_vsts'
|
||||
action :install
|
||||
end
|
||||
|
||||
vsts_build_agent_windows 'agent' do
|
||||
action :restart
|
||||
end
|
||||
|
||||
vsts_build_agent_windows 'agent' do
|
||||
vsts_token 'my_secret_token_from_vsts'
|
||||
action :remove
|
||||
end
|
||||
```
|
||||
|
||||
### xplat
|
||||
This resource installs and configures a build agent on linux or macosx host
|
||||
#### Actions
|
||||
- :install: Install and configure a build agent
|
||||
- :remove: Remove a build agent and unregister it from VSTS
|
||||
- :restart: Restart a build agent service
|
||||
|
||||
#### Parameters
|
||||
- agent_name: Name attribute. The name of build agent
|
||||
- install_dir: A target directory to install build agent
|
||||
- user: Set a user to run build agent.
|
||||
- group: Set a group to run build agent.
|
||||
- sv_name: Set a service name. Default vsoagent.host.agent_name
|
||||
- sv_envs: Set hash of environment variables to pass into an agent process
|
||||
- sv_session: For MacOsX only. Set a LaunchAgent session.
|
||||
- vsts_url: A target VSTS url
|
||||
- vsts_user: A user to connect with VSTS
|
||||
- vsts_token: A personal access token from VSTS. [See](http://roadtoalm.com/2015/07/22/using-personal-access-tokens-to-access-visual-studio-online/)
|
||||
- vsts_pool: A pool name on VSTS
|
||||
|
||||
#### Examples
|
||||
Install, configure, restart and remove build agent.
|
||||
Check [tests](test/cookbooks/basic/recipes/windows.rb) for more examples.
|
||||
|
||||
```ruby
|
||||
include_recipe 'vsts_build_agent::default'
|
||||
|
||||
if platform_family?('mac_os_x')
|
||||
include_recipe 'homebrew'
|
||||
end
|
||||
|
||||
include_recipe 'nodejs::default'
|
||||
include_recipe 'nodejs::npm'
|
||||
|
||||
vsts_build_agent_xplat 'xplat_agent' do
|
||||
install_dir "/home/vagrant/agents/xplat_agent"
|
||||
user 'vagrant'
|
||||
group 'vagrant'
|
||||
sv_envs(
|
||||
'PATH' => '/usr/local/bin/:/opt/local/bin:/sbin:/usr/sbin:/bin:/usr/bin',
|
||||
'TEST' => 'agent1'
|
||||
)
|
||||
vsts_url 'https://account.visualstudio.com'
|
||||
vsts_pool 'default'
|
||||
vsts_user 'builder'
|
||||
vsts_token 'my_secret_token_from_vsts'
|
||||
action :install
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat 'xplat_agent' do
|
||||
action :restart
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat 'xplat_agent' do
|
||||
vsts_token 'my_secret_token_from_vsts'
|
||||
action :remove
|
||||
end
|
||||
```
|
||||
|
||||
# How to contribute
|
||||
Check [Contribution Guide](CONTRIBUTING.md) and [Testing Guide](TESTING.md)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
require 'rspec/core/rake_task'
|
||||
require 'rubocop/rake_task'
|
||||
require 'foodcritic'
|
||||
require 'kitchen'
|
||||
|
||||
namespace :style do
|
||||
desc 'Run Ruby style checks'
|
||||
RuboCop::RakeTask.new(:ruby)
|
||||
|
||||
desc 'Run Chef style checks'
|
||||
FoodCritic::Rake::LintTask.new(:chef)
|
||||
end
|
||||
|
||||
desc 'Run all style checks'
|
||||
task :style => ['style:chef', 'style:ruby']
|
||||
|
||||
desc 'Run ChefSpec'
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
namespace :kitchen do
|
||||
desc 'Run Test Kitchen with Vagrant'
|
||||
task :linux do
|
||||
Kitchen.logger = Kitchen.default_file_logger
|
||||
Kitchen::Config.new.instances.get('xplat-basic-ubuntu1404').test(:always)
|
||||
end
|
||||
end
|
||||
|
||||
task :default => ['style', 'kitchen:linux']
|
|
@ -0,0 +1,33 @@
|
|||
# Testing Documentation
|
||||
|
||||
## Prerequisites
|
||||
VSTS Build Agent cookbook requires ChefDK installation. ChefDK can be downloaded at https://downloads.chef.io/chef-dk/
|
||||
|
||||
Integration testing uses Hashicorp's [Vagrant](https://www.vagrantup.com/downloads.html) and Oracle's [Virtualbox](https://www.virtualbox.org/wiki/Downloads), which must be installed first.
|
||||
|
||||
## Style Testing
|
||||
Ruby and Chef([Foodcritic](http://www.foodcritic.io/)) style checks can be performed by running:
|
||||
```
|
||||
chef exec rake style
|
||||
```
|
||||
or
|
||||
```
|
||||
rake style
|
||||
```
|
||||
|
||||
## Integration Testing
|
||||
Integration tests are orchestrated by [test-kitchen](https://github.com/test-kitchen/test-kitchen). Currently kitchen.yml contains mix of public(linux) and private boxes(Windows and MacOSX). Windows and MacOSX boxes can be built locally with help of Hashicorp's [packer](https://www.packer.io/) tool.
|
||||
!NOTE: To use MacOSX boxes you need an Apple-branded computer.
|
||||
|
||||
To run test against specific platform run:
|
||||
```
|
||||
kitchen verify PLATFORM
|
||||
```
|
||||
|
||||
Available platforms:
|
||||
* debian7 (public)
|
||||
* ubuntu1404 (public)
|
||||
* centos6 (public)
|
||||
* osx109-desktop (private)
|
||||
* windows10 (private)
|
||||
* windows81 (private)
|
|
@ -0,0 +1,3 @@
|
|||
default['vsts_build_agent']['xplat']['package_name'] = 'vsoagent-installer'
|
||||
default['vsts_build_agent']['xplat']['package_version'] = 'latest'
|
||||
default['vsts_build_agent']['xplat']['skip_vsoagent_installer'] = false
|
|
@ -0,0 +1,57 @@
|
|||
var cfgm = require("./configuration");
|
||||
var cm = require('./common');
|
||||
var webapi = require('vso-node-api/WebApi');;
|
||||
|
||||
|
||||
var cfgr = new cfgm.Configurator();
|
||||
|
||||
var _creds;
|
||||
cm.readBasicCreds().then(function (credentials) {
|
||||
_creds = credentials;
|
||||
action = process.argv.slice(2)[0];
|
||||
settings = cfgm.read();
|
||||
var agentPoolId;
|
||||
if (action == 'install') {
|
||||
console.info("Trying to create agent")
|
||||
return cfgr.create(credentials).fail(function (err) {
|
||||
// we couldn't create agent, then we try to update
|
||||
console.info("Trying to update agent")
|
||||
cfgr.update(credentials, settings)
|
||||
})
|
||||
} else if (action == 'remove') {
|
||||
console.info("Trying to remove agent")
|
||||
var agentApi = new webapi.WebApi(settings.serverUrl, cm.basicHandlerFromCreds(credentials)).getQTaskAgentApi();
|
||||
agentApi.connect()
|
||||
.then(function (connected) {
|
||||
console.log('successful connect as ' + connected.authenticatedUser.customDisplayName);
|
||||
return agentApi.getAgentPools(settings.poolName, null);
|
||||
}).then(function (agentPools) {
|
||||
if (agentPools.length == 0) {
|
||||
throw new Error(settings.poolName + ' pool does not exist.');
|
||||
}
|
||||
// we queried by name so should only get 1
|
||||
agentPoolId = agentPools[0].id;
|
||||
console.log('Retrieved agent pool: ' + agentPools[0].name + ' (' + agentPoolId + ')');
|
||||
return agentApi.getAgents(agentPoolId, settings.agentName);
|
||||
}).then(function (agents) {
|
||||
if (agents.length == 1) {
|
||||
console.log('Found agent in pool ' + agents[0].name + ' (' + agentPoolId + ')');
|
||||
var agentId = agents[0].id;
|
||||
agentApi.deleteAgent(agentPoolId, agentId);
|
||||
} else {
|
||||
console.log('Not found agents in pool '+ agentPoolId);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
console.error("Wrong action. Must be install or remove")
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
}).fail(function (err) {
|
||||
|
||||
console.error('Error starting the agent');
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
});
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
|
||||
module VSTS
|
||||
module Build
|
||||
module Agent
|
||||
# Helper methods for VSTS Build Agent installation
|
||||
module Helpers
|
||||
VARS_TO_SAVE = %w(vsts_url vsts_pool vsts_user install_dir sv_name sv_session user group user_home)
|
||||
|
||||
def agent_installed?(resource, node)
|
||||
agent_attribute?(resource.agent_name, node) &&
|
||||
(::File.exist?("#{resource.install_dir}/.agent") ||
|
||||
::File.file?("#{resource.install_dir}\\Agent\\VsoAgent.exe"))
|
||||
end
|
||||
|
||||
def service_name(resource)
|
||||
return resource.sv_name if resource.sv_name
|
||||
return nil unless resource.vsts_url
|
||||
hostname = URI.parse(resource.vsts_url).host
|
||||
hostname = hostname[0, hostname.index('.')] if hostname.include?('.')
|
||||
"vsoagent.#{hostname}.#{resource.agent_name}"
|
||||
end
|
||||
|
||||
def get_npm_install_cmd(node)
|
||||
npm_cmd = "npm install -global #{node['vsts_build_agent']['xplat']['package_name']}"
|
||||
unless node['vsts_build_agent']['xplat']['package_version'] == 'latest'
|
||||
npm_cmd += "@#{node['vsts_build_agent']['xplat']['package_version']}"
|
||||
end
|
||||
npm_cmd
|
||||
end
|
||||
|
||||
def save_current_state(resource, node)
|
||||
VARS_TO_SAVE.each do |var|
|
||||
node.set['vsts_build_agent']['agents'][resource.agent_name][var] = resource.send(var) if resource.respond_to?(var.to_sym)
|
||||
end
|
||||
node.save
|
||||
end
|
||||
|
||||
def load_current_state(resource, node)
|
||||
return unless agent_attribute?(resource.agent_name, node)
|
||||
VARS_TO_SAVE.each do |var|
|
||||
resource.send(var, node['vsts_build_agent']['agents'][resource.agent_name][var]) if resource.respond_to?(var.to_sym)
|
||||
end
|
||||
end
|
||||
|
||||
def agent_attribute?(agent_name, node)
|
||||
node['vsts_build_agent']['agents'] && node['vsts_build_agent']['agents'][agent_name]
|
||||
end
|
||||
|
||||
def remove_current_state(resource, node)
|
||||
node.set['vsts_build_agent']['agents'][resource.agent_name] = {}
|
||||
node.save
|
||||
end
|
||||
|
||||
def plist_path(resource)
|
||||
if resource.sv_session
|
||||
path = "/Library/LaunchAgents/#{resource.sv_name}.plist"
|
||||
else
|
||||
path = "/Library/LaunchDaemons/#{resource.sv_name}.plist"
|
||||
end
|
||||
|
||||
path = "#{resource.user_home}#{path}" if resource.user_home
|
||||
path
|
||||
end
|
||||
|
||||
def launchctl_load(resource)
|
||||
plist = plist_path resource
|
||||
command = 'launchctl load -w '
|
||||
command += "-S #{resource.sv_session} " if resource.sv_session
|
||||
command += plist
|
||||
command
|
||||
end
|
||||
|
||||
def launchctl_unload(resource)
|
||||
plist = plist_path resource
|
||||
command = "launchctl unload #{plist}"
|
||||
command
|
||||
end
|
||||
|
||||
def vsagentexec(args = {})
|
||||
command = 'Agent\\VsoAgent.exe '
|
||||
args.each do |key, value|
|
||||
command += "/#{key}"
|
||||
command += ":\"#{value}\"" unless value.nil?
|
||||
command += ' '
|
||||
end
|
||||
command
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
name 'vsts_build_agent'
|
||||
maintainer 'Microsoft'
|
||||
license 'MIT'
|
||||
description 'Installs/Configures visualstudio team services build agents'
|
||||
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
|
||||
version '0.1.0'
|
||||
|
||||
%w( ubuntu debian mac_os_x mac_os_x_server windows ).each do |os|
|
||||
supports os
|
||||
end
|
||||
|
||||
suggests 'nodejs'
|
||||
|
||||
depends 'runit'
|
||||
depends 'windows'
|
|
@ -0,0 +1,138 @@
|
|||
require 'chef/mixin/shell_out'
|
||||
include Chef::Mixin::ShellOut
|
||||
include ::VSTS::Build::Agent::Helpers
|
||||
|
||||
use_inline_resources
|
||||
|
||||
def whyrun_supported?
|
||||
true
|
||||
end
|
||||
|
||||
def load_current_resource
|
||||
@current_resource = Chef::Resource::VstsBuildAgentWindows.new(@new_resource.name)
|
||||
@current_resource.agent_name(@new_resource.agent_name)
|
||||
@current_resource.exists = false
|
||||
|
||||
load_current_state(@current_resource, node)
|
||||
@new_resource.sv_name(service_name(@new_resource))
|
||||
|
||||
if agent_installed?(@current_resource, node)
|
||||
@current_resource.vsts_token(@new_resource.vsts_token)
|
||||
@current_resource.exists = true
|
||||
end
|
||||
@current_resource
|
||||
end
|
||||
|
||||
action :install do
|
||||
if @current_resource.exists
|
||||
Chef::Log.info "#{new_resource.agent_name} agent already exists - nothing to do"
|
||||
else
|
||||
converge_by("Installing agent \"#{new_resource.agent_name}\"") do
|
||||
powershell_script 'Downloading vsoagent' do
|
||||
code <<-EOH
|
||||
|
||||
$username = "#{new_resource.vsts_user}"
|
||||
$patToken = "#{new_resource.vsts_token}"
|
||||
$OutFile = "#{Chef::Config[:file_cache_path]}/vso_agent.zip"
|
||||
|
||||
$auth = ('{0}:{1}' -f $username,$patToken)
|
||||
$auth = [System.Text.Encoding]::UTF8.GetBytes($auth)
|
||||
$auth = [System.Convert]::ToBase64String($auth)
|
||||
|
||||
$h = @{Authorization=('Basic {0}' -f $auth)}
|
||||
|
||||
$wc = New-Object Net.WebClient
|
||||
$wc.Headers.add('Authorization', 'Basic {0}' -f $auth)
|
||||
$wc.DownloadFile( "#{new_resource.vsts_url}/_apis/distributedtask/packages/agent", $OutFile )
|
||||
EOH
|
||||
not_if { ::File.exist?("#{Chef::Config[:file_cache_path]}/vso_agent.zip") }
|
||||
end
|
||||
|
||||
directory new_resource.install_dir do
|
||||
rights :full_control, new_resource.sv_user, :applies_to_children => true
|
||||
recursive true
|
||||
action :create
|
||||
end
|
||||
|
||||
windows_zipfile new_resource.install_dir do
|
||||
source "#{Chef::Config[:file_cache_path]}/vso_agent.zip"
|
||||
action :unzip
|
||||
end
|
||||
|
||||
powershell_script 'Removing the ZoneIdentifier from files downloaded from the internet' do
|
||||
cwd new_resource.install_dir
|
||||
code <<-EOH
|
||||
Get-ChildItem -Path #{new_resource.install_dir} | Unblock-File | out-null
|
||||
Get-ChildItem -Recurse -Path #{new_resource.install_dir}\\Agent | Unblock-File | out-null
|
||||
EOH
|
||||
end
|
||||
|
||||
args = {
|
||||
'configure' => nil,
|
||||
'RunningAsService' => nil,
|
||||
'serverUrl' => new_resource.vsts_url,
|
||||
'WindowsServiceName' => new_resource.sv_name,
|
||||
'WindowsServiceLogonAccount' => new_resource.sv_user,
|
||||
'WindowsServiceLogonPassword' => new_resource.sv_password,
|
||||
'name' => new_resource.agent_name,
|
||||
'PoolName' => new_resource.vsts_pool,
|
||||
'WorkFolder' => new_resource.work_folder,
|
||||
'Login' => "#{new_resource.vsts_user},#{new_resource.vsts_token}",
|
||||
'force' => nil,
|
||||
'NoPrompt' => nil
|
||||
}
|
||||
|
||||
execute "Configuring agent \"#{new_resource.agent_name}\"" do
|
||||
cwd new_resource.install_dir
|
||||
command vsagentexec(args)
|
||||
action :run
|
||||
end
|
||||
end
|
||||
|
||||
save_current_state(new_resource, node)
|
||||
new_resource.updated_by_last_action(true)
|
||||
Chef::Log.info "\"#{new_resource.agent_name}\" agent was installed"
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
action :remove do
|
||||
if @current_resource.exists
|
||||
converge_by("Removing agent \"#{@current_resource.agent_name}\"") do
|
||||
args = {
|
||||
'unconfigure' => nil,
|
||||
'Login' => "#{@current_resource.vsts_user},#{@current_resource.vsts_token}",
|
||||
'force' => nil,
|
||||
'NoPrompt' => nil
|
||||
}
|
||||
|
||||
execute "Unconfiguring agent \"#{@current_resource.agent_name}\"" do
|
||||
cwd current_resource.install_dir
|
||||
command vsagentexec(args)
|
||||
action :run
|
||||
retries 3
|
||||
retry_delay 15
|
||||
end
|
||||
|
||||
directory current_resource.install_dir do
|
||||
recursive true
|
||||
action :delete
|
||||
end
|
||||
end
|
||||
remove_current_state(@current_resource, node)
|
||||
new_resource.updated_by_last_action(true)
|
||||
Chef::Log.info "\"#{new_resource.agent_name}\" agent was removed"
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
if @current_resource.exists
|
||||
converge_by("Restarting agent \"#{@current_resource.agent_name}\"") do
|
||||
service @current_resource.sv_name do
|
||||
action :restart
|
||||
end
|
||||
end
|
||||
new_resource.updated_by_last_action(true)
|
||||
Chef::Log.info "\"#{@current_resource.agent_name}\" agent was restarted"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,213 @@
|
|||
require 'chef/mixin/shell_out'
|
||||
require 'json'
|
||||
|
||||
include ::VSTS::Build::Agent::Helpers
|
||||
|
||||
use_inline_resources
|
||||
|
||||
def whyrun_supported?
|
||||
true
|
||||
end
|
||||
|
||||
def load_current_resource
|
||||
@current_resource = Chef::Resource::VstsBuildAgentXplat.new(@new_resource.name)
|
||||
@current_resource.agent_name(@new_resource.agent_name)
|
||||
@current_resource.exists = false
|
||||
|
||||
load_current_state(@current_resource, node)
|
||||
@new_resource.sv_name(service_name(@new_resource))
|
||||
|
||||
if agent_installed?(@current_resource, node)
|
||||
@current_resource.vsts_token(@new_resource.vsts_token)
|
||||
@current_resource.exists = true
|
||||
end
|
||||
@current_resource
|
||||
end
|
||||
|
||||
action :install do
|
||||
if @current_resource.exists
|
||||
Chef::Log.info "#{new_resource.agent_name} agent already exists - nothing to do"
|
||||
else
|
||||
converge_by("Installing agent \"#{new_resource.agent_name}\"") do
|
||||
npm_cmd = get_npm_install_cmd(node)
|
||||
execute 'Install vsoagent-installer npm package' do
|
||||
command npm_cmd
|
||||
not_if { node['vsts_build_agent']['xplat']['skip_vsoagent_installer'] }
|
||||
end
|
||||
|
||||
directory new_resource.install_dir do
|
||||
user new_resource.user
|
||||
group new_resource.group
|
||||
mode '0755'
|
||||
recursive true
|
||||
action [:delete, :create]
|
||||
end
|
||||
|
||||
execute "Initializing agent \"#{new_resource.agent_name}\"" do
|
||||
cwd new_resource.install_dir
|
||||
command 'vsoagent-installer'
|
||||
user new_resource.user
|
||||
group new_resource.group
|
||||
end
|
||||
|
||||
template "#{new_resource.install_dir}/.agent" do
|
||||
source 'agent_conf.erb'
|
||||
variables(:agent => new_resource)
|
||||
owner new_resource.user
|
||||
group new_resource.group
|
||||
cookbook 'vsts_build_agent'
|
||||
end
|
||||
|
||||
cookbook_file "#{new_resource.install_dir}/agent/vsoagent_configurator.js" do
|
||||
source 'vsoagent_configurator.js'
|
||||
owner new_resource.user
|
||||
group new_resource.group
|
||||
cookbook 'vsts_build_agent'
|
||||
end
|
||||
|
||||
execute "Configuring agent \"#{new_resource.agent_name}\"" do
|
||||
cwd new_resource.install_dir
|
||||
command "node agent/vsoagent_configurator install -u #{new_resource.vsts_user} -p #{new_resource.vsts_token} -s #{new_resource.vsts_url} -a #{new_resource.agent_name} -l #{new_resource.vsts_pool} -b false"
|
||||
user new_resource.user
|
||||
group new_resource.group
|
||||
end
|
||||
|
||||
if new_resource.user_home && !new_resource.sv_envs.key?('HOME')
|
||||
new_resource.sv_envs['HOME'] = new_resource.user_home
|
||||
end
|
||||
|
||||
if mac_os_x?
|
||||
plist = plist_path new_resource
|
||||
|
||||
directory "#{new_resource.user_home}/Library/LaunchDaemons" do
|
||||
user new_resource.user
|
||||
group new_resource.group
|
||||
mode '0755'
|
||||
action :create
|
||||
only_if { new_resource.user_home }
|
||||
end
|
||||
|
||||
template plist do
|
||||
source "#{new_resource.sv_template}.plist.erb"
|
||||
cookbook new_resource.sv_cookbook
|
||||
user new_resource.user if new_resource.user_home
|
||||
group new_resource.group if new_resource.user_home
|
||||
variables(
|
||||
:agent => new_resource
|
||||
)
|
||||
end
|
||||
|
||||
cmd = launchctl_load @new_resource
|
||||
execute cmd do
|
||||
user new_resource.user if new_resource.user_home
|
||||
group new_resource.group if new_resource.user_home
|
||||
action :run
|
||||
end
|
||||
|
||||
else
|
||||
runit_service new_resource.sv_name do
|
||||
options(
|
||||
:agent => new_resource
|
||||
)
|
||||
owner new_resource.user
|
||||
group new_resource.group
|
||||
cookbook new_resource.sv_cookbook
|
||||
run_template_name new_resource.sv_template
|
||||
log_template_name new_resource.sv_template
|
||||
sv_timeout new_resource.sv_timeout
|
||||
sv_verbose true
|
||||
action :enable
|
||||
end
|
||||
ruby_block 'Wait for service setup' do
|
||||
block do
|
||||
# TODO: remove when runit cookbook will wait for service setup
|
||||
sleep new_resource.sv_wait_timeout
|
||||
end
|
||||
end
|
||||
runit_service new_resource.sv_name do
|
||||
action :start
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
save_current_state(new_resource, node)
|
||||
Chef::Log.info "\"#{new_resource.agent_name}\" agent was installed"
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action :remove do
|
||||
if @current_resource.exists
|
||||
converge_by("Removing agent \"#{@current_resource.agent_name}\"") do
|
||||
if mac_os_x?
|
||||
plist = plist_path @current_resource
|
||||
cmd = launchctl_unload @current_resource
|
||||
execute "Unload service for #{@current_resource.agent_name}" do
|
||||
user current_resource.user if current_resource.user_home
|
||||
group current_resource.group if current_resource.user_home
|
||||
command cmd
|
||||
only_if { ::File.exist?(plist) }
|
||||
action :run
|
||||
end
|
||||
|
||||
file plist do
|
||||
action :delete
|
||||
end
|
||||
else
|
||||
runit_service @current_resource.sv_name do
|
||||
action [:stop, :disable]
|
||||
end
|
||||
end
|
||||
|
||||
execute "Delete agent \"#{@current_resource.agent_name}\" from server" do
|
||||
cwd current_resource.install_dir
|
||||
command "node agent/vsoagent_configurator remove -u #{current_resource.vsts_user} -p #{current_resource.vsts_token} -s #{current_resource.vsts_url} -a #{current_resource.agent_name} -l #{current_resource.vsts_pool} -b false"
|
||||
user current_resource.user
|
||||
group current_resource.group
|
||||
end
|
||||
directory @current_resource.install_dir do
|
||||
recursive true
|
||||
action :delete
|
||||
end
|
||||
remove_current_state(@current_resource, node)
|
||||
Chef::Log.info "\"#{@current_resource.agent_name}\" agent was removed"
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
if @current_resource.exists
|
||||
converge_by("Restarting agent \"#{@current_resource.agent_name}\"") do
|
||||
if mac_os_x?
|
||||
cmd = launchctl_unload @current_resource
|
||||
execute cmd do
|
||||
user current_resource.user if current_resource.user_home
|
||||
group current_resource.group if current_resource.user_home
|
||||
action :run
|
||||
end
|
||||
cmd = launchctl_load @current_resource
|
||||
execute cmd do
|
||||
user current_resource.user if current_resource.user_home
|
||||
group current_resource.group if current_resource.user_home
|
||||
action :run
|
||||
end
|
||||
|
||||
else
|
||||
runit_service @current_resource.sv_name do
|
||||
action :restart
|
||||
end
|
||||
end
|
||||
|
||||
Chef::Log.info "\"#{@current_resource.agent_name}\" agent was restarted"
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mac_os_x?
|
||||
platform_family?('mac_os_x') || platform_family?('mac_os_x_server')
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
if %w(debian rhel fedora gentoo).include?(node['platform_family'])
|
||||
include_recipe 'runit::default'
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
actions :install, :remove, :restart
|
||||
default_action :install
|
||||
|
||||
attribute :agent_name, :name_attribute => true
|
||||
attribute :install_dir, :kind_of => String
|
||||
|
||||
attribute :sv_name, :kind_of => String
|
||||
attribute :sv_user, :kind_of => String
|
||||
attribute :sv_password, :kind_of => String
|
||||
|
||||
attribute :vsts_url, :kind_of => String
|
||||
attribute :vsts_pool, :kind_of => String
|
||||
attribute :vsts_user, :kind_of => String
|
||||
attribute :vsts_token, :kind_of => String
|
||||
|
||||
attribute :work_folder, :kind_of => String, :default => '_work' # not supported on client side
|
||||
|
||||
attr_accessor :exists
|
|
@ -0,0 +1,24 @@
|
|||
actions :install, :remove, :restart
|
||||
default_action :install
|
||||
|
||||
attribute :agent_name, :name_attribute => true
|
||||
attribute :install_dir, :kind_of => String
|
||||
|
||||
attribute :user, :kind_of => String
|
||||
attribute :group, :kind_of => String
|
||||
attribute :user_home, :kind_of => String
|
||||
|
||||
attribute :sv_name, :kind_of => String # Default vsoagent.host.agent_name
|
||||
attribute :sv_cookbook, :kind_of => String, :default => 'vsts_build_agent'
|
||||
attribute :sv_template, :kind_of => String, :default => 'vsts_build_agent'
|
||||
attribute :sv_timeout, :kind_of => Integer, :default => 120
|
||||
attribute :sv_envs, :kind_of => Hash, :default => {}
|
||||
attribute :sv_session, :kind_of => String, :default => nil # used by MacOsX. Can be Aqua for interact with GUI
|
||||
attribute :sv_wait_timeout, :kind_of => Integer, :default => 5
|
||||
|
||||
attribute :vsts_url, :kind_of => String
|
||||
attribute :vsts_pool, :kind_of => String
|
||||
attribute :vsts_user, :kind_of => String
|
||||
attribute :vsts_token, :kind_of => String
|
||||
|
||||
attr_accessor :exists
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"poolName": "<%= @agent.vsts_pool %>",
|
||||
"serverUrl": "<%= @agent.vsts_url %>",
|
||||
"agentName": "<%= @agent.agent_name %>"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec svlogd -tt ./main
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
ulimit -Hn 65550
|
||||
ulimit -Sn 65550
|
||||
|
||||
exec 2>&1
|
||||
cd <%= @options[:agent].install_dir %>
|
||||
exec env <% unless @options[:agent].sv_envs.empty? -%><%= @options[:agent].sv_envs.map{|k,v| "#{k}=#{v}"}.join(' ') %><% end -%> \
|
||||
chpst -u <%= @options[:agent].user %>:<%= @options[:agent].group %> \
|
||||
-U <%= @options[:agent].user %>:<%= @options[:agent].group %> \
|
||||
node ./agent/vsoagent.js -u <%= @options[:agent].vsts_user %> -p <%= @options[:agent].vsts_token %>
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string><%= @agent.sv_name %></string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>node</string>
|
||||
<string><%= @agent.install_dir %>/agent/vsoagent.js</string>
|
||||
<string>-u</string>
|
||||
<string><%= @agent.vsts_user %> </string>
|
||||
<string>-p</string>
|
||||
<string><%= @agent.vsts_token %></string>
|
||||
</array>
|
||||
<key>UserName</key>
|
||||
<string><%= @agent.user %></string>
|
||||
|
||||
<% if @session -%>
|
||||
<key>LimitLoadToSessionType</key>
|
||||
<string><%= @agent.sv_session %></string>
|
||||
<% end -%>
|
||||
|
||||
<key>WorkingDirectory</key>
|
||||
<string><%= @agent.install_dir %></string>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string><%= @agent.install_dir %>/service.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string><%= @agent.install_dir %>/service.err.log</string>
|
||||
|
||||
<% unless @agent.sv_envs.empty? -%>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<% @agent.sv_envs.each do |key, val| -%>
|
||||
<key><%= key %></key>
|
||||
<string><%= val %></string>
|
||||
<% end -%>
|
||||
</dict>
|
||||
<% end -%>
|
||||
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,5 @@
|
|||
# set attributes through test kitchen
|
||||
default['vsts_build_agent_test']['vsts_url'] = nil
|
||||
default['vsts_build_agent_test']['vsts_pool'] = nil
|
||||
default['vsts_build_agent_test']['vsts_user'] = nil
|
||||
default['vsts_build_agent_test']['vsts_token'] = nil
|
|
@ -0,0 +1,5 @@
|
|||
name 'windows-basic'
|
||||
version '0.0.1'
|
||||
|
||||
depends 'vsts_build_agent'
|
||||
depends 'windows'
|
|
@ -0,0 +1,73 @@
|
|||
include_recipe 'vsts_build_agent::default'
|
||||
|
||||
agent_prefix = node['hostname']
|
||||
sys_user = 'vagrant'
|
||||
sys_passwd = 'vagrant'
|
||||
|
||||
# clean previous run
|
||||
vsts_build_agent_windows "#{agent_prefix}_01" do
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
||||
|
||||
vsts_build_agent_windows "#{agent_prefix}_02" do
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
||||
|
||||
vsts_build_agent_windows "#{agent_prefix}_03" do
|
||||
install_dir "c:\\agents\\#{agent_prefix}_03"
|
||||
vsts_user node['vsts_build_agent_test']['vsts_user']
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
||||
|
||||
# install agents
|
||||
# agent with default service name
|
||||
vsts_build_agent_windows "#{agent_prefix}_01" do
|
||||
install_dir 'c:\\agents\\agent_01'
|
||||
sv_user sys_user
|
||||
sv_password sys_passwd
|
||||
vsts_url node['vsts_build_agent_test']['vsts_url']
|
||||
vsts_pool node['vsts_build_agent_test']['vsts_pool']
|
||||
vsts_user node['vsts_build_agent_test']['vsts_user']
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :install
|
||||
end
|
||||
|
||||
vsts_build_agent_windows "#{agent_prefix}_01" do
|
||||
action :restart
|
||||
end
|
||||
|
||||
# agent with overriden service name
|
||||
# run as Local Service user
|
||||
vsts_build_agent_windows "#{agent_prefix}_02" do
|
||||
install_dir 'c:\\agents\\agent_02'
|
||||
sv_user 'NT AUTHORITY\\LocalService'
|
||||
sv_name 'agent_02.service'
|
||||
vsts_url node['vsts_build_agent_test']['vsts_url']
|
||||
vsts_pool node['vsts_build_agent_test']['vsts_pool']
|
||||
vsts_user node['vsts_build_agent_test']['vsts_user']
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :install
|
||||
end
|
||||
|
||||
vsts_build_agent_windows "#{agent_prefix}_02" do
|
||||
action :restart
|
||||
end
|
||||
|
||||
# agent to remove
|
||||
vsts_build_agent_windows "#{agent_prefix}_03" do
|
||||
install_dir 'c:\\agents\\agent_03'
|
||||
sv_user 'NT AUTHORITY\\NetworkService'
|
||||
vsts_url node['vsts_build_agent_test']['vsts_url']
|
||||
vsts_pool node['vsts_build_agent_test']['vsts_pool']
|
||||
vsts_user node['vsts_build_agent_test']['vsts_user']
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :install
|
||||
end
|
||||
|
||||
vsts_build_agent_windows "#{agent_prefix}_03" do
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
default['nodejs']['version'] = '4.2.3'
|
||||
default['nodejs']['source']['checksum'] = nil
|
||||
default['nodejs']['binary']['checksum']['linux_x64'] = nil
|
||||
default['nodejs']['binary']['checksum']['linux_x86'] = nil
|
||||
default['nodejs']['install_method'] = 'binary'
|
||||
|
||||
# set attributes through test kitchen
|
||||
default['vsts_build_agent_test']['vsts_url'] = nil
|
||||
default['vsts_build_agent_test']['vsts_pool'] = nil
|
||||
default['vsts_build_agent_test']['vsts_user'] = nil
|
||||
default['vsts_build_agent_test']['vsts_token'] = nil
|
|
@ -0,0 +1,10 @@
|
|||
name 'xplat-basic'
|
||||
version '0.0.1'
|
||||
|
||||
depends 'vsts_build_agent'
|
||||
|
||||
depends 'apt'
|
||||
depends 'build-essential'
|
||||
depends 'nodejs'
|
||||
depends 'runit'
|
||||
depends 'homebrew'
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
include_recipe 'apt::default' if platform_family?('debian')
|
||||
|
||||
include_recipe 'vsts_build_agent::default'
|
||||
|
||||
include_recipe 'build-essential::default'
|
||||
include_recipe 'vsts_build_agent::default'
|
||||
|
||||
agent1_name = "#{node['hostname']}_01"
|
||||
agent2_name = "#{node['hostname']}_02"
|
||||
|
||||
if platform_family?('mac_os_x')
|
||||
home_dir = '/Users/vagrant'
|
||||
|
||||
bash 'Prepare dirs for the homebrew' do
|
||||
code <<-EOH
|
||||
mkdir -p /usr/local
|
||||
chown -R vagrant:staff /usr/local
|
||||
EOH
|
||||
end
|
||||
|
||||
node.set['homebrew']['owner'] = 'vagrant'
|
||||
include_recipe 'homebrew'
|
||||
|
||||
execute 'Install nodejs from brew' do
|
||||
command 'brew install node'
|
||||
user 'vagrant'
|
||||
group 'staff'
|
||||
action :run
|
||||
end
|
||||
|
||||
else
|
||||
home_dir = '/home/vagrant'
|
||||
include_recipe 'nodejs::default'
|
||||
include_recipe 'nodejs::npm'
|
||||
execute 'Set npm global prefix' do
|
||||
command 'npm config set prefix /usr/local'
|
||||
end
|
||||
end
|
||||
|
||||
# # cleanup
|
||||
vsts_build_agent_xplat agent1_name do
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat agent2_name do
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat agent1_name do
|
||||
install_dir "#{home_dir}/agents/agent_01"
|
||||
user 'vagrant'
|
||||
group 'vagrant'
|
||||
sv_envs(
|
||||
'PATH' => '/usr/local/bin/:/opt/local/bin:/sbin:/usr/sbin:/bin:/usr/bin',
|
||||
'TEST' => 'agent1'
|
||||
)
|
||||
vsts_url node['vsts_build_agent_test']['vsts_url']
|
||||
vsts_pool node['vsts_build_agent_test']['vsts_pool']
|
||||
vsts_user node['vsts_build_agent_test']['vsts_user']
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :install
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat agent2_name do
|
||||
install_dir "#{home_dir}/agents/agent_02"
|
||||
user 'vagrant'
|
||||
group 'vagrant'
|
||||
user_home home_dir
|
||||
sv_name 'agent2'
|
||||
sv_envs(
|
||||
'PATH' => '/usr/local/bin/:/opt/local/bin:/sbin:/usr/sbin:/bin:/usr/bin',
|
||||
'TEST' => 'agent2'
|
||||
)
|
||||
vsts_url node['vsts_build_agent_test']['vsts_url']
|
||||
vsts_pool node['vsts_build_agent_test']['vsts_pool']
|
||||
vsts_user node['vsts_build_agent_test']['vsts_user']
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :install
|
||||
notifies :restart, "vsts_build_agent_xplat[#{agent2_name}]", :delayed
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat "Restart '#{agent1_name}'" do
|
||||
agent_name agent1_name
|
||||
action :restart
|
||||
end
|
||||
|
||||
vsts_build_agent_xplat "Remove '#{agent1_name}'" do
|
||||
agent_name agent1_name
|
||||
vsts_token node['vsts_build_agent_test']['vsts_token']
|
||||
action :remove
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
require 'serverspec'
|
||||
|
||||
set :backend, :cmd
|
||||
set :os, :family => 'windows'
|
||||
|
||||
describe file('c:\\agents\\agent_01\\Agent\\VsoAgent.exe') do
|
||||
it { should be_file }
|
||||
end
|
||||
|
||||
describe file('c:\\agents\\agent_02\\Agent\\VsoAgent.exe') do
|
||||
it { should be_file }
|
||||
end
|
||||
|
||||
describe file('c:\\agents\\agent_03\\Agent\\VsoAgent.exe') do
|
||||
it { should_not be_file }
|
||||
end
|
||||
|
||||
describe service('agent_02.service') do
|
||||
it { should be_running }
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
require 'serverspec'
|
||||
|
||||
set :backend, :exec
|
||||
|
||||
if os[:family] == 'darwin'
|
||||
home_dir = '/Users/vagrant'
|
||||
else
|
||||
home_dir = '/home/vagrant'
|
||||
end
|
||||
|
||||
describe file("#{home_dir}/agents/agent_01/.agent") do
|
||||
it { should_not exist }
|
||||
end
|
||||
|
||||
describe file("#{home_dir}/agents/agent_02/.agent") do
|
||||
it { should be_file }
|
||||
end
|
||||
|
||||
describe service('agent2'), :unless => os[:family] == 'darwin' do
|
||||
it { should be_running }
|
||||
end
|
Загрузка…
Ссылка в новой задаче