Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

 

# 

# This file is part of Ansible 

# 

# Ansible is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 3 of the License, or 

# (at your option) any later version. 

# 

# Ansible is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

# GNU General Public License for more details. 

# 

# You should have received a copy of the GNU General Public License 

# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 

 

# Make coding more python3-ish 

from __future__ import (absolute_import, division, print_function) 

__metaclass__ = type 

 

from os.path import basename 

 

from ansible.errors import AnsibleParserError 

from ansible.playbook.attribute import FieldAttribute 

from ansible.playbook.task_include import TaskInclude 

from ansible.playbook.role import Role 

from ansible.playbook.role.include import RoleInclude 

 

try: 

from __main__ import display 

except ImportError: 

from ansible.utils.display import Display 

display = Display() 

 

__all__ = ['IncludeRole'] 

 

 

class IncludeRole(TaskInclude): 

 

""" 

A Role include is derived from a regular role to handle the special 

circumstances related to the `- include_role: ...` 

""" 

 

BASE = ('name', 'role') # directly assigned 

FROM_ARGS = ('tasks_from', 'vars_from', 'defaults_from') # used to populate from dict in role 

OTHER_ARGS = ('private', 'allow_duplicates') # assigned to matching property 

VALID_ARGS = tuple(frozenset(BASE + FROM_ARGS + OTHER_ARGS)) # all valid args 

 

_inheritable = False 

 

# ================================================================================= 

# ATTRIBUTES 

 

# private as this is a 'module options' vs a task property 

_allow_duplicates = FieldAttribute(isa='bool', default=True, private=True) 

_private = FieldAttribute(isa='bool', default=None, private=True) 

 

def __init__(self, block=None, role=None, task_include=None): 

 

super(IncludeRole, self).__init__(block=block, role=role, task_include=task_include) 

 

self._from_files = {} 

self._parent_role = role 

self._role_name = None 

self._role_path = None 

 

def get_block_list(self, play=None, variable_manager=None, loader=None): 

 

# only need play passed in when dynamic 

if play is None: 

myplay = self._parent._play 

else: 

myplay = play 

 

ri = RoleInclude.load(self._role_name, play=myplay, variable_manager=variable_manager, loader=loader) 

ri.vars.update(self.vars) 

 

# build role 

actual_role = Role.load(ri, myplay, parent_role=self._parent_role, from_files=self._from_files) 

actual_role._metadata.allow_duplicates = self.allow_duplicates 

 

# save this for later use 

self._role_path = actual_role._role_path 

 

# compile role with parent roles as dependencies to ensure they inherit 

# variables 

if not self._parent_role: 

dep_chain = [] 

else: 

dep_chain = list(self._parent_role._parents) 

dep_chain.append(self._parent_role) 

 

blocks = actual_role.compile(play=myplay, dep_chain=dep_chain) 

for b in blocks: 

b._parent = self 

 

# updated available handlers in play 

handlers = actual_role.get_handler_blocks(play=myplay) 

myplay.handlers = myplay.handlers + handlers 

return blocks, handlers 

 

@staticmethod 

def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None): 

 

ir = IncludeRole(block, role, task_include=task_include).load_data(data, variable_manager=variable_manager, loader=loader) 

 

# Validate options 

my_arg_names = frozenset(ir.args.keys()) 

 

# name is needed, or use role as alias 

ir._role_name = ir.args.get('name', ir.args.get('role')) 

if ir._role_name is None: 

raise AnsibleParserError("'name' is a required field for include_role.") 

 

# validate bad args, otherwise we silently ignore 

bad_opts = my_arg_names.difference(IncludeRole.VALID_ARGS) 

if bad_opts: 

raise AnsibleParserError('Invalid options for include_role: %s' % ','.join(list(bad_opts))) 

 

# build options for role includes 

for key in my_arg_names.intersection(IncludeRole.FROM_ARGS): 

from_key = key.replace('_from', '') 

ir._from_files[from_key] = basename(ir.args.get(key)) 

 

# manual list as otherwise the options would set other task parameters we don't want. 

for option in my_arg_names.intersection(IncludeRole.OTHER_ARGS): 

setattr(ir, option, ir.args.get(option)) 

 

return ir 

 

def copy(self, exclude_parent=False, exclude_tasks=False): 

 

new_me = super(IncludeRole, self).copy(exclude_parent=exclude_parent, exclude_tasks=exclude_tasks) 

new_me.statically_loaded = self.statically_loaded 

new_me._from_files = self._from_files.copy() 

new_me._parent_role = self._parent_role 

new_me._role_name = self._role_name 

new_me._role_path = self._role_path 

 

return new_me 

 

def get_include_params(self): 

v = super(IncludeRole, self).get_include_params() 

if self._parent_role: 

v.update(self._parent_role.get_role_params()) 

return v