qb 0.1.60 → 0.1.61
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/qb/options.rb +6 -6
- data/lib/qb/role.rb +20 -33
- data/lib/qb/role/errors.rb +30 -0
- data/lib/qb/version.rb +1 -1
- data/library/path_facts +304 -0
- data/plugins/lookup_plugins/every.py +165 -0
- data/roles/qb.facts/defaults/main.yml +3 -0
- data/roles/{qb.yarn → qb.facts}/meta/main.yml +1 -1
- data/roles/{qb.yarn → qb.facts}/meta/qb.yml +21 -26
- data/roles/qb.facts/tasks/main.yml +10 -0
- data/roles/qb.git_repo/defaults/main.yml +1 -0
- data/roles/qb.git_repo/meta/main.yml +1 -9
- data/roles/qb.git_repo/tasks/main.yml +26 -1
- data/roles/qb.qb_role/templates/qb.yml.j2 +8 -0
- data/roles/qb.role/defaults/main.yml +1 -1
- data/roles/qb.role/tasks/main.yml +1 -1
- data/roles/qb.yarn_release/defaults/main.yml +4 -0
- data/roles/{qb.release_yarn → qb.yarn_release}/meta/main.yml +1 -1
- data/roles/{qb.release_yarn → qb.yarn_release}/meta/qb.yml +1 -1
- data/roles/qb.yarn_release/tasks/main.yml +73 -0
- data/roles/qb.yarn_setup/defaults/main.yml +11 -0
- data/roles/qb.yarn_setup/meta/main.yml +8 -0
- data/roles/qb.yarn_setup/meta/qb.yml +100 -0
- data/roles/qb.yarn_setup/tasks/distribution/MacOSX/brew_create.yml +59 -0
- data/roles/qb.yarn_setup/tasks/distribution/MacOSX/main.yml +42 -0
- data/roles/qb.yarn_setup/tasks/main.yml +11 -0
- data/roles/qb.yarn_setup/templates/yarn@M.m.p.rb.j2 +22 -0
- metadata +20 -12
- data/lib/qb/options/errors.rb +0 -11
- data/roles/qb.release_yarn/defaults/main.yml +0 -4
- data/roles/qb.release_yarn/tasks/main.yml +0 -73
- data/roles/qb.yarn/defaults/main.yml +0 -5
- data/roles/qb.yarn/tasks/distribution/MacOSX.yml +0 -7
- data/roles/qb.yarn/tasks/main.yml +0 -11
@@ -0,0 +1,165 @@
|
|
1
|
+
"""
|
2
|
+
DOCUMENTATION:
|
3
|
+
lookup: every
|
4
|
+
version_added: "QB-0.1.61"
|
5
|
+
short_description: Returns true for a key every X time delta (per host).
|
6
|
+
description:
|
7
|
+
- Returns `True` if more than a specified amount of time has passed
|
8
|
+
since it last returned `True` for that key for the current
|
9
|
+
`inventory_hostname` fact.
|
10
|
+
|
11
|
+
If it's never returned `True` for the `key` / `inventory_hostname`
|
12
|
+
combo it will.
|
13
|
+
|
14
|
+
This is useful to control updating - things like "run
|
15
|
+
`apt-get update` if it doesn't look like it's been run in a day",
|
16
|
+
etcetera.
|
17
|
+
|
18
|
+
** WARNING: NOT AT ALL THREAD / CONCURRENCY SAFE **
|
19
|
+
|
20
|
+
This is meant for things that you're *rather not* have run too
|
21
|
+
often, it is not indented for and should not be used for
|
22
|
+
controlling stuff that *must not* be run more than a certain
|
23
|
+
frequency because it's a shit-simple implementation with
|
24
|
+
**NO LOCKING / CONCURRENCY SUPPORT** so if another thread or
|
25
|
+
process is trying to do the same thing at the same time they will
|
26
|
+
potentially both return `True` or who really knows what else.
|
27
|
+
|
28
|
+
Data is stored at `~/.ansible/qb/data/every.yml`. This should
|
29
|
+
probably be configurable for for the moment it will do.
|
30
|
+
|
31
|
+
options:
|
32
|
+
key:
|
33
|
+
description:
|
34
|
+
- Required single positional argument, used as the key to
|
35
|
+
store / retrieve data.
|
36
|
+
required: True
|
37
|
+
**kwargs:
|
38
|
+
description:
|
39
|
+
- Accepts all the Python `datetime.timedelta` constructor
|
40
|
+
keywords. Requires at least one.
|
41
|
+
|
42
|
+
You can set the delta to zero (so it returns True every
|
43
|
+
call) by providing `days=0` or similar (useful to test
|
44
|
+
stuff out maybe).
|
45
|
+
required: True
|
46
|
+
EXAMPLES:
|
47
|
+
|
48
|
+
- name: Install Yarn via Homebrew, updating Homebrew at most once per day
|
49
|
+
homebrew:
|
50
|
+
name: yarn
|
51
|
+
update_homebrew: "{{ lookup('every', 'update_homebrew' days=1) }}"
|
52
|
+
|
53
|
+
RETURN:
|
54
|
+
|
55
|
+
`True` if it's been more than the provided period since the lookup returned
|
56
|
+
`True` last for this key /
|
57
|
+
|
58
|
+
"""
|
59
|
+
|
60
|
+
from __future__ import (absolute_import, division, print_function)
|
61
|
+
__metaclass__ = type
|
62
|
+
|
63
|
+
from ansible.errors import AnsibleError
|
64
|
+
from ansible.plugins.lookup import LookupBase
|
65
|
+
|
66
|
+
try:
|
67
|
+
from __main__ import display
|
68
|
+
except ImportError:
|
69
|
+
from ansible.utils.display import Display
|
70
|
+
display = Display()
|
71
|
+
|
72
|
+
from datetime import datetime, timedelta
|
73
|
+
import os
|
74
|
+
import errno
|
75
|
+
import yaml
|
76
|
+
|
77
|
+
def mkdir_p(path):
|
78
|
+
"""
|
79
|
+
Can't believe Python doesn't have this built-in...
|
80
|
+
"""
|
81
|
+
try:
|
82
|
+
os.makedirs(path)
|
83
|
+
except OSError as exc:
|
84
|
+
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
85
|
+
pass
|
86
|
+
else:
|
87
|
+
raise
|
88
|
+
|
89
|
+
|
90
|
+
class LookupModule(LookupBase):
|
91
|
+
def run(self, terms, variables=None, **kwargs):
|
92
|
+
# Check args
|
93
|
+
|
94
|
+
if len(terms) != 1:
|
95
|
+
raise AnsibleError(
|
96
|
+
"Requires exacty one positional argument (key)."
|
97
|
+
)
|
98
|
+
|
99
|
+
if len(kwargs) == 0:
|
100
|
+
raise AnsibleError(
|
101
|
+
"Requires at least one Python timedelta keyword arg."
|
102
|
+
)
|
103
|
+
|
104
|
+
# Setup variables
|
105
|
+
|
106
|
+
key = terms[0]
|
107
|
+
host = variables['inventory_hostname']
|
108
|
+
|
109
|
+
data_path = os.path.join(
|
110
|
+
variables['ansible_env']['HOME'],
|
111
|
+
'.ansible',
|
112
|
+
'qb',
|
113
|
+
'data',
|
114
|
+
'every.yml'
|
115
|
+
)
|
116
|
+
|
117
|
+
delta = timedelta(**kwargs)
|
118
|
+
now = datetime.now()
|
119
|
+
|
120
|
+
# Default to empty data
|
121
|
+
data = {}
|
122
|
+
|
123
|
+
# No idea how / where to see this output...
|
124
|
+
# display.debug("Seeing if %s has been done in last %s" % (key, delta))
|
125
|
+
|
126
|
+
# Ensure the data directory exists
|
127
|
+
mkdir_p(os.path.dirname(data_path))
|
128
|
+
|
129
|
+
# Read the data file, overwriting `data` var (if file it exists)
|
130
|
+
try:
|
131
|
+
with open(data_path, 'r') as f:
|
132
|
+
data = yaml.safe_load(f)
|
133
|
+
except IOError as error:
|
134
|
+
pass
|
135
|
+
|
136
|
+
# If there's no entry for this host default to empty dict
|
137
|
+
if host not in data:
|
138
|
+
data[host] = {}
|
139
|
+
|
140
|
+
# Default `should` (our return value) to True: if it's never returned
|
141
|
+
# `True` it will now.
|
142
|
+
should = True
|
143
|
+
|
144
|
+
# If we have `data[host][key]['last']`, see if's been at least `delta`
|
145
|
+
# and set `should`
|
146
|
+
if key in data[host]:
|
147
|
+
if 'last' in data[host][key]:
|
148
|
+
should = (now - delta) >= data[host][key]['last']
|
149
|
+
else:
|
150
|
+
# Create a new dict at `data[host][key]` so we can write `now` to
|
151
|
+
# it
|
152
|
+
data[host][key] = {}
|
153
|
+
|
154
|
+
# If we're gonna return `True`, set `last` to `now` and write back
|
155
|
+
# to the path.
|
156
|
+
#
|
157
|
+
# WARNING Not at all thread / concurrency safe!
|
158
|
+
if should:
|
159
|
+
data[host][key]['last'] = now
|
160
|
+
|
161
|
+
with open(data_path, 'w') as f:
|
162
|
+
yaml.safe_dump(data, f, default_flow_style=False)
|
163
|
+
|
164
|
+
# And return our result
|
165
|
+
return should
|
@@ -1,11 +1,11 @@
|
|
1
1
|
---
|
2
|
-
# meta/qb.yml file for qb.
|
2
|
+
# meta/qb.yml file for qb.facts
|
3
3
|
#
|
4
4
|
# qb settings for this role. see README.md for more info.
|
5
5
|
#
|
6
6
|
|
7
7
|
# description of the role to show in it's help output.
|
8
|
-
description:
|
8
|
+
description: null
|
9
9
|
|
10
10
|
# prefix for role variables
|
11
11
|
var_prefix: null
|
@@ -34,39 +34,34 @@ var_prefix: null
|
|
34
34
|
# - starting at the current direcotry and climbing up to parent
|
35
35
|
# directories, use the first one that contains FILENAME. error
|
36
36
|
# if none is found.
|
37
|
-
default_dir:
|
37
|
+
default_dir: cwd
|
38
|
+
|
39
|
+
# If `true`, QB will ensure the default dir exists before starting the play.
|
40
|
+
#
|
41
|
+
# For legacy reasons, this defaults to `true` if not present, but we want to
|
42
|
+
# default declare it as `false` here so new roles can turn it on only if
|
43
|
+
# they need it.
|
44
|
+
#
|
45
|
+
mkdir: false
|
38
46
|
|
39
47
|
# default user to become for play
|
40
48
|
default_user: null
|
41
49
|
|
42
50
|
# set to false to not save options in .qb-options.yml files
|
43
|
-
save_options:
|
51
|
+
save_options: false
|
44
52
|
|
45
|
-
#
|
46
|
-
|
53
|
+
# options to pass to ansible-playbook
|
54
|
+
ansible_options: {}
|
47
55
|
|
48
|
-
options:
|
56
|
+
options:
|
49
57
|
# - name: example
|
50
58
|
# description: an example of a variable.
|
51
59
|
# required: false
|
52
60
|
# type: boolean # boolean (default) | string
|
53
61
|
# short: e
|
54
|
-
- name:
|
55
|
-
description:
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
description: >
|
61
|
-
present to install, absent to uninstall. the rest of the options are up to
|
62
|
-
you to much around with if you like.
|
63
|
-
see:
|
64
|
-
- http://docs.ansible.com/ansible/homebrew_module.html
|
65
|
-
type:
|
66
|
-
one_of:
|
67
|
-
- present
|
68
|
-
- absent
|
69
|
-
- latest
|
70
|
-
- head
|
71
|
-
- linked
|
72
|
-
- unlinked
|
62
|
+
- name: github_api
|
63
|
+
description: >-
|
64
|
+
If path is a git repo with a GitHub origin, contact the GitHub API for
|
65
|
+
additonal facts (including privacy status).
|
66
|
+
type: boolean
|
67
|
+
short: g
|
@@ -1,12 +1,4 @@
|
|
1
1
|
---
|
2
2
|
# meta file for qb.git_repo
|
3
3
|
|
4
|
-
dependencies:
|
5
|
-
- role: qb.gitignore
|
6
|
-
gitignore_name: Global/macOS
|
7
|
-
gitignore_dest: "{{ git_repo_dest }}"
|
8
|
-
when: ansible_distribution == "MacOSX"
|
9
|
-
|
10
|
-
- role: qb.gitignore
|
11
|
-
gitignore_name: QB
|
12
|
-
gitignore_dest: "{{ git_repo_dest }}"
|
4
|
+
dependencies: []
|
@@ -6,4 +6,29 @@
|
|
6
6
|
args:
|
7
7
|
chdir: "{{ git_repo_dest }}"
|
8
8
|
creates: "{{ git_repo_dest }}/.git"
|
9
|
-
|
9
|
+
|
10
|
+
- name: Tell Git to ignore OSX artifacts
|
11
|
+
when: ansible_distribution == "MacOSX"
|
12
|
+
include_role:
|
13
|
+
name: qb.gitignore
|
14
|
+
vars:
|
15
|
+
gitignore_name: Global/macOS
|
16
|
+
gitignore_dest: "{{ git_repo_dest }}"
|
17
|
+
|
18
|
+
- name: Tell Git to ignore QB artifacts
|
19
|
+
include_role:
|
20
|
+
name: qb.gitignore
|
21
|
+
vars:
|
22
|
+
gitignore_name: QB
|
23
|
+
gitignore_dest: "{{ git_repo_dest }}"
|
24
|
+
|
25
|
+
- name: >-
|
26
|
+
Tell Git to ignore each of <git_repo_gitignores>
|
27
|
+
with_items: "{{ git_repo_gitignores }}"
|
28
|
+
loop_control:
|
29
|
+
loop_var: name
|
30
|
+
include_role:
|
31
|
+
name: qb.gitignore
|
32
|
+
vars:
|
33
|
+
gitignore_name: "{{ name }}"
|
34
|
+
gitignore_dest: "{{ git_repo_dest }}"
|
@@ -36,6 +36,14 @@ var_prefix: null
|
|
36
36
|
# if none is found.
|
37
37
|
default_dir: null
|
38
38
|
|
39
|
+
# If `true`, QB will ensure the default dir exists before starting the play.
|
40
|
+
#
|
41
|
+
# For legacy reasons, this defaults to `true` if not present, but we want to
|
42
|
+
# default declare it as `false` here so new roles can turn it on only if
|
43
|
+
# they need it.
|
44
|
+
#
|
45
|
+
mkdir: false
|
46
|
+
|
39
47
|
# default user to become for play
|
40
48
|
default_user: null
|
41
49
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
---
|
2
|
+
# tasks file for qb.yarn_release
|
3
|
+
|
4
|
+
- name: load package.json
|
5
|
+
include_vars:
|
6
|
+
file: "{{ yarn_release_package_dir }}/package.json"
|
7
|
+
name: yarn_release_package_json
|
8
|
+
|
9
|
+
- name: get current version
|
10
|
+
set_fact:
|
11
|
+
yarn_release_current_version: "{{ yarn_release_package_json.version }}"
|
12
|
+
|
13
|
+
- name: create release version
|
14
|
+
set_fact:
|
15
|
+
yarn_release_release_version: >-
|
16
|
+
{{ yarn_release_current_version | semver_inc(yarn_release_level) }}
|
17
|
+
|
18
|
+
- name: >
|
19
|
+
increment to version {{ yarn_release_release_version }}
|
20
|
+
and create the git tag
|
21
|
+
command: "yarn version --new-version={{ yarn_release_release_version }}"
|
22
|
+
args:
|
23
|
+
chdir: "{{ yarn_release_package_dir }}"
|
24
|
+
|
25
|
+
- name: >
|
26
|
+
git push the v{{ yarn_release_release_version }} tag
|
27
|
+
command: "git push origin v{{ yarn_release_release_version }}"
|
28
|
+
args:
|
29
|
+
chdir: "{{ yarn_release_package_dir }}"
|
30
|
+
|
31
|
+
- name: >
|
32
|
+
npm publish v{{ yarn_release_release_version }}
|
33
|
+
command: npm publish
|
34
|
+
args:
|
35
|
+
chdir: "{{ yarn_release_package_dir }}"
|
36
|
+
|
37
|
+
- name: create the next -dev version
|
38
|
+
set_fact:
|
39
|
+
yarn_release_next_version: "{{
|
40
|
+
yarn_release_release_version | semver_inc(
|
41
|
+
level='prerelease',
|
42
|
+
preid='dev'
|
43
|
+
)
|
44
|
+
}}"
|
45
|
+
|
46
|
+
- name: >
|
47
|
+
increment to {{ yarn_release_next_version }} version
|
48
|
+
command: >
|
49
|
+
yarn version
|
50
|
+
--new-version={{ yarn_release_next_version }}
|
51
|
+
--no-git-tag-version
|
52
|
+
args:
|
53
|
+
chdir: "{{ yarn_release_package_dir }}"
|
54
|
+
|
55
|
+
- name: git add package.json
|
56
|
+
command: git add package.json
|
57
|
+
args:
|
58
|
+
chdir: "{{ yarn_release_package_dir }}"
|
59
|
+
|
60
|
+
- name: >
|
61
|
+
git commit next dev version
|
62
|
+
command: git commit -m "start {{ yarn_release_next_version }}"
|
63
|
+
args:
|
64
|
+
chdir: "{{ yarn_release_package_dir }}"
|
65
|
+
|
66
|
+
- name: git push next dev version
|
67
|
+
command: git push
|
68
|
+
args:
|
69
|
+
chdir: "{{ yarn_release_package_dir }}"
|
70
|
+
|
71
|
+
- debug:
|
72
|
+
msg: >
|
73
|
+
v{{ yarn_release_release_version }} released.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
---
|
2
|
+
# defaults file for qb.yarn_setup
|
3
|
+
yarn_setup_version: null
|
4
|
+
yarn_setup_state: present
|
5
|
+
yarn_setup_global_packages: []
|
6
|
+
|
7
|
+
yarn_setup_force: false
|
8
|
+
|
9
|
+
yarn_setup_brew_create: true
|
10
|
+
yarn_setup_brew_tap: "{{ qb_git_user_name }}/versions"
|
11
|
+
yarn_setup_brew_link: true
|