Giter VIP home page Giter VIP logo

pyinfra-dev / pyinfra Goto Github PK

View Code? Open in Web Editor NEW
2.6K 37.0 324.0 21.33 MB

pyinfra automates infrastructure using Python. It’s fast and scales from one server to thousands. Great for ad-hoc command execution, service deployment, configuration management and more.

Home Page: https://pyinfra.com

License: MIT License

Python 99.62% Shell 0.37% Jinja 0.01%
python cloud-management configuration-management remote-execution high-performance pyinfra infrastructure

pyinfra's Introduction

pyinfra

Note: this is the v3 branch, which is currently in beta. See the docs for v3. If needed the 2.x branch is here, but is in bugfix only mode.

pyinfra automates infrastructure using Python. It’s fast and scales from one server to thousands. Great for ad-hoc command execution, service deployment, configuration management and more.


DocumentationGetting StartedExamplesHelp & SupportContributing

Chat ⇒ #pyinfra on Matrix


Why pyinfra? Design features include:

  • 🚀 Super fast execution over thousands of hosts with predictable performance.
  • 🚨 Instant debugging with realtime stdin/stdout/stderr output (-vvv).
  • 🔄 Idempotent operations that enable diffs and dry runs before making changes.
  • 📦 Extendable with the entire Python package ecosystem.
  • 💻 Agentless execution against anything with shell access.
  • 🔌 Integrated with connectors for Docker, Terraform, Vagrant and more.

Quickstart

Install pyinfra with pip:

pip install pyinfra

Now you can execute commands on hosts via SSH:

pyinfra my-server.net exec -- echo "hello world"

Or target Docker containers, the local machine, and other connectors:

pyinfra @docker/ubuntu exec -- echo "Hello world"
pyinfra @local exec -- echo "Hello world"

As well as executing commands you can define state using operations:

# Install iftop apt package if not present
pyinfra @docker/ubuntu apt.packages iftop update=true _sudo=true

Which can then be saved as a Python file like deploy.py:

from pyinfra.operations import apt

apt.packages(
    name="Ensure iftop is installed",
    packages=['iftop'],
    update=True,
    _sudo=True,
)

The hosts can also be saved in a file, for example inventory.py:

targets = ["@docker/ubuntu", "my-test-server.net"]

And executed together:

pyinfra inventory.py deploy.py

Now you know the building blocks of pyinfra! By combining inventory, operations and Python code you can deploy anything.

See the more detailed getting started or using operations guides. See how to use inventory & data, global arguments and the CLI or check out the documented examples.


PyPI version PyPi downloads Docs status Execute tests status Codecov Coverage MIT Licensed

pyinfra's People

Contributors

charles-l avatar fizzadar avatar foobarquaxx avatar gaming4lifede avatar gchazot avatar gdoumenc avatar glassbeads avatar hoh avatar i-do-cpp avatar jaysoffian avatar jmpolom avatar lun-4 avatar maisim avatar meantheory avatar minusf avatar mkinney avatar morrison12 avatar pabloxio avatar remybar avatar scottkevill avatar sfermigier avatar simonw avatar stchris avatar stefanbras avatar stevenkaras avatar sysadmin75 avatar themanifold avatar tobald avatar tsnoam avatar uggedal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyinfra's Issues

Support for su w/o sudo

I have been running simple pyinfra deploy scripts like this one
for doing my daily apt-get update/upgrade combo:

apt.py

from pyinfra.modules import apt
from pyinfra.modules import server

apt.update()
apt.upgrade()
server.shell(commands="apt-get -y autoremove")

initially I always ran it as the root user, like so

pyinfra -i somehost --user root -v apt.py

ie. using simply somehost's hostname, and taking advantage of the
fact, that I have an ssh-agent running, ie. I am not asked for a password or
key phrase (whether it's a good thing to allow ssh root access, is another question,
but it certainly makes my adminstrator's life easier).

Then I got bored of always having to type --user root, so instead I introduced
simple inventories (one for each host I use so far):

somehost.py

HOSTS = [
    ('somehost', {'ssh_user': "root"})
]

that way I can just call:

pyinfra -i somehost.py apt.py -v

I guess it makes sense to have ssh_user set as "root", because most of
the operations I do on a host require root permissions.

However not always: a similar emacs/cask update I typically do as user rx
(rather then root):

cd ~/.emacs.d && EMACS="emacs" ~/cfg/e/cask/bin/cask outdated

Now what I would like is: just call

pyinfra -i somehost.py -v cask.py

given that I have prepared a similar cask deploy script:

cask.py

from pyinfra.modules import server

server.shell(chdir="~/.emacs.d"
            , commands='EMACS="emacs" ~/cfg/e/cask/bin/cask update'
            , user="rx")

Ie. I want to just use the somehost.py inventory, and have my cask.py deploy script
figure out, that a certain task requires user "rx" only.
Note that this is my wishlist thinking: the server.shell command doesn't
currently have a user=... parameter

I do not want to have to think for every little task:

  • oh, apt operations require root permissions, thus call them with an inventory
    that has 'ssh_user': "root"
  • cask operations I do as user "rx", thus call them with another inventory
    that has 'ssh_user': "rx"

Rather I want the individual deploy scripts/operations therein be able
to take a user param.

currently what I am resorting to in the case of cask above:

def caskUpdate():
    server.shell(commands='su - rx -c "cd ~/.emacs.d && EMACS=emacs ~/cfg/e/cask/bin/cask update"')

caskUpdate()

which is not really the style I want to write my operations.

Maybe this is possible with pyfinfra alreay, and I just haven't discovered it yet?

Also on my wishlist: maybe create a pyinfra mailing list, where I could ask these
kind of user questions ?

Not that in (haskell) propellor, which I am also using, this
is possible: the userScriptPropterty
there takes among other params a User param, cf eg.

http://hackage.haskell.org/package/propellor-3.0.5/docs/Propellor-Property-Cmd.html#v:userScriptProperty

ie. in propellor I just have

caskUpdate :: Property UnixLike
caskUpdate = propertyList "cask update" $ props
             & userScriptProperty (User "rx")
             [
              "(cd ~/.emacs.d && EMACS=\"emacs\" ~/cfg/e/cask/bin/cask update)"
             ] `assume` MadeChange

Thanks for creating pyinfra in the first place, and keep up your good work.

Refactor common package handling bits

modules.common.packaging or something. Needs to support diffing packages against fact AND versions - so each op will need to pull any versions passed in (currently no version comparison, just installed/not).

Common bits from following to be merged:

`pty` global kwarg

Same as sudo/sudo_user/su_user, etc - add get_pty to paramiko commands. Default to False.

Needed for certain command line tools that require a terminal because they're annoying like that.

Improve `files.line` searching

Eg 00 07 * * * ENV=production PYTHONPATH=/opt/myapp /opt/envs/myapp/bin/python -m myapp will always echo to end of file, even if line is present.

Likely issues matching with the *'s.

Look into string formatting options on op args

Ie enable passing Something={{ host.data.env }} as an argument, such that multiple "result" strings get bunched as one operation (because the op_hash will be the same). Use jinja2 w/host arg to convert string args into final format before pushing to state.

Pipelining

Investigate bunching commands up together - would be esp. effective in fact gathering. Problem is facts are bound with sudo/sudo_user as well, so need to handle that (ie can't just join all the commands together and expect it to work as currently).

Also, this might be considered over-optimisation, and as such has low priority.

Binary files

files.sync, files.put and possibly files.template can't handle binary data.

stdin support

Just started using this project and liking it so far! Had a quick question: any recommend way of dealing with needing a sudo password for a user? Is just disabling it the way to go?

As an aside it would also be awesome if the deploy bailed out as soon as a command requires some input (like prompting for a sudo password) since at the moment it just hangs.

Why do we need pyinfra?

  1. There is already a number of similar tools, far more advanced than this one, isn't it easier to just write a Salt formula or Puppet recipe?
  2. Docker + Mesos & Kubernetes solves the problem even better, why not to choose this way?

Handle ulimit

When deploying to lots of hosts, using lots of files, pyinfra often hits the file open limit. This is because a new file object is opened per-file, per-host (so uploading the same file in parallel work). Use Python's resource module to guestimate good values for config.PARALLEL.

During an operation, possible open files/host:

  1. Main one for commands
  2. Second SFTP connection
  3. Local file for SFTP
  4. Two per nested local Popen commands (callbacks)
  5. Nested fact commands (callbacks) uses main SSH connection

Max files / host should be 3 - which is SSH + Popen. SFTP uses main SSH connection and file handle is closed immediately after - so will never clash with Popen/etc.

Re-usable/package deploys: pyinfra.api.deploy

pyinfra.api.deploy would be similar to the operation module, but @deploy wrapped functions define groups of operations, a "deploy".

Need spec/example/bootstrapping support in pyinfra.

Investigate global issues in callbacks

python.execute still suffers the global name issue in #26, except that there's no hackfix because the function is essentially copied out of the namespace.

Current fix is just to do imports inside the function...

Better errors

Ie during deploy build error: highlight the target host that failed

npm Module

  • Package manage w/ npm.packages w/ optional dir arg (ie non-global install)

`.exe` for Windows

iPython does this - means executing pyinfra in PowerShell will work as expected.

Look at distlib.

Home directory is not created with `server.user`

Using the following states does not result in the home directory being created. The use is created and /home/deploy is written in /etc/passwd, but the directory is not created.

    server.user(
        'deploy',
        group='deploy',
        ensure_home=True,
    )

Using pyinfra-0.1.dev26 (pip installed) on Ubuntu 16.04 x86_64 in a Linux container.

Add global inventory

For use in CLI mode: from pyinfra import inventory in inventory data and deploy scripts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.