Ubuntu - 최신 GitHub 실행기가 localhost API에 연결할 수 없습니다.

Ubuntu - 최신 GitHub 실행기가 localhost API에 연결할 수 없습니다.

Ubuntu-latestGitHub Runner에서 실행되는 프로그램이 동일한 GitHub Runner에서 실행되는 Twisted 웹 서버 에 성공적으로 연결하려면 다음에서 정확히 무엇을 변경해야 합니까?localhost

아래와 같이 Ubuntu에서 사용하는 것과 비교하여 where twistdWindows에서 사용하는 것과 같은 약간의 변경을 통해 동일한 코드를 Windows 노트북에서 실행할 수 있습니다 .which twistd

일부 관련 코드:

localhost에서 Twisted 웹 서버를 시작하는 코드는 스크립트에 있으며 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(). 컬 명령이 올바르게 지정된 항목에 연결할 수 없습니다.http://localhost:1234/api/endpoint/

답변1

에 대한:

컬 명령이 올바르게 선언된 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

관련 정보