Merge pull request #3 from Microsoft/migrate-to-crossplatform-vsts-agent

Migrate to crossplatform vsts agent
This commit is contained in:
ivadim 2016-06-29 16:53:59 +02:00 коммит произвёл GitHub
Родитель 9d478b9ed3 49a73265cb
Коммит 704e8bf20b
36 изменённых файлов: 735 добавлений и 911 удалений

Просмотреть файл

@ -16,11 +16,11 @@ platforms:
driver_config: driver_config:
box: debian/jessie64 box: debian/jessie64
provisioner: provisioner:
require_chef_omnibus: 11.18.6 require_chef_omnibus: 12.4.3
- name: ubuntu1404 - name: ubuntu1604
driver_config: driver_config:
box: ubuntu/trusty64 box: ubuntu/xenial64
provisioner: provisioner:
require_chef_omnibus: 12.4.3 require_chef_omnibus: 12.4.3
@ -51,37 +51,41 @@ platforms:
communicator: 'winrm' communicator: 'winrm'
box: win81x64-enterprise #private box: win81x64-enterprise #private
provisioner: provisioner:
require_chef_omnibus: 11.18.6 require_chef_omnibus: 12.4.3
suites: suites:
- name: xplat-basic
run_list:
- recipe[xplat-basic::default]
includes:
- debian8
- 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 - name: windows-basic
run_list: run_list:
- recipe[windows-basic::default] - recipe[windows-basic::default]
includes: includes:
- windows10 - windows10
- windows81
attributes: attributes:
vsts_build_agent_test: vsts_agent_test:
vsts_url: <%= ENV['VSTS_URL'] %>
vsts_pool: <%= ENV['VSTS_POOL'] %>
vsts_token: <%= ENV['VSTS_TOKEN'] %>
- name: debian-basic
run_list:
- recipe[debian-basic::default]
includes:
- debian8
- ubuntu1604
attributes:
vsts_agent_test:
vsts_url: <%= ENV['VSTS_URL'] %>
vsts_pool: <%= ENV['VSTS_POOL'] %>
vsts_token: <%= ENV['VSTS_TOKEN'] %>
- name: osx-basic
run_list:
- recipe[osx-basic::default]
includes:
- osx109-desktop
attributes:
vsts_agent_test:
vsts_url: <%= ENV['VSTS_URL'] %> vsts_url: <%= ENV['VSTS_URL'] %>
vsts_pool: <%= ENV['VSTS_POOL'] %> vsts_pool: <%= ENV['VSTS_POOL'] %>
vsts_user: <%= ENV['VSTS_USER'] %>
vsts_token: <%= ENV['VSTS_TOKEN'] %> vsts_token: <%= ENV['VSTS_TOKEN'] %>

Просмотреть файл

@ -11,3 +11,11 @@ Style/SpaceBeforeFirstArg:
HashSyntax: HashSyntax:
EnforcedStyle: hash_rockets EnforcedStyle: hash_rockets
Exclude:
- '**/Berksfile'
Metrics/MethodLength:
Max: 20
Metrics/AbcSize:
Max: 20

Просмотреть файл

@ -1,8 +1,11 @@
source 'https://supermarket.chef.io' source 'https://supermarket.chef.io'
cookbook 'ark', git: 'git://github.com/ivadim/ark.git'
metadata metadata
group :integration do group :integration do
cookbook 'debian-basic', :path => './test/cookbooks/debian-basic'
cookbook 'windows-basic', :path => './test/cookbooks/windows-basic' cookbook 'windows-basic', :path => './test/cookbooks/windows-basic'
cookbook 'xplat-basic', :path => './test/cookbooks/xplat-basic' cookbook 'osx-basic', :path => './test/cookbooks/osx-basic'
end end

Просмотреть файл

@ -2,7 +2,7 @@
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. 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? ## General feedback and discussions?
Please start a discussion on the [issue tracker](https://github.com/Microsoft/vsts-build-agent-cookbook/issues). Please start a discussion on the [issue tracker](https://github.com/Microsoft/vsts-agent-cookbook/issues).
## Contributing code and content ## Contributing code and content
Get familiar with github pull requests https://help.github.com/articles/using-pull-requests/ Get familiar with github pull requests https://help.github.com/articles/using-pull-requests/

Просмотреть файл

@ -1,4 +1,4 @@
vsts-build-agent-cookbook vsts-agent-cookbook
Copyright (c) Microsoft Corporation Copyright (c) Microsoft Corporation
All rights reserved. All rights reserved.

149
README.md
Просмотреть файл

@ -1,144 +1,87 @@
Visual Studio Team Services Build Agent Cookbook Visual Studio Team Services Build and Release Agent Cookbook
================ ================
[![Join the chat at https://gitter.im/Microsoft/vsts-build-agent-cookbook](https://badges.gitter.im/Microsoft/vsts-build-agent-cookbook.svg)](https://gitter.im/Microsoft/vsts-build-agent-cookbook?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/Microsoft/vsts-agent-cookbook](https://badges.gitter.im/Microsoft/vsts-agent-cookbook.svg)](https://gitter.im/Microsoft/vsts-agent-cookbook?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/Microsoft/vsts-build-agent-cookbook.svg?branch=master)](https://travis-ci.org/Microsoft/vsts-build-agent-cookbook) [![Build Status](https://travis-ci.org/Microsoft/vsts-agent-cookbook.svg?branch=master)](https://travis-ci.org/Microsoft/vsts-agent-cookbook)
[![Cookbook Version](https://img.shields.io/cookbook/v/vsts_build_agent.svg)](https://supermarket.chef.io/cookbooks/vsts_build_agent) [![Cookbook Version](https://img.shields.io/cookbook/v/vsts_agent.svg)](https://supermarket.chef.io/cookbooks/vsts_agent)
Installs and configures Visual Studio Team Services [Build Agent](https://www.visualstudio.com/en-us/get-started/build/build-your-app-vs) (a.k.a VSO Build Agent) Installs and configures Visual Studio Team Services [Build and Release Agent](https://github.com/Microsoft/vsts-agent/)
Please check [Wiki](https://github.com/Microsoft/vsts-build-agent-cookbook/wiki) for more examples Please check [Wiki](https://github.com/Microsoft/vsts-agent-cookbook/wiki) for more examples
Requirements Requirements
------------ ------------
- Chef 11 or higher - Chef 12 or higher
### Platforms ### Platforms
The following platforms are tested and supported: The following platforms are tested and supported:
- Debian 7 (Wheezy) - Debian 8 x64 (Jessie)
- Ubuntu 14.04 - Ubuntu 16.04
- CentOS 6
- Windows 8.1
- Windows 10 - Windows 10
- Mac OS X 10.9.5 - Mac OS X 10.11.4
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 Attributes
---------- ----------
* `node['vsts_agent']['binary']['version']` - set version of package to install
* `node['vsts_build_agent']['xplat']['package_name']` - Set an xplat build agent [npm](https://www.npmjs.com/package/vsoagent-installer) package name * `node['vsts_agent']['prerequisites']['osx']['install']` - control osx dependencies installation. Default true
* `node['vsts_build_agent']['xplat']['package_version']` - Set an npm package version. Possible values 'x.y.z' or 'latest' * `node['vsts_agent']['prerequisites']['debian']['install']` - control debian dependencies installation. Default true
* `node['vsts_build_agent']['xplat']['skip_vsoagent_installer']` - Set to 'true' if you need another way to install npm package.
Resource/Provider Resource/Provider
----------------- -----------------
### windows ### vsts_agent
This resource installs and configures a build agent on windows host This resource installs and configures the vsts build and release agent
#### Actions #### Actions
- `:install`: Install and configure a build agent - `:install`: Install and configure the agent
- `:remove`: Remove a build agent and unregister it from VSTS - `:remove`: Remove the agent and unregister it from VSTS
- `:restart`: Restart a build agent service - `:restart`: Restart the agent service
#### Parameters #### Parameters
- `agent_name`: Name attribute. The name of a build agent - `agent_name`: Name attribute. The name of the vsts agent
- `install_dir`: A target directory to install a build agent - `version`: an agent version to install. Default version from an attribute
- `sv_name`: Set a windows service name. Default vsoagent.host.agent_name - `install_dir`: A target directory to install the vsts agent
- `sv_user`: Set a user name to run windows service. Possible values are "NT AUTHORITY\\NetworkService", "NT AUTHORITY\\LocalService" or any system valid username - `user`: Set a local user to run the vsts agent
- `sv_password`: Set password with sv_user unless it is equal to NetworkService or LocalService - `group`: Set a local group to run the vsts agent
- `vsts_url`: A target VSTS url - `runasservice`: run agent as a service. Default 'true'
- `vsts_user`: A user to connect with VSTS - `windowslogonaccount`: Set a user name to run a windows service. Possible values are "NT AUTHORITY\NetworkService", "NT AUTHORITY\LocalService" or any system valid username
- `vsts_token`: A personal access token from VSTS. [See](http://roadtoalm.com/2015/07/22/using-personal-access-tokens-to-access-visual-studio-online/) - `windowslogonpassword`: Set password for windowslogonaccount unless it is equal to NetworkService or LocalService
- `vsts_pool`: A pool name on VSTS - `vsts_url`: url to VSTS instance
- `vsts_pool`: A pool to connect an agent
- `vsts_auth`: Authentication type. Valid options are PAT (Personal Access Token), Negotiate (Kerberos or NTLM), Integrated (Windows default credentials) and ALT (Alternate Credentials). Default PAT auth
- `vsts_token`: A personal access token for VSTS. Used with PAT auth type. [See](http://roadtoalm.com/2015/07/22/using-personal-access-tokens-to-access-visual-studio-online/)
- `vsts_username`: A user to connect to VSTS. Used with Negotiate and ALT auth
- `vsts_password`: A user to connect to VSTS. Used with Negotiate and ALT auth
- `work_folder`: Set different workspace location. Default is "install_dir/\_work" - `work_folder`: Set different workspace location. Default is "install_dir/\_work"
#### Examples #### Examples
Install, configure, restart and remove a build agent. Install, configure, restart and remove an agent.
Check [tests](test/cookbooks/windows-basic/recipes/default.rb) for more examples. Check [windows](test/cookbooks/windows-basic/recipes/default.rb), [debian](test/cookbooks/debian-basic/recipes/default.rb) or [osx](test/cookbooks/osx-basic/recipes/default.rb) tests for more examples.
```ruby ```ruby
include_recipe 'vsts_build_agent::default' include_recipe 'vsts_agent::default'
vsts_build_agent_windows 'agent' do if platform_family?('windows')
install_dir 'c:\\agents\\agent1' dir = 'c:\\agents'
sv_user 'vagrant' else
sv_password 'vagrant' dir = '/tmp/agents'
vsts_url 'https://<account>.visualstudio.com'
vsts_pool 'default'
vsts_user 'builder'
vsts_token 'my_secret_token_from_vsts'
action :install
end end
vsts_build_agent_windows 'agent' do vsts_agent 'agent_01' do
action :restart install_dir dir
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/xplat-basic/recipes/default.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' user 'vagrant'
group 'vagrant' group 'vagrant'
sv_envs( vsts_url 'https://contoso.visualstudio.com'
'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_pool 'default'
vsts_user 'builder'
vsts_token 'my_secret_token_from_vsts' vsts_token 'my_secret_token_from_vsts'
windowslogonaccount 'builder' # will be used only on windows
windowslogonpassword 'Pas$w0r_d' # will be used only on windows
action :install action :install
end end
vsts_build_agent_xplat 'xplat_agent' do vsts_agent 'agent_01' do
action :restart action :restart
end end
vsts_build_agent_xplat 'xplat_agent' do vsts_agent 'agent_01' do
vsts_token 'my_secret_token_from_vsts' vsts_token 'my_secret_token_from_vsts'
action :remove action :remove
end end

Просмотреть файл

@ -44,9 +44,7 @@ kitchen verify PLATFORM
``` ```
Available platforms: Available platforms:
* debian7 (public) * debian8 (public)
* ubuntu1404 (public) * ubuntu1604 (public)
* centos6 (public)
* osx109-desktop (private) * osx109-desktop (private)
* windows10 (private) * windows10 (private)
* windows81 (private)

Просмотреть файл

@ -1,3 +1,19 @@
default['vsts_build_agent']['xplat']['package_name'] = 'vsoagent-installer' default['vsts_agent']['binary']['version'] = '2.102.1'
default['vsts_build_agent']['xplat']['package_version'] = 'latest'
default['vsts_build_agent']['xplat']['skip_vsoagent_installer'] = false case node['platform_family']
when 'windows'
default['vsts_agent']['binary']['url'] = 'https://github.com/Microsoft/vsts-agent/releases/download/v%s/vsts-agent-win7-x64-%s.zip'
when 'rhel'
default['vsts_agent']['binary']['url'] = 'https://github.com/Microsoft/vsts-agent/releases/download/v%s/vsts-agent-rhel.7.2-x64-%s.tar.gz'
when 'debian'
default['vsts_agent']['binary']['url'] = 'https://github.com/Microsoft/vsts-agent/releases/download/v%s/vsts-agent-ubuntu.14.04-x64-%s.tar.gz'
when 'mac_os_x', 'mac_os_x_server'
default['vsts_agent']['binary']['url'] = 'https://github.com/Microsoft/vsts-agent/releases/download/v%s/vsts-agent-osx.10.11-x64-%s.tar.gz'
end
default['vsts_agent']['prerequisites']['osx']['install'] = true
default['vsts_agent']['prerequisites']['osx']['openssl']['url'] = 'https://www.openssl.org/source/openssl-1.0.2h.tar.gz'
default['vsts_agent']['prerequisites']['osx']['openssl']['version'] = '1.0.2h'
default['vsts_agent']['prerequisites']['debian']['install'] = true
default['vsts_agent']['prerequisites']['debian']['libicu52']['url'] = 'http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu52_52.1-8ubuntu0.2_amd64.deb'

Просмотреть файл

@ -1,57 +0,0 @@
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);
});

Просмотреть файл

@ -1,91 +1,134 @@
module VSTS module VSTS
module Build module Build
module Agent module Agent
# Helper methods for VSTS Build Agent installation # Helper methods for VSTS Build Agent installation
module Helpers module Helpers
VARS_TO_SAVE = %w(vsts_url vsts_pool vsts_user install_dir sv_name sv_session user group user_home).freeze include Chef::DSL::PlatformIntrospection
def agent_installed?(resource, node) require 'json'
agent_attribute?(resource.agent_name, node) &&
(::File.exist?("#{resource.install_dir}/.agent") || VARS_TO_SAVE = %w(install_dir version user group).freeze
::File.file?("#{resource.install_dir}\\Agent\\VsoAgent.exe"))
end
def service_name(resource) def service_name(resource)
return resource.sv_name if resource.sv_name
return nil unless resource.vsts_url return nil unless resource.vsts_url
hostname = URI.parse(resource.vsts_url).host hostname = URI.parse(resource.vsts_url).host
hostname = hostname[0, hostname.index('.')] if hostname.include?('.') hostname = hostname[0, hostname.index('.')] if hostname.include?('.')
"vsoagent.#{hostname}.#{resource.agent_name}" if windows?
"vstsagent.#{hostname}.#{resource.agent_name}"
else
"vsts.agent.#{hostname}.#{resource.agent_name}"
end
end end
def get_npm_install_cmd(node) def service_config(resource)
npm_cmd = "npm install -global #{node['vsts_build_agent']['xplat']['package_name']}" service_name = service_name(resource)
unless node['vsts_build_agent']['xplat']['package_version'] == 'latest' if osx?
npm_cmd += "@#{node['vsts_build_agent']['xplat']['package_version']}" "/Users/#{resource.user}/Library/LaunchAgents/#{service_name}.plist"
else
"/etc/systemd/system/#{service_name}.service"
end end
npm_cmd
end end
def save_current_state(resource, node) def archive_name(resource)
VARS_TO_SAVE.each do |var| name = 'vsts_agent'
node.set['vsts_build_agent']['agents'][resource.agent_name][var] = resource.send(var) if resource.respond_to?(var.to_sym) name += '_' + resource.version if resource.version
end name
end
def download_url(version, node)
url = node['vsts_agent']['binary']['url']
url = url.gsub '%s', version
url
end
def windows?
platform_family?('windows')
end
def debian?
platform_family?('debian')
end
def rhel?
platform_family?('rhel')
end
def osx?
platform_family?('mac_os_x') || platform_family?('mac_os_x_server')
end
def save_vars(resource, node)
VARS_TO_SAVE.each { |var| node.set['vsts_agent']['agents'][resource.agent_name][var] = resource.send(var) if resource.respond_to?(var.to_sym) }
node.save node.save
end end
def load_vars(resource, node)
VARS_TO_SAVE.each { |var| resource.send(var, node['vsts_agent']['agents'][resource.agent_name][var]) if resource.respond_to?(var.to_sym) }
end
def load_current_state(resource, node) def load_current_state(resource, node)
return unless agent_attribute?(resource.agent_name, node) resource.exists = false
VARS_TO_SAVE.each do |var| if agent_attribute?(resource.agent_name, node)
resource.send(var, node['vsts_build_agent']['agents'][resource.agent_name][var]) if resource.respond_to?(var.to_sym) load_vars(resource, node)
if ::File.exist?(::File.join(resource.install_dir, '.agent'))
load_data_from_json(resource)
resource.runasservice(::File.exist?(::File.join(resource.install_dir, '.service')))
resource.exists = true
end
end end
end end
def load_data_from_json(resource)
f = ::File.read(::File.join(resource.install_dir, '.agent'), :mode => 'r:bom|utf-8').strip
agent = JSON.parse(f)
resource.vsts_url(agent['serverUrl'])
resource.vsts_pool(agent['poolName'])
resource.work_folder(agent['workFolder'])
end
def agent_attribute?(agent_name, node) def agent_attribute?(agent_name, node)
node['vsts_build_agent']['agents'] && node['vsts_build_agent']['agents'][agent_name] if node['vsts_agent']['agents'].nil? ||
node['vsts_agent']['agents'][agent_name].nil? ||
node['vsts_agent']['agents'][agent_name]['install_dir'].nil? ||
node['vsts_agent']['agents'][agent_name]['install_dir'].empty?
return false
else
return true
end
end end
def remove_current_state(resource, node) def remove_current_state(resource, node)
node.set['vsts_build_agent']['agents'][resource.agent_name] = {} node.set['vsts_agent']['agents'][resource.agent_name] = {}
node.save node.save
end end
def plist_path(resource) def set_auth(args, resource)
path = if resource.sv_session args['auth'] = resource.vsts_auth
"/Library/LaunchAgents/#{resource.sv_name}.plist" if resource.vsts_auth == 'PAT'
else args['token'] = resource.vsts_token
"/Library/LaunchDaemons/#{resource.sv_name}.plist" elsif (resource.vsts_auth == 'Negotiate') || (resource.vsts_auth == 'ALT')
end args['--username'] = resource.vsts_username
args['--password'] = resource.vsts_password
path = "#{resource.user_home}#{path}" if resource.user_home end
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 end
def vsagentexec(args = {}) def vsagentexec(args = {})
command = 'Agent\\VsoAgent.exe ' command = 'Agent.Listener '
args.each do |key, value| command = './' + command unless windows?
command += "/#{key}" args.each { |key, value| command += append_arguments(key, value) + ' ' }
command += ":\"#{value}\"" unless value.nil?
command += ' '
end
command command
end end
def append_arguments(key, value)
result = ''
if key == 'configure' || key == 'remove'
result += key
else
result += "--#{key}"
result += " \"#{value}\"" unless value.nil?
end
result
end
end end
end end
end end

Просмотреть файл

@ -1,18 +1,17 @@
name 'vsts_build_agent' name 'vsts_agent'
maintainer 'Microsoft' maintainer 'Microsoft'
maintainer_email 'dmivanov@microsoft.com' maintainer_email 'dmivanov@microsoft.com'
license 'MIT' license 'MIT'
description 'Installs/Configures visualstudio team services build agents' description 'Installs/Configures visualstudio team services build agents'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
source_url 'https://github.com/Microsoft/vsts-build-agent-cookbook' if respond_to?(:source_url) source_url 'https://github.com/Microsoft/vsts-agent-cookbook' if respond_to?(:source_url)
issues_url 'https://github.com/Microsoft/vsts-build-agent-cookbook/issues' if respond_to?(:issues_url) issues_url 'https://github.com/Microsoft/vsts-agent-cookbook/issues' if respond_to?(:issues_url)
version '0.1.3' version '1.0.0'
%w( ubuntu debian mac_os_x mac_os_x_server windows ).each do |os| %w( ubuntu debian mac_os_x mac_os_x_server windows ).each do |os|
supports os supports os
end end
suggests 'nodejs'
depends 'runit'
depends 'windows' depends 'windows'
depends 'ark'
depends 'seven_zip', '~> 2.0.0'

225
providers/default.rb Normal file
Просмотреть файл

@ -0,0 +1,225 @@
require 'chef/mixin/shell_out'
require 'json'
include ::VSTS::Build::Agent::Helpers
include ::Windows::Helper
use_inline_resources
def whyrun_supported?
true
end
def load_current_resource
@current_resource = Chef::Resource::VstsAgent.new(@new_resource.name)
@current_resource.agent_name(@new_resource.agent_name)
load_current_state(@current_resource, node)
@current_resource
end
action :install do
condidate_version = new_resource.version || node['vsts_agent']['binary']['version']
need_upgrade = current_resource.version != condidate_version
if @current_resource.exists && !need_upgrade
Chef::Log.info "'#{new_resource.agent_name}' agent '#{current_resource.version}' already exists - nothing to do"
else
converge_by("Installing agent '#{new_resource.agent_name}' version '#{condidate_version}'") do
version = condidate_version
archive_url = download_url(version, node)
archive_name = archive_name(new_resource)
unpack_dir = ::File.join(Chef::Config[:file_cache_path], 'unpack_agent')
unpack_dir = win_friendly_path(unpack_dir) if windows?
if current_resource.exists && need_upgrade
Chef::Log.info "'#{new_resource.agent_name}' agent will be upgradet to version '#{current_resource.version}'"
remove_agent(current_resource, new_resource)
end
config = service_config(new_resource)
execute "Remove service config file #{config}" do
command "rm -rf #{config}"
action :run
not_if { windows? }
end
directory unpack_dir do
recursive true
action :delete
end
ark archive_name do
url archive_url
backup false
path unpack_dir
owner new_resource.user
strip_components 0 if windows?
action :put
end
directory new_resource.install_dir do
recursive true
rights :full_control, new_resource.user, :applies_to_children => true if windows?
user new_resource.user
group new_resource.group
mode '0755'
action :create
end
execute "Move #{new_resource.agent_name} agent from intermidiate folder" do
command "cp -r #{unpack_dir}/#{archive_name}/* #{new_resource.install_dir}" unless windows?
command "xcopy #{unpack_dir}\\#{archive_name}\\* #{win_friendly_path(new_resource.install_dir)} /s /e" if windows?
action :run
end
args = {
'configure' => nil,
'unattended' => nil,
'replace' => nil,
'url' => new_resource.vsts_url,
'pool' => new_resource.vsts_pool,
'agent' => new_resource.agent_name,
'work' => new_resource.work_folder
}
if new_resource.runasservice
args['runasservice'] = nil
if windows?
args['windowslogonaccount'] = new_resource.windowslogonaccount
end
if windows? && new_resource.windowslogonpassword
args['windowslogonpassword'] = new_resource.windowslogonpassword
end
else
args['nostart'] = nil
end
set_auth(args, new_resource)
execute "Configuring agent '#{new_resource.agent_name}'" do
cwd "#{new_resource.install_dir}/bin"
sensitive true if respond_to?(:sensitive)
command vsagentexec(args)
action :run
end
execute "Fix permissions for agent '#{new_resource.agent_name}'" do
command "chown -R #{new_resource.user}:#{new_resource.group} #{new_resource.install_dir}"
action :run
not_if { windows? }
end
directory "/Users/#{new_resource.user}/Library/LaunchAgents" do
owner new_resource.user
group new_resource.group
mode '0755'
action :create
only_if { osx? }
end
manage_service("install #{new_resource.user}", new_resource) if new_resource.runasservice
manage_service('restart', new_resource) if new_resource.runasservice
ruby_block "save state for agent '#{new_resource.agent_name}'" do
block do
save_vars(new_resource, node)
Chef::Log.info "'#{new_resource.agent_name}' agent was installed"
end
action :run
end
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
remove_agent(current_resource, new_resource)
ruby_block "remove state for agent '#{current_resource.agent_name}'" do
block do
remove_current_state(current_resource, node)
Chef::Log.info "'#{current_resource.agent_name}' agent was removed"
end
action :run
end
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
manage_service('restart', current_resource) if current_resource.runasservice
log "'#{current_resource.agent_name}' agent was restarted"
new_resource.updated_by_last_action(true)
end
end
end
def remove_agent(current_resource, new_resource)
manage_service('uninstall', current_resource) if current_resource.runasservice
args = {
'remove' => nil,
'unattended' => nil
}
set_auth(args, new_resource)
execute "Unconfiguring agent '#{current_resource.agent_name}'" do
cwd "#{current_resource.install_dir}/bin"
command vsagentexec(args)
sensitive true if respond_to?(:sensitive)
action :run
end
directory current_resource.install_dir do
recursive true
action :delete
end
end
def manage_service(operation, resource)
if windows?
manage_windows_service(operation, resource)
else
manage_unix_service(operation, resource)
end
end
def manage_windows_service(operation, resource)
if operation == 'restart' || operation == 'stop'
a = [operation.to_sym]
elsif operation == 'uninstall'
a = [:stop, :disable]
else
return # unsupported operations
end
sn = service_name(resource)
service sn do
action a
ignore_failure true
end
end
def manage_unix_service(operation, resource)
cmd = if operation == 'restart'
'./svc.sh stop && ./svc.sh start'
elsif operation == 'uninstall'
'./svc.sh stop && ./svc.sh uninstall'
else
"./svc.sh #{operation}"
end
envvars = { 'HOME' => "/Users/#{resource.user}" }
execute "Run action '#{operation}' on service for '#{resource.agent_name}'" do
cwd resource.install_dir
command cmd
user resource.user if osx?
group resource.group if osx?
environment envvars if osx?
action :run
ignore_failure true
end
end

Просмотреть файл

@ -1,136 +0,0 @@
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

Просмотреть файл

@ -1,211 +0,0 @@
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

Просмотреть файл

@ -1,3 +1,44 @@
if %w(debian rhel fedora gentoo).include?(node['platform_family']) include_recipe 'ark::default'
include_recipe 'runit::default'
if platform_family?('debian') && node['vsts_agent']['prerequisites']['debian']['install']
package 'libunwind8'
package 'libcurl3'
if platform?('ubuntu') && node['platform_version'].to_i >= 16
remote_file "#{Chef::Config[:file_cache_path]}/libicu52_52.1-8ubuntu0.2_amd64.deb" do
source node['vsts_agent']['prerequisites']['debian']['libicu52']['url']
mode 0644
end
dpkg_package 'libicu52' do
source "#{Chef::Config[:file_cache_path]}/libicu52_52.1-8ubuntu0.2_amd64.deb"
version '52.1-8ubuntu0.2'
action :install
end
else
package 'libicu52'
end
elsif (platform_family?('mac_os_x') || platform_family?('mac_os_x_server')) && node['vsts_agent']['prerequisites']['osx']['install']
cpu = node['cpu'] ? node['cpu']['total'].to_i : 2
version = node['vsts_agent']['prerequisites']['osx']['openssl']['version']
ark 'openssl' do
url node['vsts_agent']['prerequisites']['osx']['openssl']['url']
backup false
path Chef::Config[:file_cache_path]
action :put
end
bash "Make openssl #{version}" do
cwd "#{Chef::Config[:file_cache_path]}/openssl"
code <<-EOH
./configure shared darwin64-x86_64-cc --prefix=/usr/local/openssl-#{version}
make depend
make -j #{cpu}
make install
rm -rf /usr/local/openssl /usr/local/bin/openssl
ln -s /usr/local/openssl-#{version} /usr/local/openssl
ln -s /usr/local/openssl/bin/openssl /usr/local/bin/openssl
mkdir -p /usr/local/lib
cp /usr/local/openssl/lib/lib* /usr/local/lib/
EOH
not_if "/usr/local/bin/openssl version |grep #{version}"
end
end end

27
resources/default.rb Normal file
Просмотреть файл

@ -0,0 +1,27 @@
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 :work_folder, :kind_of => String, :default => '_work'
attribute :runasservice, :kind_of => [TrueClass, FalseClass], :default => true
attribute :windowslogonaccount, :kind_of => String
attribute :windowslogonpassword, :kind_of => String
# environment
attribute :version, :kind_of => String
# VSTS Access
attribute :vsts_url, :kind_of => String
attribute :vsts_pool, :kind_of => String
attribute :vsts_auth, :kind_of => String, :default => 'PAT'
attribute :vsts_username, :kind_of => String
attribute :vsts_password, :kind_of => String
attribute :vsts_token, :kind_of => String
attr_accessor :exists

Просмотреть файл

@ -1,18 +0,0 @@
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

Просмотреть файл

@ -1,24 +0,0 @@
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

Просмотреть файл

@ -1,5 +0,0 @@
{
"poolName": "<%= @agent.vsts_pool %>",
"serverUrl": "<%= @agent.vsts_url %>",
"agentName": "<%= @agent.agent_name %>"
}

Просмотреть файл

@ -1,2 +0,0 @@
#!/bin/sh
exec svlogd -tt ./main

Просмотреть файл

@ -1,11 +0,0 @@
#!/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 %>

Просмотреть файл

@ -1,44 +0,0 @@
<?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,4 @@
# set attributes through test kitchen
default['vsts_agent_test']['vsts_url'] = nil
default['vsts_agent_test']['vsts_pool'] = nil
default['vsts_agent_test']['vsts_token'] = nil

Просмотреть файл

@ -0,0 +1,7 @@
name 'debian-basic'
version '0.0.1'
depends 'vsts_agent'
depends 'apt'
depends 'build-essential'

Просмотреть файл

@ -0,0 +1,74 @@
#### Begin prepare system ####
include_recipe 'apt::default'
include_recipe 'build-essential::default'
user 'vagrant' do
supports :manage_home => true
comment 'Vagrant user'
home '/home/vagrant'
shell '/bin/bash'
not_if 'id -u vagrant'
end
user 'builder' do
supports :manage_home => true
comment 'Builder user'
home '/home/builder'
shell '/bin/bash'
end
#### End prepare system ####
include_recipe 'vsts_agent::default'
agent1_name = "#{node['hostname']}_01"
agent2_name = "#{node['hostname']}_02"
agents_dir = '/home/vagrant/agents'
# cleanup
vsts_agent agent1_name do
vsts_token node['vsts_agent_test']['vsts_token']
action :remove
end
vsts_agent agent2_name do
vsts_token node['vsts_agent_test']['vsts_token']
action :remove
end
# Agent1
vsts_agent agent1_name do
install_dir "#{agents_dir}/#{agent1_name}"
user 'vagrant'
group 'vagrant'
vsts_url node['vsts_agent_test']['vsts_url']
vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_token node['vsts_agent_test']['vsts_token']
action :install
end
vsts_agent agent1_name do
action :restart
end
vsts_agent agent1_name do
vsts_token node['vsts_agent_test']['vsts_token']
action :remove
end
# Agent2
vsts_agent agent2_name do
version '2.102.1'
install_dir "#{agents_dir}/#{agent2_name}"
user 'builder'
group 'builder'
vsts_url node['vsts_agent_test']['vsts_url']
vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_token node['vsts_agent_test']['vsts_token']
action :install
end
vsts_agent agent2_name do
action :restart
end

Просмотреть файл

@ -0,0 +1,4 @@
# set attributes through test kitchen
default['vsts_agent_test']['vsts_url'] = nil
default['vsts_agent_test']['vsts_pool'] = nil
default['vsts_agent_test']['vsts_token'] = nil

Просмотреть файл

@ -0,0 +1,5 @@
name 'osx-basic'
version '0.0.1'
depends 'vsts_agent'
depends 'build-essential'

Просмотреть файл

@ -0,0 +1,53 @@
#### Begin prepare system ####
include_recipe 'build-essential::default'
#### End prepare system ####
include_recipe 'vsts_agent::default'
agent1_name = "osx_#{node['hostname']}_01"
agent2_name = "osx_#{node['hostname']}_02"
agents_dir = '/Users/vagrant/agents'
# cleanup
vsts_agent agent1_name do
vsts_token node['vsts_agent_test']['vsts_token']
action :remove
end
# Agent1
vsts_agent agent1_name do
version '2.102.0'
install_dir "#{agents_dir}/#{agent1_name}"
user 'vagrant'
group 'staff'
vsts_url node['vsts_agent_test']['vsts_url']
vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_token node['vsts_agent_test']['vsts_token']
action :install
end
vsts_agent agent1_name do
action :restart
end
vsts_agent agent1_name do
vsts_token node['vsts_agent_test']['vsts_token']
action :remove
end
# Agent2
vsts_agent agent2_name do
version '2.102.1'
install_dir "#{agents_dir}/#{agent2_name}"
user 'vagrant'
group 'staff'
vsts_url node['vsts_agent_test']['vsts_url']
vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_token node['vsts_agent_test']['vsts_token']
action :install
end
vsts_agent agent2_name do
action :restart
end

Просмотреть файл

@ -1,5 +1,4 @@
# set attributes through test kitchen # set attributes through test kitchen
default['vsts_build_agent_test']['vsts_url'] = nil default['vsts_agent_test']['vsts_url'] = nil
default['vsts_build_agent_test']['vsts_pool'] = nil default['vsts_agent_test']['vsts_pool'] = nil
default['vsts_build_agent_test']['vsts_user'] = nil default['vsts_agent_test']['vsts_token'] = nil
default['vsts_build_agent_test']['vsts_token'] = nil

Просмотреть файл

@ -1,5 +1,5 @@
name 'windows-basic' name 'windows-basic'
version '0.0.1' version '0.0.1'
depends 'vsts_build_agent' depends 'vsts_agent'
depends 'windows' depends 'grant_logon_as_service'

Просмотреть файл

@ -1,73 +1,87 @@
include_recipe 'vsts_build_agent::default' #### Begin prepare system ####
user 'builder' do
comment 'Builder user'
home '/home/builder'
shell '/bin/bash'
password 'Pas$w0r_d'
end
agent_prefix = node['hostname'] grant_logon_as_service 'vagrant'
sys_user = 'vagrant' grant_logon_as_service 'builder'
sys_passwd = 'vagrant'
# clean previous run #### End prepare system ####
vsts_build_agent_windows "#{agent_prefix}_01" do
vsts_token node['vsts_build_agent_test']['vsts_token'] include_recipe 'vsts_agent::default'
agent1_name = "win_#{node['hostname']}_01"
agent2_name = "win_#{node['hostname']}_02"
agent3_name = "win_#{node['hostname']}_03"
agents_dir = 'C:\\Users\\vagrant\\agents'
# cleanup
vsts_agent agent1_name do
vsts_token node['vsts_agent_test']['vsts_token']
action :remove action :remove
end end
vsts_build_agent_windows "#{agent_prefix}_02" do vsts_agent agent2_name do
vsts_token node['vsts_build_agent_test']['vsts_token'] vsts_token node['vsts_agent_test']['vsts_token']
action :remove action :remove
end end
vsts_build_agent_windows "#{agent_prefix}_03" do vsts_agent agent3_name do
install_dir "c:\\agents\\#{agent_prefix}_03" vsts_token node['vsts_agent_test']['vsts_token']
vsts_user node['vsts_build_agent_test']['vsts_user']
vsts_token node['vsts_build_agent_test']['vsts_token']
action :remove action :remove
end end
# install agents # Agent1
# agent with default service name vsts_agent agent1_name do
vsts_build_agent_windows "#{agent_prefix}_01" do version '2.102.0'
install_dir 'c:\\agents\\agent_01' install_dir "#{agents_dir}/#{agent1_name}"
sv_user sys_user user 'vagrant'
sv_password sys_passwd vsts_url node['vsts_agent_test']['vsts_url']
vsts_url node['vsts_build_agent_test']['vsts_url'] vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_pool node['vsts_build_agent_test']['vsts_pool'] vsts_token node['vsts_agent_test']['vsts_token']
vsts_user node['vsts_build_agent_test']['vsts_user'] windowslogonaccount 'vagrant'
vsts_token node['vsts_build_agent_test']['vsts_token'] windowslogonpassword 'vagrant'
action :install action :install
end end
vsts_build_agent_windows "#{agent_prefix}_01" do vsts_agent agent1_name do
action :restart action :restart
end end
# agent with overriden service name vsts_agent agent1_name do
# run as Local Service user vsts_token node['vsts_agent_test']['vsts_token']
vsts_build_agent_windows "#{agent_prefix}_02" do action :remove
install_dir 'c:\\agents\\agent_02' end
sv_user 'NT AUTHORITY\\LocalService'
sv_name 'agent_02.service' # Agent2
vsts_url node['vsts_build_agent_test']['vsts_url'] vsts_agent agent2_name do
vsts_pool node['vsts_build_agent_test']['vsts_pool'] version '2.102.0'
vsts_user node['vsts_build_agent_test']['vsts_user'] install_dir "#{agents_dir}/#{agent2_name}"
vsts_token node['vsts_build_agent_test']['vsts_token'] user 'builder'
vsts_url node['vsts_agent_test']['vsts_url']
vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_token node['vsts_agent_test']['vsts_token']
windowslogonaccount 'NT AUTHORITY\\NetworkService'
action :install action :install
end end
vsts_build_agent_windows "#{agent_prefix}_02" do vsts_agent agent2_name do
action :restart action :restart
end end
# agent to remove # Agent3
vsts_build_agent_windows "#{agent_prefix}_03" do vsts_agent agent3_name do
install_dir 'c:\\agents\\agent_03' version '2.102.1'
sv_user 'NT AUTHORITY\\NetworkService' install_dir "#{agents_dir}/#{agent3_name}"
vsts_url node['vsts_build_agent_test']['vsts_url'] user 'builder'
vsts_pool node['vsts_build_agent_test']['vsts_pool'] vsts_url node['vsts_agent_test']['vsts_url']
vsts_user node['vsts_build_agent_test']['vsts_user'] vsts_pool node['vsts_agent_test']['vsts_pool']
vsts_token node['vsts_build_agent_test']['vsts_token'] vsts_token node['vsts_agent_test']['vsts_token']
windowslogonaccount 'builder'
windowslogonpassword 'Pas$w0r_d'
action :install action :install
end end
vsts_build_agent_windows "#{agent_prefix}_03" do
vsts_token node['vsts_build_agent_test']['vsts_token']
action :remove
end

Просмотреть файл

@ -1,11 +0,0 @@
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

Просмотреть файл

@ -1,10 +0,0 @@
name 'xplat-basic'
version '0.0.1'
depends 'vsts_build_agent'
depends 'apt'
depends 'build-essential'
depends 'nodejs'
depends 'runit'
depends 'homebrew'

Просмотреть файл

@ -1,94 +0,0 @@
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

Просмотреть файл

@ -1,20 +0,0 @@
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

Просмотреть файл

@ -2,20 +2,20 @@ require 'serverspec'
set :backend, :exec set :backend, :exec
home_dir = if os[:family] == 'darwin' # home_dir = if os[:family] == 'darwin'
'/Users/vagrant' # '/Users/vagrant'
else # else
'/home/vagrant' # '/home/vagrant'
end # end
describe file("#{home_dir}/agents/agent_01/.agent") do # describe file("#{home_dir}/agents/agent_01/.agent") do
it { should_not exist } # it { should_not exist }
end # end
describe file("#{home_dir}/agents/agent_02/.agent") do # describe file("#{home_dir}/agents/agent_02/.agent") do
it { should be_file } # it { should be_file }
end # end
describe service('agent2'), :unless => os[:family] == 'darwin' do # describe service('agent2'), :unless => os[:family] == 'darwin' do
it { should be_running } # it { should be_running }
end # end