xref: /openbmc/openbmc/poky/scripts/oe-publish-sdk (revision 5199d831)
1#!/usr/bin/env python3
2#
3# OpenEmbedded SDK publishing tool
4#
5# Copyright (C) 2015-2016 Intel Corporation
6#
7# SPDX-License-Identifier: GPL-2.0-only
8#
9
10import sys
11import os
12import argparse
13import glob
14import re
15import subprocess
16import logging
17import shutil
18import errno
19
20scripts_path = os.path.dirname(os.path.realpath(__file__))
21lib_path = scripts_path + '/lib'
22sys.path = sys.path + [lib_path]
23import scriptutils
24import argparse_oe
25logger = scriptutils.logger_create('sdktool')
26
27def mkdir(d):
28    try:
29        os.makedirs(d)
30    except OSError as e:
31        if e.errno != errno.EEXIST:
32            raise e
33
34def publish(args):
35    logger.debug("In publish function")
36    target_sdk = args.sdk
37    destination = args.dest
38    logger.debug("target_sdk = %s, update_server = %s" % (target_sdk, destination))
39    sdk_basename = os.path.basename(target_sdk)
40
41    # Ensure the SDK exists
42    if not os.path.exists(target_sdk):
43        logger.error("Specified SDK %s doesn't exist" % target_sdk)
44        return -1
45    if os.path.isdir(target_sdk):
46        logger.error("%s is a directory - expected path to SDK installer file" % target_sdk)
47        return -1
48
49    if ':' in destination:
50        is_remote = True
51        host, destdir = destination.split(':')
52        dest_sdk = os.path.join(destdir, sdk_basename)
53    else:
54        is_remote = False
55        dest_sdk = os.path.join(destination, sdk_basename)
56        destdir = destination
57
58    # Making sure the directory exists
59    logger.debug("Making sure the destination directory exists")
60    if not is_remote:
61        mkdir(destination)
62    else:
63        cmd = "ssh %s 'mkdir -p %s'" % (host, destdir)
64        ret = subprocess.call(cmd, shell=True)
65        if ret != 0:
66            logger.error("Making directory %s on %s failed" % (destdir, host))
67            return ret
68
69    # Copying the SDK to the destination
70    logger.info("Copying the SDK to destination")
71    if not is_remote:
72        if os.path.exists(dest_sdk):
73            os.remove(dest_sdk)
74        if (os.stat(target_sdk).st_dev == os.stat(destination).st_dev):
75            os.link(target_sdk, dest_sdk)
76        else:
77            shutil.copy(target_sdk, dest_sdk)
78    else:
79        cmd = "scp %s %s" % (target_sdk, destination)
80        ret = subprocess.call(cmd, shell=True)
81        if ret != 0:
82            logger.error("scp %s %s failed" % (target_sdk, destination))
83            return ret
84
85    # Unpack the SDK
86    logger.info("Unpacking SDK")
87    if not is_remote:
88        cmd = "sh %s -p -y -d %s" % (dest_sdk, destination)
89        ret = subprocess.call(cmd, shell=True)
90        if ret == 0:
91            logger.info('Successfully unpacked %s to %s' % (dest_sdk, destination))
92            os.remove(dest_sdk)
93        else:
94            logger.error('Failed to unpack %s to %s' % (dest_sdk, destination))
95            return ret
96    else:
97        rm_or_not = " && rm -f %s" % dest_sdk
98        if args.keep_orig:
99            rm_or_not = ""
100        cmd = "ssh %s 'sh %s -p -y -d %s%s'" % (host, dest_sdk, destdir, rm_or_not)
101        ret = subprocess.call(cmd, shell=True)
102        if ret == 0:
103            logger.info('Successfully unpacked %s to %s' % (dest_sdk, destdir))
104        else:
105            logger.error('Failed to unpack %s to %s' % (dest_sdk, destdir))
106            return ret
107
108    # Setting up the git repo
109    if not is_remote:
110        cmd = 'set -e; mkdir -p %s/layers; cd %s/layers; if [ ! -e .git ]; then git init .; cp .git/hooks/post-update.sample .git/hooks/post-commit; echo "*.pyc\n*.pyo\npyshtables.py" > .gitignore; fi; git config gc.auto 0; git add -A .; git config user.email "oe@oe.oe" && git config user.name "OE" && git commit -q -m "init repo" || true' % (destination, destination)
111    else:
112        cmd = "ssh %s 'set -e; mkdir -p %s/layers; cd %s/layers; if [ ! -e .git ]; then git init .; cp .git/hooks/post-update.sample .git/hooks/post-commit; echo '*.pyc' > .gitignore; echo '*.pyo' >> .gitignore; echo 'pyshtables.py' >> .gitignore; fi; git config gc.auto 0; git add -A .; git config user.email 'oe@oe.oe' && git config user.name 'OE' && git commit -q -m \"init repo\" || true'" % (host, destdir, destdir)
113    ret = subprocess.call(cmd, shell=True)
114    if ret == 0:
115        logger.info('SDK published successfully')
116    else:
117        logger.error('Failed to set up layer git repo')
118    return ret
119
120
121def main():
122    parser = argparse_oe.ArgumentParser(description="OpenEmbedded extensible SDK publishing tool - writes server-side data to support the extensible SDK update process to a specified location")
123    parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
124    parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
125    parser.add_argument('-k', '--keep-orig', help='When published to a remote host, the eSDK installer gets deleted by default.', action='store_true')
126
127    parser.add_argument('sdk', help='Extensible SDK to publish (path to .sh installer file)')
128    parser.add_argument('dest', help='Destination to publish SDK to; can be local path or remote in the form of user@host:/path (in the latter case ssh/scp will be used).')
129
130    parser.set_defaults(func=publish)
131
132    args = parser.parse_args()
133
134    if args.debug:
135        logger.setLevel(logging.DEBUG)
136    elif args.quiet:
137        logger.setLevel(logging.ERROR)
138
139    ret = args.func(args)
140    return ret
141
142if __name__ == "__main__":
143    try:
144        ret = main()
145    except Exception:
146        ret = 1
147        import traceback
148        traceback.print_exc()
149    sys.exit(ret)
150