Ubuntu - 最新のGitHubランチャーがlocalhost APIに接続できない

Ubuntu - 最新のGitHubランチャーがlocalhost APIに接続できない

Ubuntu-latestGitHub Runnerで実行されているプログラムを同じGitHub Runnerで実行されているTwisted Webサーバーに正常に接続するには、次の点で正確に何を変更する必要がありますか?localhost

以下のように、Ubuntuで使用されているものと比較して、where twistdWindowsで使用されているものと少し変更すると、同じコードをWindowsノートブックで実行できます。which twistd

いくつかの関連コード:

localhostでTwisted Webサーバーを起動するコードはスクリプトにあり、twistdStartup.py次の内容が含まれています。

import subprocess
import re
import os

escape_chars = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')

def runShellCommand(commandToRun, numLines=999):
  proc = subprocess.Popen( commandToRun,cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
  while True:
    line = proc.stdout.readline()
    if line:
      if numLines == 1:
        return escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n'))
      else:
        print(escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
    else:
      break

print("About to create venv.")
runShellCommand("python3 -m venv venv")

print("About to activate venv.")
runShellCommand("source venv/bin/activate")

print("About to install flask.")
runShellCommand("pip install Flask")
print("About to install requests.")
runShellCommand("pip install requests")
print("About to install twisted.")
runShellCommand("pip install Twisted")

##Set environ variable for the API
os.environ['PYTHONPATH'] = '.'
print("Done updating PYTHONPATH.  About to start server.")

twistdLocation = runShellCommand("which twistd", 1)
startTwistdCommand = twistdLocation+" web --wsgi myAPI.app  &>/dev/null & "
print("startTwistdCommand is: ", startTwistdCommand)

subprocess.call(startTwistdCommand, shell=True)
print("startTwistdCommand should be running in the background now.")

startTheAPI.py上記のコードを呼び出す呼び出しプログラムのコードは次のtwistdStartup.pyとおりです。

myScript = 'twistdStartup.py'
print("About to start Twisted.")
subprocess.Popen(["python", myScript], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print("Just finished starting Twisted.")

GitHub Action操作のこの段階で生成されたログは次のとおりです。

About to start Twisted.
Just finished starting Twisted.

開始するために30秒待ってから、同じタスクの次のステップで、同じUbuntu最新のGitHubランチャーでカールコマンドを実行した結果は次のとおりです。

$ curl http://localhost:1234/api/endpoint/
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                               Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (7) Failed to connect to localhost port 1234 after 1 ms: Connection refused

callTheAPI.pyコマンドを実行するプログラムの内容はcurl次のとおりです。

import subprocess
import re
import os

escape_chars = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')

def runShellCommand(commandToRun, numLines=999):
  proc = subprocess.Popen( commandToRun,cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
  while True:
    line = proc.stdout.readline()
    if line:
      if numLines == 1:
        return escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n'))
      else:
        print(escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
    else:
      break

print("About to call API.")    
runShellCommand("curl http://localhost:1234/api/endpoint/")
print("Done calling API.")

要約:

スクリプトtwistdStartup.pyは実行中ですが、すべてのコマンドを実行したにもかかわらず、ログに出力を提供できませんprint()。 curl コマンドが正しく指定された項目に接続できません。http://localhost:1234/api/endpoint/

答え1

について:

curl コマンドが正しく宣言された http://localhost:1234/api/endpoint/ に接続できません。

ここで最大の問題は、実行するすべてのコマンドがrunShellCommand("somecommand")新しいシェルで実行されるため、コマンドの実行後にすべての変更(関数、変数、環境変数など)が消えることです。

たとえば、次のことを試してみてくださいtwistdStartup.py

print("Running echo $PATH")
runShellCommand("echo $PATH")

print("Running PATH=/")
runShellCommand("PATH=/")

print("Running echo $PATH")
runShellCommand("echo $PATH")

出力(私の場合):

Running echo $PATH
/home/edgar/.local/bin:/home/edgar/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/go/bin
Running PATH=/
Running echo $PATH
/home/edgar/.local/bin:/home/edgar/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/go/bin

上記のように、課題Running PATH=/は次のとおりです。無視される再び走るときrunShellCommand("echo $PATH")

これ可能解決策(すべてのコマンドでテストされるわけではありません)は、runShellCommand次のように、すべてのメソッド呼び出しを単一のメソッド呼び出しにラップするか、コードをシェルスクリプトに変換することです。

TwistdStartup.pyの一部:

runShellCommand(
"""
set -e
echo About to create venv.
python3 -m venv venv

echo About to activate venv.
. venv/bin/activate

echo About to install flask.
pip install Flask

echo About to install requests.
pip install requests

echo About to install twisted.
pip install Twisted

export PYTHONPATH='.'
echo Done updating PYTHONPATH.  About to start server.

twistdLocation=$(which twistd)

echo "Running ${twistdLocation} web --wsgi customControllerAPI.app  &>/dev/null &"

( 
$twistdLocation web --wsgi myAPI.py  >/dev/null 2>&1
)&


echo startTwistdCommand should be running in the background now.
""")

source venv/bin/activateGitHub Actionsでテスト中にこれが無効であるため、エラーが発生することがわかりましたsource(おそらくGitHubのUbuntuデフォルトシェルはdash)。反対を
使用する代わりに、source次のものを使用する必要があります.(はるかに優れています). venv/bin/activate
上記のコマンドでエラーが発生しました。which twistd正常に動作しません。ウィニフソースがありません。したがって、次のコマンドは $twistdLocation web --wsgi customControllerAPI.app &>/dev/null失敗し、Flask APIは実行されません(したがって、次のメッセージが表示されますFailed to connect to localhost port 1234 after 1 ms: Connection refused)。

について:

ただし、すべてのprint()コマンドを使用しても、ログに出力を提供することはできません。

あなたの文書api_server.pyPythonスクリプトを呼び出していますsetup.py

apiServer = subprocess.Popen(["python", "setup.py"], stdout=subprocess.DEVNULL, cwd=str(path))

ここではコマンドの出力を取得できないので、その行を削除してpython setup.py次を追加することをお勧めします。

    apiServer = subprocess.Popen(["python", "setup.py"], cwd=str(path),stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while True:
        line = apiServer.stdout.readline()

        if line:
            print(self.escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
        else:
          break

  1. twistdLocation=$(which twistd)その行を次に変更したい場合がありますtwistdLocation=$(command -v twistd)「which」を使わないのはなぜですか?それでは何を使うべきですか?
  2. set -eまた、この行をスクリプトの最初の行に追加することをお勧めします。このコマンドは、いくつかのエラーが発生した場合に次のコマンドの実行を中断するために使用されます(したがって、一部の依存関係が独自にインストールされていない場合はスクリプトが停止します)。
  3. 私は($twistdLocation web --wsgi myAPI.py >/dev/null 2>&1 )&Pythonがこのコマンドの出力を読むのを待つのを防ぐためにそれを使いますsubprocess。これにより、サーバーが「無限に」停止します。
  4. stdoutコマンドのログ(および)に興味がある場合は、出力を次のファイルにリダイレクトする必要があります。stderr$twistdLocation ...
( 
$twistdLocationn web --wsgi myAPI.py  >/tmp/twistd.logs 2>&1
)&

また、次のようにcatコマンドの内容を含めるようにgithubジョブを編集する必要があります。/tmp/twistd.logs

steps:
  - uses: actions/checkout@v3
  - shell: bash
    name: Start the localhost Server
    run: |
      echo "Current working directory is: "
      echo "$PWD"
      python code/commandStartServer.py
      echo "Checking twistd logs"
      cat /tmp/twistd.logs

したがって、このファイルには次のコードが必要です。

api_server.py

import os
import re
 
class api_server:
  
  def __init__(self):  
    pass

  escape_chars = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
 
  def startServer(self):
    path = os.getcwd()+"/api/"
    print(path)
    print("About to start .")
    import subprocess
    #The version of command on next line runs the server in the background.  Comment it out and replace with the one below it if you want to see output.
    apiServer = subprocess.Popen(["python", "setup.py"], cwd=str(path),stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while True:
        line = apiServer.stdout.readline()

        if line:
            print(self.escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
        else:
          break

    #The second version of the command below will print output to the console, but will also halt your program because it runs the server in the foreground.
    #apiServer = subprocess.Popen(["python", "setup.py"], cwd=str(path))
    print("Just finished starting .")

  def destroyServer(self):
    ... # your current code

installer.py

import subprocess
import re
import os

escape_chars = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')

def runShellCommand(commandToRun, numLines=999):
  proc = subprocess.Popen( commandToRun,cwd=None,  shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  while True:
    line = proc.stdout.readline()
    if line:
      if numLines == 1:
        return escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n'))
      else:
        print(escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
    else:
      break

runShellCommand(
"""
set -e
echo About to create venv.
python3 -m venv venv

echo About to activate venv.
. venv/bin/activate

echo About to install flask.
pip install Flask

echo About to install requests.
pip install requests

echo About to install twisted.
pip install Twisted

export PYTHONPATH='.'
echo Done updating PYTHONPATH: $PYTHONPATH.  About to start server.

twistdLocation=$(which twistd)

echo "Running ${twistdLocation} web --wsgi customControllerAPI.app  &>/dev/null &"

( 
$twistdLocation web --wsgi myAPI.py  >/dev/null 2>&1
)&


echo startTwistdCommand should be running in the background now.
""")

localhost-api.yml

name: localhost-api
on:
  push:
    branches:
      - main
jobs:
  start-and-then-call-localhost-api:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - shell: bash
        name: Start the localhost Server
        run: |
          echo "Current working directory is: "
          echo "$PWD"
          python code/commandStartServer.py
          echo "Checking twistd logs"
          cat /tmp/twistd.logs
      - shell: bash
        name: Call the localhost API
        run: |
          echo "Current working directory is: "
          echo "$PWD"
          python code/commandCallAPI.py
      - shell: bash
        name: Destroy the localhost Server
        run: |
          echo "Current working directory is: "
          echo "$PWD"
          python code/commandDestroyServer.py

関連情報