Hi Amit,
This issue is likely due to multiple tenant security being enabled on the
tower server. The custom inventory script (few lines of bash) gets executed
in a proot, which hides most of the filesystem, and that’s why Python can’t
open inventory.py.
Could you please replace the contents of the custom inventory script in
tower with the contents of the all-in-one.py file attached here? Current
content that will need to be replace should be:
#!/bin/bash
if [ "$1" == "--list" ]; then
python /var/lib/awx/scalr/inventory.py $SCALR_API_URL $SCALR_API_KEY_ID
$SCALR_API_KEY_SECRET $SCALR_ENV_ID $SCALR_FARM_ID
else
echo '{}'
fi
)
Many thanks,
Wm. Marc O'Brien
Scalr Technical Support
On Thursday, November 10, 2016 at 10:17:59 AM UTC-7, Amit Saini wrote:
>
> Hi Marc,
>
> I did change in first line ( marked bold) of following script. Now not
> getting this error
>
> failed (rc=2) with output: python: can't open file [Errno 2] No such
> file or directory
>
> ***************************************
>
> *#!usr/bin/bash/python2.7 *
>
> if [ "$1" == "--list" ]; then
>
> python /var/lib/awx/scalr/scalr-ansible-tower/inventory.py
> $SCALR_API_URL $SCALR_API_KEY_ID $SCALR_API_KEY_SECRET $SCALR_ENV_ID
> $SCALR_FARM_ID
>
> else
>
> echo '{}'
>
> fi
>
> ************************************
>
>
>
>
> *But New Error is came :(*
>
> 2.248 INFO Updating inventory 4: Scalr Inventory 2.277 INFO Reading
> executable JSON source: /tmp/ansible_tower_launch_8bq4Ga/tmpy0MuDU 2.301
> ERROR Failed to load JSON from: Traceback (most recent call last): File
> "/usr/bin/tower-manage", line 9, in <module>
> load_entry_point('ansible-tower==3.0.3', 'console_scripts',
> 'tower-manage')() File "/lib/python2.7/site-packages/awx/__init__.py", line
> 103, in manage File
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/__init__.py",
>
> line 354, in execute_from_command_line utility.execute() File
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/__init__.py",
>
> line 346, in execute
> self.fetch_command(subcommand).run_from_argv(self.argv) File
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/base.py",
>
> line 394, in run_from_argv self.execute(*args, **cmd_options) File
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/base.py",
>
> line 445, in execute output = self.handle(*args, **options) File
> "/var/lib/awx/venv/tower/lib/python2.7/site-packages/django/core/management/base.py",
>
> line 661, in handle return self.handle_noargs(**options) File
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>
> line 1285, in handle_noargs File
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>
> line 499, in load_inventory_source File
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>
> line 503, in load_inventory_source File
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>
> line 393, in load File
> "/lib/python2.7/site-packages/awx/main/management/commands/inventory_import.py",
>
> line 381, in command_to_json RuntimeError: ['proot', '-v', '0', '-r', '/',
> '-b', '/tmp/ansible_tower_launch_8bq4Ga/tmp_P6tYy:/etc/tower', '-b',
> '/tmp/ansible_tower_launch_8bq4Ga/tmpI8YWHM:/tmp', '-b',
> '/tmp/ansible_tower_launch_8bq4Ga/tmpzmar2T:/var/lib/awx', '-b',
> '/tmp/ansible_tower_launch_8bq4Ga/tmp91ioqa:/var/lib/awx/job_status', '-b',
> '/tmp/ansible_tower_launch_8bq4Ga/tmpAB66lA:/var/lib/awx/projects', '-b',
> '/tmp/ansible_tower_launch_8bq4Ga/tmp0gB6tg:/var/log', '-b',
> '/tmp/ansible_tower_launch_8bq4Ga:/tmp/ansible_tower_launch_8bq4Ga', '-b',
> '/var/lib/awx/venv/ansible:/var/lib/awx/venv/ansible', '-b',
> '/var/lib/awx/venv/tower:/var/lib/awx/venv/tower', '-w',
> '/tmp/ansible_tower_launch_8bq4Ga',
> '/tmp/ansible_tower_launch_8bq4Ga/tmpy0MuDU', '--list'] failed (rc=1) with
> output: proot error: execve("/tmp/ansible_tower_launch_8bq4Ga/tmpy0MuDU"):
> No such file or directory proot info: possible causes: * the program is a
> script but its interpreter (eg. /bin/sh) was not found; * the program is an
> ELF but its interpreter (eg. ld-linux.so) was not found; * the program is a
> foreign binary but qemu was not specified; * qemu does not work correctly
> (if specified); * the loader was not found or doesn't work. fatal error:
> see `proot --help`. proot error: can't chmod '/tmp/proot-14165-FKg5i0': No
> such file or directory
>
>
> On Wednesday, November 9, 2016 at 11:45:52 AM UTC-5, Amit Saini wrote:
>>
>>
>> Thanks Marc for replying
>>
>> Yes I am following Scalr document
>> <https://scalr-wiki.atlassian.net/wiki/display/docs/Step+1+-+Synchronising+Scalr+Servers+with+an+Ansible+inventory>.
>>
>> I have copy the content of *scalr-ansible-tower* to */var/lib/awx/scalr*
>> ( Refer the Image4 ) but still I am getting the same error ( Refer
>> job_477.txt )
>>
>>
>>
>> Please help me!!!
>>
>> On Tuesday, November 8, 2016 at 4:05:04 PM UTC-5, Marc O'Brien wrote:
>>>
>>> Hi Amit,
>>>
>>> Are you following our Ansible Tower with Scalr Tutorial
>>> <https://scalr-wiki.atlassian.net/wiki/display/docs/Step+1+-+Synchronising+Scalr+Servers+with+an+Ansible+inventory>?
>>>
>>> If so, it appears that when you run "git clone
>>> https://github.com/scalr-tutorials/scalr-ansible-tower.git" there is an
>>> additional level in the directory tree. Do you see any change to behavior
>>> if you move the contents of scalr-ansible-tower to /var/lib/awx/scalr, or
>>> update the path in the Ansible script to include the scalr-ansible-tower
>>> folder in the directory path to inventory.py? This should resolve the "no
>>> such file" error that you are experiencing.
>>>
>>> Many thanks,
>>> Wm. Marc O'Brien
>>> Scalr Technical Support
>>>
>>>
>>>
>>> On Tuesday, November 8, 2016 at 1:44:30 PM UTC-7, Amit Saini wrote:
>>>>
>>>> Hi Team,
>>>>
>>>> While Integration of Ansible Tower with Scalr and I configure the
>>>> custom script ansible tower's Inventory (Refer Image 1) and try to Sync-up
>>>> with Scalr but got the error ( Refer text file job_419) with message
>>>> *'/var/lib/awx/scalr/inventory.py':
>>>> [Errno 2] No such file or directory*
>>>>
>>>>
>>>> While I have SSH ansible tower machine and found that there is not
>>>> *inventory.py* file available on the following path */var/lib/awx/scalr/
>>>> (Refer Image3). *I found *scalr-ansible-tower* file over there
>>>>
>>>> Please help me!!!
>>>>
>>>
--
You received this message because you are subscribed to the Google Groups
"scalr-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
import datetime
import hashlib
import hmac
import json
import logging
import os
import pytz
import random
import requests
import requests.auth
import requests.exceptions
import sys
import urllib
import urlparse
from collections import Mapping, Iterable
class ScalrApiClient(object):
def __init__(self, api_url, key_id, key_secret):
self.api_url = api_url
self.key_id = key_id
self.key_secret = key_secret
self.logger = logging.getLogger("api[{0}]".format(self.api_url))
self.logger.addHandler(logging.StreamHandler())
self.session = ScalrApiSession(self)
def list(self, path, **kwargs):
data = []
ident = False
while path is not None:
if ident:
print
body = self.session.get(path, **kwargs).json()
data.extend(body["data"])
path = body["pagination"]["next"]
ident = True
return data
def create(self, *args, **kwargs):
self._fuzz_ids(kwargs.get("json", {}))
return self.session.post(*args, **kwargs).json().get("data")
def fetch(self, *args, **kwargs):
return self.session.get(*args, **kwargs).json()["data"]
def delete(self, *args, **kwargs):
self.session.delete(*args, **kwargs)
def post(self, *args, **kwargs):
return self.session.post(*args, **kwargs).json()["data"]
class ScalrApiSession(requests.Session):
def __init__(self, client):
self.client = client
super(ScalrApiSession, self).__init__()
def prepare_request(self, request):
if not request.url.startswith(self.client.api_url):
request.url = "".join([self.client.api_url, request.url])
request = super(ScalrApiSession, self).prepare_request(request)
now = datetime.datetime.now(tz=pytz.timezone(os.environ.get("TZ", "UTC")))
date_header = now.isoformat()
url = urlparse.urlparse(request.url)
# TODO - Spec isn't clear on whether the sorting should happen prior or after encoding
if url.query:
pairs = urlparse.parse_qsl(url.query, keep_blank_values=True, strict_parsing=True)
pairs = [map(urllib.quote, pair) for pair in pairs]
pairs.sort(key=lambda pair: pair[0])
canon_qs = "&".join("=".join(pair) for pair in pairs)
else:
canon_qs = ""
# Authorize
sts = "\n".join([
request.method,
date_header,
url.path,
canon_qs,
request.body if request.body is not None else ""
])
sig = " ".join([
"V1-HMAC-SHA256",
base64.b64encode(hmac.new(str(self.client.key_secret), sts, hashlib.sha256).digest())
])
request.headers.update({
"X-Scalr-Key-Id": self.client.key_id,
"X-Scalr-Signature": sig,
"X-Scalr-Date": date_header,
"X-Scalr-Debug": "1"
})
self.client.logger.debug("URL: %s", request.url)
self.client.logger.debug("StringToSign: %s", repr(sts))
self.client.logger.debug("Signature: %s", repr(sig))
return request
def request(self, *args, **kwargs):
res = super(ScalrApiSession, self).request(*args, **kwargs)
self.client.logger.info("%s - %s", " ".join(args), res.status_code)
try:
errors = res.json().get("errors", None)
if errors is not None:
for error in errors:
self.client.logger.warning("API Error (%s): %s", error["code"], error["message"])
except ValueError:
self.client.logger.error("Received non-JSON response from API!")
res.raise_for_status()
self.client.logger.debug("Received response: %s", res.text)
return res
def get_env_servers(client, envId):
servers_path = '/api/v1beta0/user/{envId}/servers/?status=running'.format(envId=envId)
servers = client.list(servers_path)
farmIds = []
farmRoleIds = []
for s in servers:
farmIds.append(s['farm']['id'])
farmRoleIds.append(s['farmRole']['id'])
farmIds = set(farmIds)
farmRoleIds = set(farmRoleIds)
farms = {}
farm_path = '/api/v1beta0/user/{envId}/farms/{farmId}/'
for farmId in farmIds:
path = farm_path.format(envId=envId, farmId=farmId)
farms[farmId] = client.fetch(path)
farmRoles = {}
farmRole_path = '/api/v1beta0/user/{envId}/farm-roles/{farmRoleId}/'
for farmRoleId in farmRoleIds:
path = farmRole_path.format(envId=envId, farmRoleId=farmRoleId)
farmRoles[farmRoleId] = client.fetch(path)
result = {'_meta' :
{'hostvars': {}}
}
for farmId, farm in farms.iteritems():
result[farm['name']] = {'vars': {
'id': farmId,
'project': farm['project']['id'],
'owner': farm['owner']['id']
},
'children': []}
for farmRoleId, farmRole in farmRoles.iteritems():
if farmRole['farm']['id'] != farmId:
continue
farmRoleGroupId = 'farm-role-' + str(farmRoleId) + '-' + farmRole['alias']
result[farm['name']]['children'].append(farmRoleGroupId)
result[farmRoleGroupId] = {'hosts': [], 'vars': {
'id': farmRoleId,
'platform': farmRole['platform'],
'roleId': farmRole['role']['id']
}}
for server in servers:
if server['farmRole']['id'] != farmRoleId:
continue
if len(server['publicIp']) == 0:
# Server has no public IP
continue
result[farmRoleGroupId]['hosts'].append(server['publicIp'][0])
result['_meta']['hostvars'][server['publicIp'][0]] = {'hostname': server['hostname']}
print json.dumps(result, indent=2)
def get_farm_servers(client, envId, farmId):
servers_path = '/api/v1beta0/user/{envId}/farms/{farmId}/servers/?status=running'.format(envId=envId, farmId=farmId)
servers = client.list(servers_path)
farmRoleIds = []
for s in servers:
farmRoleIds.append(s['farmRole']['id'])
farmRoleIds = set(farmRoleIds)
farm_path = '/api/v1beta0/user/{envId}/farms/{farmId}/'.format(envId=envId, farmId=farmId)
farm = client.fetch(farm_path)
farmRoles = {}
farmRole_path = '/api/v1beta0/user/{envId}/farm-roles/{farmRoleId}/'
for farmRoleId in farmRoleIds:
path = farmRole_path.format(envId=envId, farmRoleId=farmRoleId)
farmRoles[farmRoleId] = client.fetch(path)
result = {'_meta' :
{'hostvars': {}}
}
for farmRoleId, farmRole in farmRoles.iteritems():
farmRoleGroupId = 'farm-role-' + str(farmRoleId) + '-' + farmRole['alias']
result[farmRoleGroupId] = {'hosts': [], 'vars': {
'id': farmRoleId,
'platform': farmRole['platform'],
'roleId': farmRole['role']['id']
}}
for server in servers:
if server['farmRole']['id'] != farmRoleId:
continue
if len(server['publicIp']) == 0:
# Server has no public IP
continue
result[farmRoleGroupId]['hosts'].append(server['publicIp'][0])
result['_meta']['hostvars'][server['publicIp'][0]] = {'hostname': server['hostname']}
print json.dumps(result, indent=2)
def main():
api_url = os.environ.get('SCALR_API_URL')
api_key_id = os.environ.get('SCALR_API_KEY_ID')
api_key_secret = os.environ.get('SCALR_API_KEY_SECRET')
env_id = os.environ.get('SCALR_ENV_ID')
farm_id = os.environ.get('SCALR_FARM_ID')
if not api_url:
print 'API URL not specified, exiting.'
return
if not api_key_id:
print 'API Key ID not specified, exiting.'
return
if not api_key_secret:
print 'API Key Secret not specified, exiting.'
return
if not env_id:
print 'Scalr Environment ID not specified, exiting.'
return
client = ScalrApiClient(api_url.rstrip("/"), api_key_id, api_key_secret)
if farm_id:
get_farm_servers(client, env_id, farm_id)
else:
get_env_servers(client, env_id)
if __name__ == "__main__":
if len(sys.argv) >= 2 and sys.argv[1] == '--list':
main()
else:
print '{}'