{ "info": { "author": "Nick Zigarovich", "author_email": "eckso@eckso.io", "bugtrack_url": null, "classifiers": [], "description": "Giga\n====\n\nGiga is a Unix system orchestration framework for Python (>= 3.6) programmers.\n\nInstallation\n------------\n\n```\npython3 -m pip install giga\n```\n\nFeatures\n--------\n\n_The following snippets demonstrate giga's features in broad strokes by\ncreating automation to install and uninstall the python package `example-pkg`\nfrom git._\n\n- **An API for operating Unix systems.**\n\n```python\nimport giga\n\n# pass super=True to run all commands as the superuser. the login and\n# superuser passwords can be given as arguments if needed\nsystem = giga.unix.Ssh(host='albatross.local', user='jrandom', super=True)\n\n# make a predicate that returns True if example-pkg is installed else False\ninstalled = lambda: system.zero(\"pip3 list|grep '^example-pkg '\")\n\n# install example-pkg\nif not installed():\n system.run('pip3 install git+https://github.com/mykelalvis/example_pkg')\n\n# print example-pkg install state\nprint(installed()) # => 'True'\n\n# uninstall example-pkg\nif installed():\n system.run('yes|pip3 uninstall example-pkg')\n\n# print example-pkg install state\nprint(installed()) # => 'False'\n```\n\n- **An API for creating reusable system configurations.**\n\n```python\nimport giga\n\nclass ExamplePkg(giga.Config):\n 'Apply or delete the example-pkg python package.'\n\n @property\n def installed(self):\n return self.system.zero(\"pip3 list|grep '^example-pkg '\")\n\n # extend giga.Config.on_apply()\n def on_apply(self):\n super().on_apply()\n with giga.Task('Apply example-pkg') as task:\n if not self.installed:\n url = 'git+https://github.com/mykelalvis/example_pkg'\n self.system.run(f'pip3 install {url}')\n task.change()\n\n # extend giga.Config.on_delete()\n def on_delete(self):\n super().on_delete()\n with giga.Task('Delete example-pkg') as task:\n if self.installed:\n self.system.run('yes|pip3 uninstall example-pkg')\n task.change()\n\n # extend giga.Config.on_is_applied()\n def on_is_applied(self):\n return super().on_is_applied() and self.installed\n```\n```python\n# create a system\nsystem = giga.unix.Ssh(host='albatross.local', user='jrandom', super=True)\n\n# apply ExamplePkg to the system\nsystem.apply(ExamplePkg)\n\n# print ExamplePkg apply status\nprint(system.is_applied(ExamplePkg)) # => 'True'\n\n# delete ExamplePkg from the system\nsystem.delete(ExamplePkg)\n\n# print ExamplePkg apply status\nprint(system.is_applied(ExamplePkg)) # => 'False'\n```\n\n- **Customization and composition of system configurations.**\n\n```python\n# existing configurations can be customized via inheritance or instantiation.\n# here we use one of giga's base configurations to implement our ExamplePkg\n# configuration\n\nclass ExamplePkg(giga.configs.python.Packages):\n\n packages = [\n ('example-pkg', 'git+https://github.com/mykelalvis/example_pkg'),\n ]\n\nexample_pkg = giga.configs.python.Packages(\n packages = [\n ('example-pkg', 'git+https://github.com/mykelalvis/example_pkg'),\n ]\n)\n```\n```python\n# composition assembles many configurations into one and is delegated by\n# `giga.Config.config_include`, which may be a sequence or a callable\n# returning a sequence\n\nclass ExamplePkg(giga.Config):\n\n pkg = 'example-pkg'\n url = 'git+https://github.com/mykelalvis/example_pkg'\n\n config_include = [\n giga.configs.os.debian.Packages(packages=['python3-pip']),\n giga.configs.python.Packages(packages=[(pkg, url)]),\n ]\n\nclass ExamplePkg(giga.Config):\n\n def config_include(self):\n pkg = 'example-pkg'\n url = 'git+https://github.com/mykelalvis/example_pkg'\n return [\n giga.configs.os.debian.Packages(packages=['python3-pip']),\n giga.configs.python.Packages(packages=[(pkg, url)]),\n ]\n```\n```python\n# the callable form of `config_include` can branch on things like os family\n\nclass ExamplePkg(giga.Config):\n\n @property\n def os_packages(self):\n family = self.system.os.family\n if family == 'debian':\n return giga.configs.os.debian.Packages(packages=['python3-pip'])\n elif family == 'redhat':\n return giga.configs.os.redhat.Packages(packages=['python36u-pip'])\n else:\n raise giga.error.NotImplementedFor(family)\n\n @property\n def py_packages(self):\n pkg = 'example-pkg'\n url = 'git+https://github.com/mykelalvis/example_pkg'\n return giga.configs.python.Packages(packages=[(pkg, url)])\n\n def config_include(self):\n return [\n self.os_packages,\n self.py_packages,\n ]\n```\n\n- **An API for operating groups of Unix systems.** _The command-line\n interface typically handles all of this behind the scenes, but it is\n perfectly reasonable to drive giga from other python code._\n\n```python\n# a simple version using the built-in result handler\n\nimport giga\n\nclass ExamplePkg(giga.Config): pass # see previous examples\n\nhosts = (\n 'server1.local',\n 'server2.local',\n 'server3.local',\n)\n\n# create a group\ngroup = giga.Group(hosts=hosts, user='jrandom', super=True)\n\n# apply ExamplePkg to the group\nok, err = group.apply(ExamplePkg)\ngroup.log_results(ok, err)\n\n# print ExamplePkg apply status\nok, err = group.is_applied(ExamplePkg)\ngroup.log_results(ok, err)\n\n# delete ExamplePkg from the group\nok, err = group.delete(ExamplePkg)\ngroup.log_results(ok, err)\n```\n```python\n# a fuller version showing the structure of the group result lists, ok and err\n\nimport giga, traceback\n\nclass ExamplePkg(giga.Config): pass # see previous examples\n\ndef results(ok, err):\n 'Handle the results of Group.apply(), Group.delete(), or Group.is_applied().'\n\n # print tracebacks for all failed hosts\n for system, exc_info in err:\n _, exc, _ = exc_info\n # configs can raise either giga.Cancel or giga.Fail\n if isinstance(exc, giga.Cancel):\n # we should ignore these and look for the root cause, the giga.Fail\n continue\n assert(isinstance(exc, giga.Fail))\n print('-', system.name)\n traceback.print_exception(*exc.exc_info) # the exc_info of the real error\n print()\n\n # print results for all successful hosts\n for system, result in ok:\n\n if isinstance(result, int):\n # apply/delete return int, the number of changes made to the system\n print(f'- {system.name} made {result} changes')\n\n elif isinstance(result, bool):\n # is_applied returns bool, True if a configuration is applied else False\n status = 'applied' if result else 'not applied'\n print(f'- configuration is {status} to {system.name}')\n\nhosts = (\n 'server1.local',\n 'server2.local',\n 'server3.local',\n)\n\n# create a group\ngroup = giga.Group(hosts=hosts, user='jrandom', super=True)\n\n# apply ExamplePkg to the group\nok, err = group.apply(ExamplePkg)\nresults(ok, err)\n\n# print ExamplePkg apply status\nok, err = group.is_applied(ExamplePkg)\nresults(ok, err)\n\n# delete ExamplePkg from the group\nok, err = group.delete(ExamplePkg)\nresults(ok, err)\n```\n\n- **Command-line interface.**\n\n```sh\n# apply config ExamplePkg in module examplepkg to 3 hosts\ngiga apply examplepkg.ExamplePkg -h host1,host2,host3 -u jrandom -s\n\n# check apply status for config ExamplePkg in module examplepkg on 3 hosts\ngiga is-applied examplepkg.ExamplePkg -h host1,host2,host3 -u jrandom -s\n\n# delete config ExamplePkg in module examplepkg from 3 hosts\ngiga delete examplepkg.ExamplePkg -h host1,host2,host3 -u jrandom -s\n\n# show help\ngiga --help\n```\n\nStatus\n------\n\nGiga is undergoing heavy development and refinement. While some things are\nstill held together with tape and glue, it continues to improve steadily, and\nis used daily by its author to deploy and maintain enterprise infrastructure.\n\nContributing\n------------\n\nIf you're interested in contributing, wow, I'm really quite shocked. :) I can\nbe reached at `eckso@eckso.io`.\n\nLicense\n-------\n\nGiga is licensed under the Apache License Version 2.0.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ecks0/giga", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "giga", "package_url": "https://pypi.org/project/giga/", "platform": "", "project_url": "https://pypi.org/project/giga/", "project_urls": { "Homepage": "https://github.com/ecks0/giga" }, "release_url": "https://pypi.org/project/giga/0.0.7/", "requires_dist": [ "click (>=6.0.0)", "deepmerge (>=0.1.0)", "lura (>=0.4.6)" ], "requires_python": ">= 3.6", "summary": "system orchestration framework", "version": "0.0.7", "yanked": false, "yanked_reason": null }, "last_serial": 6072861, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "d729a7941e76c867fdb3e83d0d4c38a9", "sha256": "33fa722921a9578698ffe3dc0dc0f54011178a79cf6affbf1ab876437b789b7a" }, "downloads": -1, "filename": "giga-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "d729a7941e76c867fdb3e83d0d4c38a9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 36200, "upload_time": "2019-10-22T04:30:13", "upload_time_iso_8601": "2019-10-22T04:30:13.828179Z", "url": "https://files.pythonhosted.org/packages/78/e5/d1858f65bec0eca31fc5a7a749672bf9403e8015d44df171be0bdd7058ff/giga-0.0.1-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "5165e6ecf2c8c577d75558b90a613382", "sha256": "9e521f1e368525047c4c0fd58e698581a5a818707d963597031f35676d4dc324" }, "downloads": -1, "filename": "giga-0.0.1.tar.gz", "has_sig": false, "md5_digest": "5165e6ecf2c8c577d75558b90a613382", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 24906, "upload_time": "2019-10-22T04:30:16", "upload_time_iso_8601": "2019-10-22T04:30:16.796383Z", "url": "https://files.pythonhosted.org/packages/0b/05/ff5e45690c4f976fd4d43e7e640bcaa8d22d33af789c3e7b3df6c2335076/giga-0.0.1.tar.gz", "yanked": false, "yanked_reason": null } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "1ec27511d056672ba60451686989dd48", "sha256": "b39ab54b8dd0d59882db418e42948a990ee01cd78bc2908da73ec9e131be948b" }, "downloads": -1, "filename": "giga-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "1ec27511d056672ba60451686989dd48", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 46165, "upload_time": "2019-10-28T23:26:15", "upload_time_iso_8601": "2019-10-28T23:26:15.181652Z", "url": "https://files.pythonhosted.org/packages/32/d3/f6029bdd77cabe07739907f27a39b5bc789c4481a6c7c433e4519be5b66a/giga-0.0.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "c0560d94577de0de469361b45985743b", "sha256": "63b5402c280d851cd6fa18e31e926d7a4f07dfa9925810ad95e33e286471de63" }, "downloads": -1, "filename": "giga-0.0.2.tar.gz", "has_sig": false, "md5_digest": "c0560d94577de0de469361b45985743b", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 30589, "upload_time": "2019-10-28T23:26:16", "upload_time_iso_8601": "2019-10-28T23:26:16.843812Z", "url": "https://files.pythonhosted.org/packages/f9/aa/52feb028c2e500072ec01be847eb9d39e7829e53c72e6de267e72a923b81/giga-0.0.2.tar.gz", "yanked": false, "yanked_reason": null } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "3d4003b300e669b57bb68118a5a24f09", "sha256": "f677fe3d9803a50699770383033aa76c0423338139ba38063d6e6a068c7f3c54" }, "downloads": -1, "filename": "giga-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "3d4003b300e669b57bb68118a5a24f09", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 50456, "upload_time": "2019-11-01T19:08:34", "upload_time_iso_8601": "2019-11-01T19:08:34.051012Z", "url": "https://files.pythonhosted.org/packages/33/13/c71de1ea08360d0506483fea2895097a369624603f4cc4286d6226058859/giga-0.0.3-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "4df105805234ec7080c5329077f67b07", "sha256": "3d8bd439b4407f022ec45aed55e370ea7ff568c8f68f0fda91f7155eb3ecb9d8" }, "downloads": -1, "filename": "giga-0.0.3.tar.gz", "has_sig": false, "md5_digest": "4df105805234ec7080c5329077f67b07", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 36493, "upload_time": "2019-11-01T19:08:35", "upload_time_iso_8601": "2019-11-01T19:08:35.878778Z", "url": "https://files.pythonhosted.org/packages/26/27/87cac7fb03a26ca976ccec96029ebe0977d34e61556448b6467b7d6b36f6/giga-0.0.3.tar.gz", "yanked": false, "yanked_reason": null } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "f506e7ead1cb2272de272f453bd0b36c", "sha256": "cd2bee5279b605b48bc11b4903031bf4820b999d0e8edfabb31d0e24ae0d9212" }, "downloads": -1, "filename": "giga-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "f506e7ead1cb2272de272f453bd0b36c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 51197, "upload_time": "2019-11-03T17:45:39", "upload_time_iso_8601": "2019-11-03T17:45:39.731076Z", "url": "https://files.pythonhosted.org/packages/ff/b4/af266e15e444a7652a3f9b799733a5c6bca13c910311b4c31bbe3ff2fb91/giga-0.0.4-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "f7145ca1a803f3f41adf7b0e10f4a8f4", "sha256": "5c2bfca6051bb530659b7f564d910d44cdfe1bd665aaa23c12c03ca73cfcb215" }, "downloads": -1, "filename": "giga-0.0.4.tar.gz", "has_sig": false, "md5_digest": "f7145ca1a803f3f41adf7b0e10f4a8f4", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 37113, "upload_time": "2019-11-03T17:45:41", "upload_time_iso_8601": "2019-11-03T17:45:41.296734Z", "url": "https://files.pythonhosted.org/packages/05/65/c33687434add93d510a46eee4df19638809004b33643345c3eb797fa0c28/giga-0.0.4.tar.gz", "yanked": false, "yanked_reason": null } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "62f2e50bd7ce8c0028530a5b860fa244", "sha256": "217575608afe8ced21758e2b0c67088eae8f507d2d239c356dc44b161c60ab78" }, "downloads": -1, "filename": "giga-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "62f2e50bd7ce8c0028530a5b860fa244", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 51465, "upload_time": "2019-11-04T00:54:43", "upload_time_iso_8601": "2019-11-04T00:54:43.987924Z", "url": "https://files.pythonhosted.org/packages/42/1b/597d55aa6cf73dcf5e240d20fd71f8ac105453d2668af515b6809caab1b1/giga-0.0.5-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "5ff76e2ee2c9a47c518fe220d5f46129", "sha256": "f8906b2783124860ca0db33ff5ff4240003e03338b7b396d26ab7cf8a8f8cf6b" }, "downloads": -1, "filename": "giga-0.0.5.tar.gz", "has_sig": false, "md5_digest": "5ff76e2ee2c9a47c518fe220d5f46129", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 37169, "upload_time": "2019-11-04T00:54:45", "upload_time_iso_8601": "2019-11-04T00:54:45.756939Z", "url": "https://files.pythonhosted.org/packages/01/fa/68f9d55efc10c4bb5202bc393d7ffdb29b894ab56f8e80ae4b5550fd1fb4/giga-0.0.5.tar.gz", "yanked": false, "yanked_reason": null } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "c827e608cc809af8eaf2c298b36b2560", "sha256": "48e556c0a93fcd2dafa763005f54f0fa06fb8e62c5785657da50717732b485e8" }, "downloads": -1, "filename": "giga-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "c827e608cc809af8eaf2c298b36b2560", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 51453, "upload_time": "2019-11-04T01:10:31", "upload_time_iso_8601": "2019-11-04T01:10:31.661350Z", "url": "https://files.pythonhosted.org/packages/2c/7b/eaeb48e17683cc5d7c7c87fe071baab868324fa49a7561d9568581a3fa35/giga-0.0.6-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "96a0ebf65a39ffc1dc6d379057468526", "sha256": "816778eecca04d9fc461c15ebb1101c4df9273fdf6444c18f88cb03d61475dc4" }, "downloads": -1, "filename": "giga-0.0.6.tar.gz", "has_sig": false, "md5_digest": "96a0ebf65a39ffc1dc6d379057468526", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 37169, "upload_time": "2019-11-04T01:10:33", "upload_time_iso_8601": "2019-11-04T01:10:33.223992Z", "url": "https://files.pythonhosted.org/packages/b2/29/9136bc9fddc0f4e92029fc518e75ca82164813e6ce89450389c27650dcd3/giga-0.0.6.tar.gz", "yanked": false, "yanked_reason": null } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "cc068a4e905ac6889f3af0f688243e09", "sha256": "29b71c99e77d24702ac287814b482716a7d3e091b55ee0ded4f07fb01b5391af" }, "downloads": -1, "filename": "giga-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "cc068a4e905ac6889f3af0f688243e09", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 51460, "upload_time": "2019-11-04T02:51:17", "upload_time_iso_8601": "2019-11-04T02:51:17.714276Z", "url": "https://files.pythonhosted.org/packages/cd/33/a8641f8f5ed9af5ac356cea457a56c02b9210f465209262f9b322feff944/giga-0.0.7-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "f98fe01f22f3f4f2f8ac3d799decae1d", "sha256": "e29af006db21228dc3f5cbec3da2f45c00dec734d4bb87c7bc50e2af75a4d9c0" }, "downloads": -1, "filename": "giga-0.0.7.tar.gz", "has_sig": false, "md5_digest": "f98fe01f22f3f4f2f8ac3d799decae1d", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 37166, "upload_time": "2019-11-04T02:51:19", "upload_time_iso_8601": "2019-11-04T02:51:19.152911Z", "url": "https://files.pythonhosted.org/packages/ea/c8/72cdc41386aadba6f183bc3ed98be8469551868301c64e5d62d75f6e5cd2/giga-0.0.7.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "cc068a4e905ac6889f3af0f688243e09", "sha256": "29b71c99e77d24702ac287814b482716a7d3e091b55ee0ded4f07fb01b5391af" }, "downloads": -1, "filename": "giga-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "cc068a4e905ac6889f3af0f688243e09", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.6", "size": 51460, "upload_time": "2019-11-04T02:51:17", "upload_time_iso_8601": "2019-11-04T02:51:17.714276Z", "url": "https://files.pythonhosted.org/packages/cd/33/a8641f8f5ed9af5ac356cea457a56c02b9210f465209262f9b322feff944/giga-0.0.7-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "f98fe01f22f3f4f2f8ac3d799decae1d", "sha256": "e29af006db21228dc3f5cbec3da2f45c00dec734d4bb87c7bc50e2af75a4d9c0" }, "downloads": -1, "filename": "giga-0.0.7.tar.gz", "has_sig": false, "md5_digest": "f98fe01f22f3f4f2f8ac3d799decae1d", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.6", "size": 37166, "upload_time": "2019-11-04T02:51:19", "upload_time_iso_8601": "2019-11-04T02:51:19.152911Z", "url": "https://files.pythonhosted.org/packages/ea/c8/72cdc41386aadba6f183bc3ed98be8469551868301c64e5d62d75f6e5cd2/giga-0.0.7.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }