Merge pull request #3 from Microsoft/migrate-to-crossplatform-vsts-agent
Migrate to crossplatform vsts agent
This commit is contained in:
Коммит
704e8bf20b
54
.kitchen.yml
54
.kitchen.yml
|
@ -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
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
|
||||||
|
|
13
metadata.rb
13
metadata.rb
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче